From 4ad0c421429d8e740f3d4998815226d3eb5f83fa Mon Sep 17 00:00:00 2001 From: Cengiz Date: Thu, 12 Jun 2014 13:27:37 -0400 Subject: [PATCH] Modified some files to support get_member_attributes optimization --- osd-target/cdb.c | 64 +++++++++++++++++++++++++++--------- osd-target/coll.c | 11 +++---- osd-target/coll.h | 2 +- osd-target/osd.c | 84 ++++++++++++++++++++++++++++++++++++++++++++--- osd-target/osd.h | 3 +- 5 files changed, 135 insertions(+), 29 deletions(-) diff --git a/osd-target/cdb.c b/osd-target/cdb.c index 7eab5ca..e31af10 100644 --- a/osd-target/cdb.c +++ b/osd-target/cdb.c @@ -185,7 +185,7 @@ static int set_one_attr_value(struct command *cmd, uint64_t pid, uint64_t oid, * ==0: success * >0: failure, senselen is returned. */ -static int get_attr_list(struct command *cmd, uint64_t pid, uint64_t oid, +static int get_attr_list(struct command *cmd, uint64_t pid, uint64_t *oids, uint8_t isembedded, uint16_t numoid, uint32_t cdb_cont_len) { int ret = 0; @@ -201,6 +201,9 @@ static int get_attr_list(struct command *cmd, uint64_t pid, uint64_t oid, const uint8_t *list_hdr = &cmd->indata[list_off]; uint8_t *outbuf; uint8_t *cp = NULL; + int len_per_oid; + int current_oid = 0; + uint32_t starting_len; if (getattr_list_len == 0) return 0; /* nothing to retrieve, osd2r00 Sec 5.2.2.3 */ @@ -243,28 +246,31 @@ static int get_attr_list(struct command *cmd, uint64_t pid, uint64_t oid, cp = outbuf + 8; cmd->get_used_outlen = 8; list_alloc_len -= 8; + len_per_oid = list_len / numoid; + starting_len = list_len; while (list_len > 0) { uint32_t page = get_ntohl(&list_hdr[0]); uint32_t number = get_ntohl(&list_hdr[4]); + uint32_t get_used_outlen = 0; - for (i = oid; i < oid+numoid; i++) { - uint32_t get_used_outlen; - ret = osd_getattr_list(cmd->osd, pid, i, page, number, + ret = osd_getattr_list(cmd->osd, pid, oids[current_oid], page, number, cp, list_alloc_len, isembedded, listfmt, &get_used_outlen, cdb_cont_len, cmd->sense); - if (ret != 0) { - cmd->senselen = ret; - goto out_err; - } - - list_alloc_len -= get_used_outlen; - cmd->get_used_outlen += get_used_outlen; - cp += get_used_outlen; + if (ret != 0) { + cmd->senselen = ret; + goto out_err; } + list_alloc_len -= get_used_outlen; + cmd->get_used_outlen += get_used_outlen; + cp += get_used_outlen; + list_len -= 8; list_hdr += 8; + + if (!((starting_len - list_len) % len_per_oid)) + current_oid++; } set_htonl(&outbuf[4], cmd->get_used_outlen - 8); @@ -283,12 +289,12 @@ static int get_attr_list(struct command *cmd, uint64_t pid, uint64_t oid, out_param_list_err: return sense_basic_build(cmd->sense, OSD_SSK_ILLEGAL_REQUEST, OSD_ASC_PARAMETER_LIST_LENGTH_ERROR, pid, - oid); + oids[0]); out_invalid_param_list: return sense_basic_build(cmd->sense, OSD_SSK_ILLEGAL_REQUEST, OSD_ASC_INVALID_FIELD_IN_PARAM_LIST, pid, - oid); + oids[0]); } @@ -537,7 +543,14 @@ static int get_attributes(struct command *cmd, uint64_t pid, uint64_t oid, if (cmd->getset_cdbfmt == GETPAGE_SETVALUE) { return get_attr_page(cmd, pid, oid, isembedded, numoid, cdb_cont_len); } else if (cmd->getset_cdbfmt == GETLIST_SETLIST) { - return get_attr_list(cmd, pid, oid, isembedded, numoid, cdb_cont_len); + if(numoid > 1) { + uint64_t *oids = (uint64_t *)malloc(numoid * sizeof(uint64_t)); + ret = get_attr_list(cmd, pid, oids, isembedded, numoid, cdb_cont_len); + free(oids); + return ret; + } else { + return get_attr_list(cmd, pid, &oid, isembedded, 1, cdb_cont_len); + } } else if (cmd->getset_cdbfmt == GETFIELD_SETVALUE){ return 0; }else { @@ -1652,6 +1665,12 @@ static void exec_service_action(struct command *cmd) ret = osd_create_and_write(osd, pid, requested_oid, len, offset, indata, cdb_cont_len, sglist, sense, ddt); + if (ret) + break; + + oid = osd->ccap.oid; + + ret = std_get_set_attr(cmd, pid, oid, cdb_cont_len); break; } case OSD_CREATE_CLONE: { @@ -1775,7 +1794,20 @@ static void exec_service_action(struct command *cmd) case OSD_GET_MEMBER_ATTRIBUTES: { uint64_t pid = get_ntohll(&cdb[16]); uint64_t cid = get_ntohll(&cdb[24]); - ret = osd_get_member_attributes(osd, pid, cid, cdb_cont_len, sense); + uint64_t min_oid = get_ntohll(&cdb[32]); + uint64_t max_oid = get_ntohll(&cdb[40]); + int numobj = get_ntohl(&cmd->cdb[80]); + uint64_t oids[numobj]; + + ret = check_no_continuations(cmd, cdb_cont_len, pid, cid); + if (ret) + break; + + ret = osd_get_member_attributes(osd, pid, cid, min_oid, max_oid, oids, numobj, cdb_cont_len, sense); + if (ret) + break; + + ret = get_attr_list(cmd, pid, oids, true, numobj, cdb_cont_len); break; } case OSD_LIST: { diff --git a/osd-target/coll.c b/osd-target/coll.c index b606176..bbba56d 100644 --- a/osd-target/coll.c +++ b/osd-target/coll.c @@ -130,8 +130,7 @@ int coll_initialize(struct db_context *dbc) if (ret != SQLITE_OK) goto out_finalize_getcid; - sprintf(SQL, "SELECT oid FROM %s WHERE pid = ? AND cid = ? AND " - " oid >= ?;", dbc->coll->name); + sprintf(SQL, "SELECT oid FROM %s WHERE cid = ? AND oid BETWEEN ? AND ?;", dbc->coll->name); ret = sqlite3_prepare(dbc->db, SQL, -1, &dbc->coll->getoids, NULL); if (ret != SQLITE_OK) goto out_finalize_getoids; @@ -473,7 +472,7 @@ int coll_get_cid(struct db_context *dbc, uint64_t pid, uint64_t oid, * OSD_OK: success, oids copied into outbuf, cont_id set if necessary */ int coll_get_oids_in_cid(struct db_context *dbc, uint64_t pid, uint64_t cid, - uint64_t initial_oid, uint64_t alloc_len, + uint64_t min_oid, uint64_t max_oid, uint64_t alloc_len, uint8_t *outdata, uint64_t *used_outlen, uint64_t *add_len, uint64_t *cont_id) { @@ -486,9 +485,9 @@ int coll_get_oids_in_cid(struct db_context *dbc, uint64_t pid, uint64_t cid, repeat: ret = 0; stmt = dbc->coll->getoids; - ret |= sqlite3_bind_int64(stmt, 1, pid); - ret |= sqlite3_bind_int64(stmt, 2, cid); - ret |= sqlite3_bind_int64(stmt, 3, initial_oid); + ret |= sqlite3_bind_int64(stmt, 1, cid); + ret |= sqlite3_bind_int64(stmt, 2, min_oid); + ret |= sqlite3_bind_int64(stmt, 3, max_oid); ret = db_exec_id_rtrvl_stmt(dbc, stmt, ret, __func__, alloc_len, outdata, used_outlen, add_len, cont_id); if (ret == OSD_REPEAT) diff --git a/osd-target/coll.h b/osd-target/coll.h index 3c28703..649a68d 100644 --- a/osd-target/coll.h +++ b/osd-target/coll.h @@ -48,7 +48,7 @@ int coll_get_cap(sqlite3 *db, uint64_t pid, uint64_t oid, void *outbuf, uint64_t outlen, uint8_t listfmt, uint32_t *used_outlen); int coll_get_oids_in_cid(struct db_context *dbc, uint64_t pid, uint64_t cid, - uint64_t initial_oid, uint64_t alloc_len, + uint64_t min_oid, uint64_t max_oid, uint64_t alloc_len, uint8_t *outdata, uint64_t *used_outlen, uint64_t *add_len, uint64_t *cont_id); diff --git a/osd-target/osd.c b/osd-target/osd.c index 1164be9..dd5d890 100644 --- a/osd-target/osd.c +++ b/osd-target/osd.c @@ -1932,6 +1932,8 @@ int osd_create_and_write(struct osd_device *osd, uint64_t pid, return ret; } + oid = osd->ccap.oid; + ret = osd_write(osd, pid, oid, len, offset, data, sglist, sense, ddt); if (ret) { osd_remove(osd, pid, oid, cdb_cont_len, sense); @@ -2664,10 +2666,71 @@ int osd_getattr_page(struct osd_device *osd, uint64_t pid, uint64_t oid, int osd_get_member_attributes(struct osd_device *osd, uint64_t pid, - uint64_t cid, uint32_t cdb_cont_len, uint8_t *sense) + uint64_t cid, uint64_t min_oid, uint64_t max_oid, uint64_t oids[], int numobj, + uint32_t cdb_cont_len, uint8_t *sense) { - osd_debug(__func__); - return osd_error_unimplemented(0, sense); + int ret = 0; + size_t i = 0; + int present = 0; + uint8_t obj_type = 0; + uint8_t within_txn = 0; + + uint64_t usedlen; + uint64_t addlen; + uint64_t cont_id = 0; + int j=0, k=0; + + osd_debug("%s: get attrs from pid %llu cid %llu", __func__, llu(pid), + llu(cid)); + + assert(osd && osd->root && osd->dbc && sense); + + /* encapsulate all db ops in txn */ + ret = db_begin_txn(osd->dbc); + assert(ret == 0); + within_txn = 1; + + ret = obj_ispresent(osd->dbc, pid, cid, &present); + if (ret != OSD_OK || !present) /* collection absent! */ + goto out_cdb_err; + + obj_type = get_obj_type(osd, pid, cid); + if (obj_type != COLLECTION) + goto out_cdb_err; + + ret = coll_get_oids_in_cid(osd->dbc, pid, cid, min_oid, max_oid, + numobj*8, (uint8_t *)oids, + &usedlen, &addlen, &cont_id); + + for(j=0; jdbc); + assert(ret == 0); + + fill_ccap(&osd->ccap, NULL, COLLECTION, pid, cid, 0); + + return OSD_OK; /* success */ + +out_hw_err: + if (within_txn) { + ret = db_end_txn(osd->dbc); + assert(ret == 0); + } + return sense_build_sdd(sense, OSD_SSK_HARDWARE_ERROR, + OSD_ASC_INVALID_FIELD_IN_CDB, pid, cid); + +out_cdb_err: + if (within_txn) { + ret = db_end_txn(osd->dbc); + assert(ret == 0); + } + return sense_build_sdd(sense, OSD_SSK_ILLEGAL_REQUEST, + OSD_ASC_INVALID_FIELD_IN_CDB, pid, cid); + } /* @@ -2824,7 +2887,7 @@ int osd_list_collection(struct osd_device *osd, uint8_t list_attr, alloc_len, &outdata[24], used_outlen, &add_len, &cont_id) : - coll_get_oids_in_cid(osd->dbc, pid, cid, initial_oid, + coll_get_oids_in_cid(osd->dbc, pid, cid, initial_oid, 1, alloc_len, &outdata[24], used_outlen, &add_len, &cont_id)); if (ret) @@ -3647,6 +3710,11 @@ int osd_remove_collection(struct osd_device *osd, uint64_t pid, uint64_t cid, if (ret != 0) goto out_hw_err; + /* delete all collection memberships */ + ret = coll_delete_oid(osd->dbc, pid, cid); + if (ret != 0) + goto out_hw_err; + ret = obj_delete(osd->dbc, pid, cid); if (ret != 0) goto out_hw_err; @@ -3819,6 +3887,12 @@ int osd_set_attributes(struct osd_device *osd, uint64_t pid, uint64_t oid, goto out_success; else goto out_cdb_err; + case ANY_PG + USER_COLL_PG: + ret = set_cap(osd, pid, oid, number, val, len); + if (ret == OSD_OK) + goto out_success; + else + goto out_cdb_err; case USER_COLL_PG: ret = set_cap(osd, pid, oid, number, val, len); if (ret == OSD_OK) @@ -4208,7 +4282,7 @@ int osd_cas(struct osd_device *osd, uint64_t pid, uint64_t oid, uint64_t cmp, goto out_cdb_err; obj_type = get_obj_type(osd, pid, oid); - if (obj_type != USEROBJECT) + if (obj_type != USEROBJECT && obj_type != COLLECTION) goto out_cdb_err; ret = attr_get_val(osd->dbc, pid, oid, USER_ATOMICS_PG, UAP_CAS, diff --git a/osd-target/osd.h b/osd-target/osd.h index b135148..1846a9b 100644 --- a/osd-target/osd.h +++ b/osd-target/osd.h @@ -79,7 +79,8 @@ int osd_getattr_list(struct osd_device *osd, uint64_t pid, uint64_t oid, uint32_t outlen, uint8_t isembedded, uint8_t listfmt, uint32_t *used_outlen, uint32_t cdb_cont_len, uint8_t *sense); int osd_get_member_attributes(struct osd_device *osd, uint64_t pid, - uint64_t cid, uint32_t cdb_cont_len, uint8_t *sense); + uint64_t cid, uint64_t min_oid, uint64_t max_oid, uint64_t oids[], int numobj, + uint32_t cdb_cont_len, uint8_t *sense); int osd_list(struct osd_device *osd, uint8_t list_attr, uint64_t pid, uint64_t alloc_len, uint64_t initial_oid, struct getattr_list *get_attr, uint32_t list_id,