scsi: add persistent reservation in command with read keys action support
Change-Id: Ia8e4ad31e84a1a97c83d4f49680bb7090ee4e041 Signed-off-by: Changpeng Liu <changpeng.liu@intel.com> Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/436093 Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com> Reviewed-by: Jim Harris <james.r.harris@intel.com>
This commit is contained in:
parent
a6edaa9600
commit
4e9e220e7c
@ -2043,6 +2043,14 @@ bdev_scsi_process_primary(struct spdk_scsi_task *task)
|
||||
data_len = 0;
|
||||
break;
|
||||
|
||||
case SPDK_SPC_PERSISTENT_RESERVE_IN:
|
||||
alloc_len = from_be16(&cdb[7]);
|
||||
data_len = alloc_len;
|
||||
data = calloc(1, data_len);
|
||||
assert(data != NULL);
|
||||
rc = spdk_scsi_pr_in(task, cdb, data, data_len);
|
||||
break;
|
||||
|
||||
default:
|
||||
return SPDK_SCSI_TASK_UNKNOWN;
|
||||
}
|
||||
|
@ -202,6 +202,7 @@ bool spdk_scsi_bdev_get_dif_ctx(struct spdk_bdev *bdev, uint8_t *cdb, uint32_t o
|
||||
struct spdk_dif_ctx *dif_ctx);
|
||||
|
||||
int spdk_scsi_pr_out(struct spdk_scsi_task *task, uint8_t *cdb, uint8_t *data, uint16_t data_len);
|
||||
int spdk_scsi_pr_in(struct spdk_scsi_task *task, uint8_t *cdb, uint8_t *data, uint16_t data_len);
|
||||
|
||||
struct spdk_scsi_globals {
|
||||
pthread_mutex_t mutex;
|
||||
|
@ -560,3 +560,59 @@ invalid:
|
||||
SPDK_SCSI_ASCQ_CAUSE_NOT_REPORTABLE);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int
|
||||
spdk_scsi_pr_in_read_keys(struct spdk_scsi_task *task, uint8_t *data,
|
||||
uint16_t data_len)
|
||||
{
|
||||
struct spdk_scsi_lun *lun = task->lun;
|
||||
struct spdk_scsi_pr_in_read_keys_data *keys;
|
||||
struct spdk_scsi_pr_registrant *reg, *tmp;
|
||||
uint16_t count = 0;
|
||||
|
||||
SPDK_DEBUGLOG(SPDK_LOG_SCSI, "PR IN READ KEYS\n");
|
||||
keys = (struct spdk_scsi_pr_in_read_keys_data *)data;
|
||||
|
||||
to_be32(&keys->header.pr_generation, lun->pr_generation);
|
||||
TAILQ_FOREACH_SAFE(reg, &lun->reg_head, link, tmp) {
|
||||
if (((count + 1) * 8 + sizeof(keys->header)) > data_len) {
|
||||
break;
|
||||
}
|
||||
to_be64(&keys->rkeys[count], reg->rkey);
|
||||
count++;
|
||||
}
|
||||
to_be32(&keys->header.addiontal_len, count * 8);
|
||||
|
||||
return (sizeof(keys->header) + count * 8);
|
||||
}
|
||||
|
||||
int
|
||||
spdk_scsi_pr_in(struct spdk_scsi_task *task,
|
||||
uint8_t *cdb, uint8_t *data,
|
||||
uint16_t data_len)
|
||||
{
|
||||
enum spdk_scsi_pr_in_action_code action;
|
||||
int rc = 0;
|
||||
|
||||
action = cdb[1] & 0x1f;
|
||||
if (data_len < sizeof(struct spdk_scsi_pr_in_read_header)) {
|
||||
goto invalid;
|
||||
}
|
||||
|
||||
switch (action) {
|
||||
case SPDK_SCSI_PR_IN_READ_KEYS:
|
||||
rc = spdk_scsi_pr_in_read_keys(task, data, data_len);
|
||||
break;
|
||||
default:
|
||||
goto invalid;
|
||||
}
|
||||
|
||||
return rc;
|
||||
|
||||
invalid:
|
||||
spdk_scsi_task_set_status(task, SPDK_SCSI_STATUS_CHECK_CONDITION,
|
||||
SPDK_SCSI_SENSE_ILLEGAL_REQUEST,
|
||||
SPDK_SCSI_ASC_INVALID_FIELD_IN_CDB,
|
||||
SPDK_SCSI_ASCQ_CAUSE_NOT_REPORTABLE);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -105,6 +105,9 @@ DEFINE_STUB(spdk_bdev_is_dif_check_enabled, bool,
|
||||
DEFINE_STUB(spdk_scsi_pr_out, int, (struct spdk_scsi_task *task,
|
||||
uint8_t *cdb, uint8_t *data, uint16_t data_len), 0);
|
||||
|
||||
DEFINE_STUB(spdk_scsi_pr_in, int, (struct spdk_scsi_task *task, uint8_t *cdb,
|
||||
uint8_t *data, uint16_t data_len), 0);
|
||||
|
||||
void
|
||||
spdk_scsi_lun_complete_task(struct spdk_scsi_lun *lun, struct spdk_scsi_task *task)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user