Commit 6c78cc06 authored by Akinobu Mita's avatar Akinobu Mita Committed by James Bottomley

[SCSI] scsi_debug: protect device access with atomic_rw lock

This change ensures that concurrent device access including ramdisk
storage, protection info, and provisioning map by read, write, and
unmap commands are protected with atomic_rw spinlock.
Signed-off-by: default avatarAkinobu Mita <akinobu.mita@gmail.com>
Reviewed-by: default avatarDouglas Gilbert <dgilbert@interlog.com>
Reviewed-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: default avatarJames Bottomley <JBottomley@Parallels.com>
parent be4e11be
...@@ -1888,17 +1888,19 @@ static int resp_read(struct scsi_cmnd *SCpnt, unsigned long long lba, ...@@ -1888,17 +1888,19 @@ static int resp_read(struct scsi_cmnd *SCpnt, unsigned long long lba,
return check_condition_result; return check_condition_result;
} }
read_lock_irqsave(&atomic_rw, iflags);
/* DIX + T10 DIF */ /* DIX + T10 DIF */
if (scsi_debug_dix && scsi_prot_sg_count(SCpnt)) { if (scsi_debug_dix && scsi_prot_sg_count(SCpnt)) {
int prot_ret = prot_verify_read(SCpnt, lba, num, ei_lba); int prot_ret = prot_verify_read(SCpnt, lba, num, ei_lba);
if (prot_ret) { if (prot_ret) {
read_unlock_irqrestore(&atomic_rw, iflags);
mk_sense_buffer(devip, ABORTED_COMMAND, 0x10, prot_ret); mk_sense_buffer(devip, ABORTED_COMMAND, 0x10, prot_ret);
return illegal_condition_result; return illegal_condition_result;
} }
} }
read_lock_irqsave(&atomic_rw, iflags);
ret = do_device_access(SCpnt, devip, lba, num, 0); ret = do_device_access(SCpnt, devip, lba, num, 0);
read_unlock_irqrestore(&atomic_rw, iflags); read_unlock_irqrestore(&atomic_rw, iflags);
if (ret == -1) if (ret == -1)
...@@ -2098,17 +2100,19 @@ static int resp_write(struct scsi_cmnd *SCpnt, unsigned long long lba, ...@@ -2098,17 +2100,19 @@ static int resp_write(struct scsi_cmnd *SCpnt, unsigned long long lba,
if (ret) if (ret)
return ret; return ret;
write_lock_irqsave(&atomic_rw, iflags);
/* DIX + T10 DIF */ /* DIX + T10 DIF */
if (scsi_debug_dix && scsi_prot_sg_count(SCpnt)) { if (scsi_debug_dix && scsi_prot_sg_count(SCpnt)) {
int prot_ret = prot_verify_write(SCpnt, lba, num, ei_lba); int prot_ret = prot_verify_write(SCpnt, lba, num, ei_lba);
if (prot_ret) { if (prot_ret) {
write_unlock_irqrestore(&atomic_rw, iflags);
mk_sense_buffer(devip, ILLEGAL_REQUEST, 0x10, prot_ret); mk_sense_buffer(devip, ILLEGAL_REQUEST, 0x10, prot_ret);
return illegal_condition_result; return illegal_condition_result;
} }
} }
write_lock_irqsave(&atomic_rw, iflags);
ret = do_device_access(SCpnt, devip, lba, num, 1); ret = do_device_access(SCpnt, devip, lba, num, 1);
if (scsi_debug_lbp()) if (scsi_debug_lbp())
map_region(lba, num); map_region(lba, num);
...@@ -2187,6 +2191,7 @@ static int resp_unmap(struct scsi_cmnd * scmd, struct sdebug_dev_info * devip) ...@@ -2187,6 +2191,7 @@ static int resp_unmap(struct scsi_cmnd * scmd, struct sdebug_dev_info * devip)
struct unmap_block_desc *desc; struct unmap_block_desc *desc;
unsigned int i, payload_len, descriptors; unsigned int i, payload_len, descriptors;
int ret; int ret;
unsigned long iflags;
ret = check_readiness(scmd, 1, devip); ret = check_readiness(scmd, 1, devip);
if (ret) if (ret)
...@@ -2208,6 +2213,8 @@ static int resp_unmap(struct scsi_cmnd * scmd, struct sdebug_dev_info * devip) ...@@ -2208,6 +2213,8 @@ static int resp_unmap(struct scsi_cmnd * scmd, struct sdebug_dev_info * devip)
desc = (void *)&buf[8]; desc = (void *)&buf[8];
write_lock_irqsave(&atomic_rw, iflags);
for (i = 0 ; i < descriptors ; i++) { for (i = 0 ; i < descriptors ; i++) {
unsigned long long lba = get_unaligned_be64(&desc[i].lba); unsigned long long lba = get_unaligned_be64(&desc[i].lba);
unsigned int num = get_unaligned_be32(&desc[i].blocks); unsigned int num = get_unaligned_be32(&desc[i].blocks);
...@@ -2222,6 +2229,7 @@ static int resp_unmap(struct scsi_cmnd * scmd, struct sdebug_dev_info * devip) ...@@ -2222,6 +2229,7 @@ static int resp_unmap(struct scsi_cmnd * scmd, struct sdebug_dev_info * devip)
ret = 0; ret = 0;
out: out:
write_unlock_irqrestore(&atomic_rw, iflags);
kfree(buf); kfree(buf);
return ret; return ret;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment