From 1146ff5d66360b5e4fc451ea96d83588614308e4 Mon Sep 17 00:00:00 2001 From: "John A. Chandy" Date: Tue, 5 Jun 2012 15:43:04 -0400 Subject: [PATCH] Fixes to support change in MULTIOBJ attribute lists CREATE multi-object attributes lists were removed in osd2r02 and replaced with retrieved multi-object attributes lists. This patch updates the code to support that change. --- osd-target/attr.c | 5 ++++- osd-target/cdb.c | 7 ++++--- osd-target/list-entry.c | 35 ++++++++++++++++++++++++++++++++++- osd-target/list-entry.h | 4 ++++ osd-target/osd.c | 37 ++++++++++++++++++++++++------------- 5 files changed, 70 insertions(+), 18 deletions(-) diff --git a/osd-target/attr.c b/osd-target/attr.c index de107cf..9a5367a 100644 --- a/osd-target/attr.c +++ b/osd-target/attr.c @@ -333,9 +333,12 @@ static int attr_gather_attr(sqlite3_stmt *stmt, void *buf, uint32_t buflen, if (listfmt == RTRVD_SET_ATTR_LIST) { return le_pack_attr(buf, buflen, page, number, len, val); - } else if (listfmt == RTRVD_CREATE_MULTIOBJ_LIST) { + } else if (listfmt == RTRVD_MULTIOBJ_LIST) { return le_multiobj_pack_attr(buf, buflen, oid, page, number, len, val); + } else if (listfmt == RTRVD_CREATE_MULTIOBJ_LIST) { + return le_create_multiobj_pack_attr(buf, buflen, oid, page, + number, len, val); } else { return -EINVAL; } diff --git a/osd-target/cdb.c b/osd-target/cdb.c index b6aa8c6..7eab5ca 100644 --- a/osd-target/cdb.c +++ b/osd-target/cdb.c @@ -145,9 +145,10 @@ static int set_one_attr_value(struct command *cmd, uint64_t pid, uint64_t oid, uint16_t len = get_ntohs(&cdb[60]); void *value = &cmd->cdb[62]; - /* nothing to set. osd2r03 Sec 5.2.4.2 */ + /* conflict in standard. osd2r03 Sec 5.2.4.2 says do nothing */ + /* osd2r03 Sec 7.1.2.7 says return error */ if (page == 0) - return 0; + goto out_invalid_param; /* terminate command with check command status, set sense to illegal reguest osd2r03 Sec 5.2.4.2 */ @@ -230,7 +231,7 @@ static int get_attr_list(struct command *cmd, uint64_t pid, uint64_t oid, goto out_param_list_err; if (numoid > 1) - listfmt = RTRVD_CREATE_MULTIOBJ_LIST; + listfmt = RTRVD_MULTIOBJ_LIST; outbuf[0] = listfmt; /* fill list header */ outbuf[1] = outbuf[2] = outbuf[3] = 0; diff --git a/osd-target/list-entry.c b/osd-target/list-entry.c index 613f63e..07b7dfa 100644 --- a/osd-target/list-entry.c +++ b/osd-target/list-entry.c @@ -78,7 +78,7 @@ int le_pack_attr(void *buf, uint32_t buflen, uint32_t page, uint32_t number, } /* - * retrieve attr in list entry format; tab 130 Sec 7.1.3.4 + * retrieve attr in list entry format; osd2r02 tab 156 Sec 7.1.3.4 * * returns: * -EINVAL: error, alignment error @@ -110,3 +110,36 @@ int le_multiobj_pack_attr(void *buf, uint32_t buflen, uint64_t oid, return ret; } +/* + * retrieve attr in list entry format; osdr200 tab 130 Sec 7.1.3.4 + * + * returns: + * -EINVAL: error, alignment error + * -EOVERFLOW: error, if not enough room to even start the entry + * >0: success. returns number of bytes copied into buf. + */ +int le_create_multiobj_pack_attr(void *buf, uint32_t buflen, uint64_t oid, + uint32_t page, uint32_t number, uint16_t valen, + const void *val) +{ + int ret = 0; + uint8_t *cp = buf; + + if (buflen < MLE_MIN_ITEM_LEN) + return -EOVERFLOW; + + set_htonll(cp, oid); + + /* + * test if layout of struct multiobj_list_entry is similar to + * struct list_entry prefixed with oid. + */ + assert(MLE_VAL_OFF == (LE_VAL_OFF+sizeof(oid))); + + ret = le_pack_attr(cp+sizeof(oid), buflen-sizeof(oid), page, number, + valen, val); + if (ret > 0) + ret = MLE_PAGE_OFF + ret; /* add sizeof(oid) to length */ + return ret; +} + diff --git a/osd-target/list-entry.h b/osd-target/list-entry.h index ae17006..e21595e 100644 --- a/osd-target/list-entry.h +++ b/osd-target/list-entry.h @@ -27,4 +27,8 @@ int le_multiobj_pack_attr(void *buf, uint32_t buflen, uint64_t oid, uint32_t page, uint32_t number, uint16_t valen, const void *val); +int le_create_multiobj_pack_attr(void *buf, uint32_t buflen, uint64_t oid, + uint32_t page, uint32_t number, uint16_t valen, + const void *val); + #endif /* __LIST_ENTRY_H */ diff --git a/osd-target/osd.c b/osd-target/osd.c index 00cc7e2..cdcdc4a 100644 --- a/osd-target/osd.c +++ b/osd-target/osd.c @@ -335,7 +335,7 @@ static int get_ccap(struct osd_device *osd, void *outbuf, uint64_t outlen, /* * Get current command attributes page (osd2r00 Sec 7.1.2.24) attributes. * - * NOTE: since RTRVD_CREATE_MULTIOBJ_LIST listfmt is set only when multiple + * NOTE: since RTRVD_MULTIOBJ_LIST listfmt is set only when multiple * objects are created, and CCAP has room for only one (pid, oid), the * retrieved attributes are always in RTRVD_SET_ATTR_LIST format described in * osd2r00 Sec 7.1.3.3 @@ -549,9 +549,13 @@ static int get_utsap_aslist(struct osd_device *osd, uint64_t pid, uint64_t oid, return OSD_ERROR; } - if (listfmt == RTRVD_CREATE_MULTIOBJ_LIST) + if (listfmt == RTRVD_MULTIOBJ_LIST) ret = le_multiobj_pack_attr(outbuf, outlen, oid, USER_TMSTMP_PG, number, len, val); + else if (listfmt == RTRVD_CREATE_MULTIOBJ_LIST) + ret = le_create_multiobj_pack_attr(outbuf, outlen, oid, + USER_TMSTMP_PG, number, len, + val); else ret = le_pack_attr(outbuf, outlen, USER_TMSTMP_PG, number, len, val); @@ -657,9 +661,12 @@ static int get_uiap(struct osd_device *osd, uint64_t pid, uint64_t oid, set_htonll(ll, value); if (listfmt == RTRVD_SET_ATTR_LIST) ret = le_pack_attr(outbuf, outlen, page, number, len, val); - else if (listfmt == RTRVD_CREATE_MULTIOBJ_LIST) + else if (listfmt == RTRVD_MULTIOBJ_LIST) ret = le_multiobj_pack_attr(outbuf, outlen, oid, page, number, len, val); + else if (listfmt == RTRVD_CREATE_MULTIOBJ_LIST) + ret = le_create_multiobj_pack_attr(outbuf, outlen, oid, page, + number, len, val); else return OSD_ERROR; @@ -809,9 +816,12 @@ static int get_riap(struct osd_device *osd, uint64_t pid, uint64_t oid, if (listfmt == RTRVD_SET_ATTR_LIST) ret = le_pack_attr(outbuf, outlen, page, number, len, val); - else if (listfmt == RTRVD_CREATE_MULTIOBJ_LIST) + else if (listfmt == RTRVD_MULTIOBJ_LIST) ret = le_multiobj_pack_attr(outbuf, outlen, oid, page, number, len, val); + else if (listfmt == RTRVD_CREATE_MULTIOBJ_LIST) + ret = le_create_multiobj_pack_attr(outbuf, outlen, oid, page, + number, len, val); else return OSD_ERROR; @@ -955,9 +965,13 @@ static int get_ciap(struct osd_device *osd, uint64_t pid, uint64_t cid, if (listfmt == RTRVD_SET_ATTR_LIST) ret = le_pack_attr(outbuf, outlen, COLL_INFO_PG, number, len, val); - else if (listfmt == RTRVD_CREATE_MULTIOBJ_LIST) + else if (listfmt == RTRVD_MULTIOBJ_LIST) ret = le_multiobj_pack_attr(outbuf, outlen, cid, COLL_INFO_PG, number, len, val); + else if (listfmt == RTRVD_CREATE_MULTIOBJ_LIST) + ret = le_create_multiobj_pack_attr(outbuf, outlen, cid, + COLL_INFO_PG, number, len, + val); else return OSD_ERROR; @@ -2317,9 +2331,12 @@ static int fill_null_attr(struct osd_device *osd, uint64_t pid, uint64_t oid, int ret; if (page != GETALLATTR_PG && number != ATTRNUM_GETALL) { - if (listfmt == RTRVD_CREATE_MULTIOBJ_LIST) + if (listfmt == RTRVD_MULTIOBJ_LIST) ret = le_multiobj_pack_attr(outbuf, outlen, oid, page, number, 0, NULL); + else if (listfmt == RTRVD_CREATE_MULTIOBJ_LIST) + ret = le_create_multiobj_pack_attr(outbuf, outlen, oid, + page, number, 0,NULL); else ret = le_pack_attr(outbuf, outlen, page, number, 0, NULL); @@ -2489,7 +2506,7 @@ int osd_getattr_list(struct osd_device *osd, uint64_t pid, uint64_t oid, * current command * null * - * NOTE: since RTRVD_CREATE_MULTIOBJ_LIST listfmt can only be used when + * NOTE: since RTRVD_MULTIOBJ_LIST listfmt can only be used when * cdbfmt == GETLIST_SETLIST, osd_getattr_page always generates list in * RTRVD_SET_ATTR_LIST. hence there is no listfmt arg. * @@ -3685,12 +3702,6 @@ int osd_set_attributes(struct osd_device *osd, uint64_t pid, uint64_t oid, if (number == ATTRNUM_UNMODIFIABLE) goto out_param_list; - if ((val == NULL && len != 0) || (val != NULL && len == 0)) { - osd_warning("%s: NULLs %llu oid %llu", __func__, - llu(pid), llu(oid)); - goto out_cdb_err; - } - /* information page, make sure null terminated. osd2r00 7.1.2.2 */ if (number == ATTRNUM_INFO) { int i;