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:
Changpeng Liu 2019-05-14 01:34:34 -04:00 committed by Jim Harris
parent a6edaa9600
commit 4e9e220e7c
4 changed files with 68 additions and 0 deletions

View File

@ -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;
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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)
{