diff --git a/osd-target/cdb.c b/osd-target/cdb.c index f29db9d..50c4036 100644 --- a/osd-target/cdb.c +++ b/osd-target/cdb.c @@ -577,35 +577,40 @@ static int set_attributes(struct command *cmd, uint64_t pid, uint64_t oid, OSD_ASC_INVALID_FIELD_IN_CDB, pid, oid); } -static int cdb_copy_user_objects(struct command*cmd, uint32_t cdb_cont_len) +static int cdb_copy_user_objects(struct command *cmd) { int ret = 0; - int cpy_atr = 0, pad_len = 0; uint16_t descriptor_type = 0; - uint32_t cdb_descriptor_len = 0; - uint8_t dupl_method = cmd->cdb[16]; + uint8_t dupl_method = cmd->cdb[14]; uint64_t destination_pid = get_ntohll(&cmd->cdb[16]); uint64_t requested_oid = get_ntohll(&cmd->cdb[24]); - uint64_t source_pid; - uint64_t source_oid; - - - descriptor_type = get_ntohs(&cmd->cdb[48]); - pad_len = cmd->cdb[51] & 7; - cdb_descriptor_len = get_ntohl(&cmd->cdb[52]); - source_pid = get_ntohll(&cmd->cdb[56]); - source_oid = get_ntohll(&cmd->cdb[64]); - cpy_atr = cmd->cdb[72] & 1; - - if (descriptor_type != 0x0101) - goto out_cdb_err; - if (pad_len != 0) - goto out_cdb_err; - if (cdb_descriptor_len != 18) + struct cdb_continuation_descriptor *copy_desc; + const struct copy_user_object_source *cuos; + + /* osd2r04 6.4 - there should be exactly one copy user object + source descriptor and at most one extension capabilities + descriptor */ + if (cmd->cont.num_descriptors == 1 && + cmd->cont.descriptors[0].type != COPY_USER_OBJECT_SOURCE) { + copy_desc = &cmd->cont.descriptors[0]; + } else if (cmd->cont.num_descriptors == 2 && + cmd->cont.descriptors[0].type == COPY_USER_OBJECT_SOURCE && + cmd->cont.descriptors[1].type == EXTENSION_CAPABILITIES) { + copy_desc = &cmd->cont.descriptors[0]; + } else if (cmd->cont.num_descriptors == 2 && + cmd->cont.descriptors[1].type == COPY_USER_OBJECT_SOURCE && + cmd->cont.descriptors[0].type == EXTENSION_CAPABILITIES) { + copy_desc = &cmd->cont.descriptors[1]; + } else { + goto out_cdb_err; + } + + cuos = (typeof(cuos))copy_desc->desc_specific_hdr; + if (copy_desc->length != 18) goto out_cdb_err; - ret = osd_copy_user_objects(cmd->osd, destination_pid, requested_oid, source_pid, source_oid, - cpy_atr, dupl_method, cdb_cont_len, cmd->sense); + ret = osd_copy_user_objects(cmd->osd, destination_pid, requested_oid, + cuos, dupl_method, cmd->sense); out_cdb_err: ret = sense_basic_build(cmd->sense, OSD_SSK_ILLEGAL_REQUEST, OSD_ASC_INVALID_FIELD_IN_CDB, destination_pid, @@ -1382,6 +1387,11 @@ static int parse_cdb_continuation_segment(struct command *cmd, break; } + case COPY_USER_OBJECT_SOURCE: { + desc->desc_specific_hdr = (const uint8_t *)(desc_hdr+1); + goto out_cdb_err; + } + default: goto out_cdb_err; } @@ -1472,7 +1482,7 @@ static void exec_service_action(struct command *cmd) } case OSD_COPY_USER_OBJECTS: { - ret = cdb_copy_user_objects(cmd, cdb_cont_len); + ret = cdb_copy_user_objects(cmd); break; } diff --git a/osd-target/osd-types.h b/osd-target/osd-types.h index 5045325..65285f4 100644 --- a/osd-target/osd-types.h +++ b/osd-target/osd-types.h @@ -231,6 +231,17 @@ struct sg_list { const struct sg_list_entry *entries; }; +struct copy_user_object_source { + uint64_t source_pid; + uint64_t source_oid; + uint8_t reserved1:7; + uint8_t cpy_attr:1; + uint8_t freeze:1; + uint8_t reserved2:3; + uint8_t time_of_duplication:4; + uint16_t reserved3; +}; + struct cdb_continuation_descriptor_header { uint16_t type; uint8_t reserved; diff --git a/osd-target/osd.c b/osd-target/osd.c index cf52c12..2ae5a34 100644 --- a/osd-target/osd.c +++ b/osd-target/osd.c @@ -1478,12 +1478,14 @@ int osd_clear(struct osd_device *osd, uint64_t pid, uint64_t oid, */ int osd_copy_user_objects(struct osd_device *osd, uint64_t pid, uint64_t requested_oid, - uint64_t source_pid, uint64_t source_oid, int cpy_atr, - uint8_t dupl_method, uint32_t cdb_cont_len, uint8_t *sense) + const struct copy_user_object_source *cuos, + uint8_t dupl_method, uint8_t *sense) { int ret = 0; uint64_t oid = 0; int present = 0; + uint64_t source_pid; + uint64_t source_oid; osd_debug("%s: pid: %llu cid %llu", __func__, llu(pid), llu(requested_oid)); @@ -1494,8 +1496,8 @@ int osd_copy_user_objects(struct osd_device *osd, uint64_t pid, uint64_t request if (requested_oid != 0 && requested_oid < USEROBJECT_OID_LB) goto out_cdb_err; - if (cdb_cont_len == 0) - goto out_cdb_err; + source_pid = get_ntohll(&cuos->source_pid); + source_oid = get_ntohll(&cuos->source_oid); /* verify that source_pid & source_oid exist */ ret = obj_ispresent(osd->dbc, source_pid, PARTITION_OID, &present); @@ -1536,11 +1538,11 @@ int osd_copy_user_objects(struct osd_device *osd, uint64_t pid, uint64_t request osd->ic.cur_pid = osd->ic.next_id = 0; } - if (dupl_method == DEFAULT){ + if (dupl_method == DEFAULT) { /* call function to copy userobject data from source object in source partition to destination object in destination partition */ } - if (cpy_atr == 1){ + if (cuos->cpy_attr == 1) { /* call function to copy attribute data from source object in source partition to destination object in destination partition */ } diff --git a/osd-target/osd.h b/osd-target/osd.h index 10a9cef..84df6d2 100644 --- a/osd-target/osd.h +++ b/osd-target/osd.h @@ -44,9 +44,10 @@ int osd_append(struct osd_device *osd, uint64_t pid, uint64_t oid, uint32_t cdb_cont_len, uint8_t *sense, uint8_t ddt); int osd_clear(struct osd_device *osd, uint64_t pid, uint64_t oid, uint64_t len, uint64_t offset ,uint32_t cdb_cont_len, uint8_t *sense); -int osd_copy_user_objects(struct osd_device *osd, uint64_t pid, uint64_t requested_oid, - uint64_t source_pid, uint64_t source_oid, int cpy_atr, uint8_t dupl_method, - uint32_t cdb_cont_len, uint8_t *sense); +int osd_copy_user_objects(struct osd_device *osd, uint64_t pid, + uint64_t requested_oid, + const struct copy_user_object_source *cuos, + uint8_t dupl_method, uint8_t *sense); int osd_create(struct osd_device *osd, uint64_t pid, uint64_t requested_oid, uint16_t num, uint32_t cdb_cont_len, uint8_t *sense); int osd_create_and_write(struct osd_device *osd, uint64_t pid,