aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorAkinobu Mita <akinobu.mita@gmail.com>2014-02-26 08:57:03 -0500
committerJames Bottomley <JBottomley@Parallels.com>2014-03-19 18:04:30 -0400
commit6c78cc06583344244628bf29aa5b5fe43ff5d04e (patch)
tree6ef80001e2fe6f27993cb708003092acf5ebd771 /drivers/scsi
parentbe4e11be99dbb36308760595ee848ef51713b4b0 (diff)
[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: Akinobu Mita <akinobu.mita@gmail.com> Reviewed-by: Douglas Gilbert <dgilbert@interlog.com> Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/scsi_debug.c12
1 files changed, 10 insertions, 2 deletions
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index 004b98566c41..0bb1d49c3552 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -1888,17 +1888,19 @@ static int resp_read(struct scsi_cmnd *SCpnt, unsigned long long lba,
1888 return check_condition_result; 1888 return check_condition_result;
1889 } 1889 }
1890 1890
1891 read_lock_irqsave(&atomic_rw, iflags);
1892
1891 /* DIX + T10 DIF */ 1893 /* DIX + T10 DIF */
1892 if (scsi_debug_dix && scsi_prot_sg_count(SCpnt)) { 1894 if (scsi_debug_dix && scsi_prot_sg_count(SCpnt)) {
1893 int prot_ret = prot_verify_read(SCpnt, lba, num, ei_lba); 1895 int prot_ret = prot_verify_read(SCpnt, lba, num, ei_lba);
1894 1896
1895 if (prot_ret) { 1897 if (prot_ret) {
1898 read_unlock_irqrestore(&atomic_rw, iflags);
1896 mk_sense_buffer(devip, ABORTED_COMMAND, 0x10, prot_ret); 1899 mk_sense_buffer(devip, ABORTED_COMMAND, 0x10, prot_ret);
1897 return illegal_condition_result; 1900 return illegal_condition_result;
1898 } 1901 }
1899 } 1902 }
1900 1903
1901 read_lock_irqsave(&atomic_rw, iflags);
1902 ret = do_device_access(SCpnt, devip, lba, num, 0); 1904 ret = do_device_access(SCpnt, devip, lba, num, 0);
1903 read_unlock_irqrestore(&atomic_rw, iflags); 1905 read_unlock_irqrestore(&atomic_rw, iflags);
1904 if (ret == -1) 1906 if (ret == -1)
@@ -2098,17 +2100,19 @@ static int resp_write(struct scsi_cmnd *SCpnt, unsigned long long lba,
2098 if (ret) 2100 if (ret)
2099 return ret; 2101 return ret;
2100 2102
2103 write_lock_irqsave(&atomic_rw, iflags);
2104
2101 /* DIX + T10 DIF */ 2105 /* DIX + T10 DIF */
2102 if (scsi_debug_dix && scsi_prot_sg_count(SCpnt)) { 2106 if (scsi_debug_dix && scsi_prot_sg_count(SCpnt)) {
2103 int prot_ret = prot_verify_write(SCpnt, lba, num, ei_lba); 2107 int prot_ret = prot_verify_write(SCpnt, lba, num, ei_lba);
2104 2108
2105 if (prot_ret) { 2109 if (prot_ret) {
2110 write_unlock_irqrestore(&atomic_rw, iflags);
2106 mk_sense_buffer(devip, ILLEGAL_REQUEST, 0x10, prot_ret); 2111 mk_sense_buffer(devip, ILLEGAL_REQUEST, 0x10, prot_ret);
2107 return illegal_condition_result; 2112 return illegal_condition_result;
2108 } 2113 }
2109 } 2114 }
2110 2115
2111 write_lock_irqsave(&atomic_rw, iflags);
2112 ret = do_device_access(SCpnt, devip, lba, num, 1); 2116 ret = do_device_access(SCpnt, devip, lba, num, 1);
2113 if (scsi_debug_lbp()) 2117 if (scsi_debug_lbp())
2114 map_region(lba, num); 2118 map_region(lba, num);
@@ -2187,6 +2191,7 @@ static int resp_unmap(struct scsi_cmnd * scmd, struct sdebug_dev_info * devip)
2187 struct unmap_block_desc *desc; 2191 struct unmap_block_desc *desc;
2188 unsigned int i, payload_len, descriptors; 2192 unsigned int i, payload_len, descriptors;
2189 int ret; 2193 int ret;
2194 unsigned long iflags;
2190 2195
2191 ret = check_readiness(scmd, 1, devip); 2196 ret = check_readiness(scmd, 1, devip);
2192 if (ret) 2197 if (ret)
@@ -2208,6 +2213,8 @@ static int resp_unmap(struct scsi_cmnd * scmd, struct sdebug_dev_info * devip)
2208 2213
2209 desc = (void *)&buf[8]; 2214 desc = (void *)&buf[8];
2210 2215
2216 write_lock_irqsave(&atomic_rw, iflags);
2217
2211 for (i = 0 ; i < descriptors ; i++) { 2218 for (i = 0 ; i < descriptors ; i++) {
2212 unsigned long long lba = get_unaligned_be64(&desc[i].lba); 2219 unsigned long long lba = get_unaligned_be64(&desc[i].lba);
2213 unsigned int num = get_unaligned_be32(&desc[i].blocks); 2220 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 ret = 0; 2229 ret = 0;
2223 2230
2224out: 2231out:
2232 write_unlock_irqrestore(&atomic_rw, iflags);
2225 kfree(buf); 2233 kfree(buf);
2226 2234
2227 return ret; 2235 return ret;