diff mbox series

scsi: target: fix prot handling in WRITE SAME 32

Message ID 20210616095632.16775-1-d.bogdanov@yadro.com
State New
Headers show
Series scsi: target: fix prot handling in WRITE SAME 32 | expand

Commit Message

Dmitry Bogdanov June 16, 2021, 9:56 a.m. UTC
WRITE SAME 32 command handling reads WRPROTECT at the wrong offset
in 1st octet instead of 10th octet.

Fixes: afd73f1b60fc ("target: Perform PROTECT sanity checks for WRITE_SAME")
Signed-off-by: Dmitry Bogdanov <d.bogdanov@yadro.com>
---
 drivers/target/target_core_sbc.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

Comments

Martin K. Petersen June 29, 2021, 3:01 a.m. UTC | #1
Dmitry,

> WRITE SAME 32 command handling reads WRPROTECT at the wrong offset

> in 1st octet instead of 10th octet.


Instead of twiddling all these offsets I think it would be cleaner to
turn the sbc_setup_write_same() flags[] into an 'unsigned char
protect'. And then fix up sbc_check_prot() to take 'protect' as argument
instead of the full CDB and indexing into that.

Another option would be passing the index but since cdb[0] is only used
for a rare error message I'm not sure it's worth it.

-- 
Martin K. Petersen	Oracle Linux Engineering
Dmitry Bogdanov June 29, 2021, 4:29 p.m. UTC | #2
Hi Martin,

> > WRITE SAME 32 command handling reads WRPROTECT at the wrong offset in 

> > 1st octet instead of 10th octet.


> Instead of twiddling all these offsets I think it would be cleaner to turn the sbc_setup_write_same() flags[] into an 'unsigned char protect'. And then fix up

> sbc_check_prot() to take 'protect' as argument instead of the full CDB and indexing into that.


OK, I will prepare new version of the patch.

> Another option would be passing the index but since cdb[0] is only used for a rare error message I'm not sure it's worth it.


BR,
 Dmitry
diff mbox series

Patch

diff --git a/drivers/target/target_core_sbc.c b/drivers/target/target_core_sbc.c
index f7c527a826fd..309aae33c358 100644
--- a/drivers/target/target_core_sbc.c
+++ b/drivers/target/target_core_sbc.c
@@ -286,7 +286,7 @@  sbc_setup_write_same(struct se_cmd *cmd, unsigned char *flags, struct sbc_ops *o
 	unsigned int sectors = sbc_get_write_same_sectors(cmd);
 	sense_reason_t ret;
 
-	if ((flags[0] & 0x04) || (flags[0] & 0x02)) {
+	if ((flags[1] & 0x04) || (flags[1] & 0x02)) {
 		pr_err("WRITE_SAME PBDATA and LBDATA"
 			" bits not supported for Block Discard"
 			" Emulation\n");
@@ -308,7 +308,7 @@  sbc_setup_write_same(struct se_cmd *cmd, unsigned char *flags, struct sbc_ops *o
 	}
 
 	/* We always have ANC_SUP == 0 so setting ANCHOR is always an error */
-	if (flags[0] & 0x10) {
+	if (flags[1] & 0x10) {
 		pr_warn("WRITE SAME with ANCHOR not supported\n");
 		return TCM_INVALID_CDB_FIELD;
 	}
@@ -316,7 +316,7 @@  sbc_setup_write_same(struct se_cmd *cmd, unsigned char *flags, struct sbc_ops *o
 	 * Special case for WRITE_SAME w/ UNMAP=1 that ends up getting
 	 * translated into block discard requests within backend code.
 	 */
-	if (flags[0] & 0x08) {
+	if (flags[1] & 0x08) {
 		if (!ops->execute_unmap)
 			return TCM_UNSUPPORTED_SCSI_OPCODE;
 
@@ -331,7 +331,7 @@  sbc_setup_write_same(struct se_cmd *cmd, unsigned char *flags, struct sbc_ops *o
 	if (!ops->execute_write_same)
 		return TCM_UNSUPPORTED_SCSI_OPCODE;
 
-	ret = sbc_check_prot(dev, cmd, &cmd->t_task_cdb[0], sectors, true);
+	ret = sbc_check_prot(dev, cmd, flags, sectors, true);
 	if (ret)
 		return ret;
 
@@ -980,7 +980,7 @@  sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops)
 			size = sbc_get_size(cmd, 1);
 			cmd->t_task_lba = get_unaligned_be64(&cdb[12]);
 
-			ret = sbc_setup_write_same(cmd, &cdb[10], ops);
+			ret = sbc_setup_write_same(cmd, &cdb[9], ops);
 			if (ret)
 				return ret;
 			break;
@@ -1079,7 +1079,7 @@  sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops)
 		size = sbc_get_size(cmd, 1);
 		cmd->t_task_lba = get_unaligned_be64(&cdb[2]);
 
-		ret = sbc_setup_write_same(cmd, &cdb[1], ops);
+		ret = sbc_setup_write_same(cmd, cdb, ops);
 		if (ret)
 			return ret;
 		break;