scsi: allow zero-length read and write
The SCSI spec says that zero transfer length shouldn't be considered an error. Change-Id: I98958cc393e0e487e25fdbb0eb7fc8126aff9945 Signed-off-by: Daniel Verkamp <daniel.verkamp@intel.com> Reviewed-on: https://review.gerrithub.io/374320 Tested-by: SPDK Automated Test System <sys_sgsw@intel.com> Reviewed-by: Ben Walker <benjamin.walker@intel.com>
This commit is contained in:
parent
75a3ee3f66
commit
0720ad357b
@ -1338,15 +1338,6 @@ spdk_bdev_scsi_write(struct spdk_bdev *bdev,
|
|||||||
int rc;
|
int rc;
|
||||||
struct spdk_scsi_task *primary = task->parent;
|
struct spdk_scsi_task *primary = task->parent;
|
||||||
|
|
||||||
if (len == 0) {
|
|
||||||
task->data_transferred = 0;
|
|
||||||
spdk_scsi_task_set_status(task, SPDK_SCSI_STATUS_CHECK_CONDITION,
|
|
||||||
SPDK_SCSI_SENSE_NO_SENSE,
|
|
||||||
SPDK_SCSI_ASC_NO_ADDITIONAL_SENSE,
|
|
||||||
SPDK_SCSI_ASCQ_CAUSE_NOT_REPORTABLE);
|
|
||||||
return SPDK_SCSI_TASK_COMPLETE;
|
|
||||||
}
|
|
||||||
|
|
||||||
blen = spdk_bdev_get_block_size(bdev);
|
blen = spdk_bdev_get_block_size(bdev);
|
||||||
offset = lba * blen;
|
offset = lba * blen;
|
||||||
nbytes = ((uint64_t)len) * blen;
|
nbytes = ((uint64_t)len) * blen;
|
||||||
@ -1461,6 +1452,11 @@ spdk_bdev_scsi_readwrite(struct spdk_bdev *bdev,
|
|||||||
return SPDK_SCSI_TASK_COMPLETE;
|
return SPDK_SCSI_TASK_COMPLETE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (xfer_len == 0) {
|
||||||
|
task->status = SPDK_SCSI_STATUS_GOOD;
|
||||||
|
return SPDK_SCSI_TASK_COMPLETE;
|
||||||
|
}
|
||||||
|
|
||||||
/* Transfer Length is limited to the Block Limits VPD page Maximum Transfer Length */
|
/* Transfer Length is limited to the Block Limits VPD page Maximum Transfer Length */
|
||||||
max_xfer_len = SPDK_WORK_BLOCK_SIZE / spdk_bdev_get_block_size(bdev);
|
max_xfer_len = SPDK_WORK_BLOCK_SIZE / spdk_bdev_get_block_size(bdev);
|
||||||
if (xfer_len > max_xfer_len) {
|
if (xfer_len > max_xfer_len) {
|
||||||
|
@ -672,6 +672,24 @@ xfer_len_test(void)
|
|||||||
CU_ASSERT((task.sense_data[2] & 0xf) == SPDK_SCSI_SENSE_ILLEGAL_REQUEST);
|
CU_ASSERT((task.sense_data[2] & 0xf) == SPDK_SCSI_SENSE_ILLEGAL_REQUEST);
|
||||||
CU_ASSERT(task.sense_data[12] == SPDK_SCSI_ASC_INVALID_FIELD_IN_CDB);
|
CU_ASSERT(task.sense_data[12] == SPDK_SCSI_ASC_INVALID_FIELD_IN_CDB);
|
||||||
|
|
||||||
|
/* zero transfer length (valid) */
|
||||||
|
to_be64(&cdb[2], 0); /* LBA */
|
||||||
|
to_be32(&cdb[10], 0); /* transfer length */
|
||||||
|
task.transfer_len = 0;
|
||||||
|
rc = spdk_bdev_scsi_execute(&bdev, &task);
|
||||||
|
CU_ASSERT(rc == SPDK_SCSI_TASK_COMPLETE);
|
||||||
|
CU_ASSERT(task.status == SPDK_SCSI_STATUS_GOOD);
|
||||||
|
CU_ASSERT(task.data_transferred == 0);
|
||||||
|
|
||||||
|
/* zero transfer length past end of disk (invalid) */
|
||||||
|
to_be64(&cdb[2], g_test_bdev_num_blocks); /* LBA */
|
||||||
|
to_be32(&cdb[10], 0); /* transfer length */
|
||||||
|
task.transfer_len = 0;
|
||||||
|
rc = spdk_bdev_scsi_execute(&bdev, &task);
|
||||||
|
CU_ASSERT(rc == SPDK_SCSI_TASK_COMPLETE);
|
||||||
|
CU_ASSERT(task.status == SPDK_SCSI_STATUS_CHECK_CONDITION);
|
||||||
|
CU_ASSERT(task.sense_data[12] == SPDK_SCSI_ASC_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE);
|
||||||
|
|
||||||
spdk_put_task(&task);
|
spdk_put_task(&task);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user