[v2,6/6] scsi:scsi_debug: set command's result and sense data if the error is injected

Message ID 20230428013320.347050-7-haowenchao2@huawei.com
State New
Headers
Series scsi:scsi_debug: Add error injection for single device |

Commit Message

Wenchao Hao April 28, 2023, 1:33 a.m. UTC
  If a fail commnd error is injected, set the command's status and sense
data then finish this scsi command.

For example, the following command would make read(0x88) command finished
with UNC for 8 times:
  error=/sys/kernel/debug/scsi_debug/0:0:0:1/error
  echo "2 -8 0x88 0 0 0x2 0x3 0x11 0x0" >$error

Signed-off-by: Wenchao Hao <haowenchao2@huawei.com>
---
 drivers/scsi/scsi_debug.c | 46 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 46 insertions(+)
  

Comments

Dan Carpenter May 11, 2023, 11:02 a.m. UTC | #1
Hi Wenchao,

kernel test robot noticed the following build warnings:

https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Wenchao-Hao/scsi-scsi_debug-create-scsi_debug-directory-in-the-debugfs-filesystem/20230427-201534
base:   https://git.kernel.org/pub/scm/linux/kernel/git/mkp/scsi.git for-next
patch link:    https://lore.kernel.org/r/20230428013320.347050-7-haowenchao2%40huawei.com
patch subject: [PATCH v2 6/6] scsi:scsi_debug: set command's result and sense data if the error is injected
config: mips-randconfig-m041-20230509 (https://download.01.org/0day-ci/archive/20230511/202305111419.HegopAw8-lkp@intel.com/config)
compiler: mips-linux-gcc (GCC) 12.1.0

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <lkp@intel.com>
| Reported-by: Dan Carpenter <error27@gmail.com>
| Link: https://lore.kernel.org/r/202305111419.HegopAw8-lkp@intel.com/

New smatch warnings:
drivers/scsi/scsi_debug.c:7880 scsi_debug_queuecommand() warn: missing error code? 'ret'

Old smatch warnings:
drivers/scsi/scsi_debug.c:5389 scsi_debug_slave_destroy() warn: variable dereferenced before check 'devip' (see line 5388)

vim +/ret +7880 drivers/scsi/scsi_debug.c

70abb3e2434633 Wenchao Hao     2023-04-28  7861  	if (sdebug_timeout_cmd(scp)) {
70abb3e2434633 Wenchao Hao     2023-04-28  7862  		scmd_printk(KERN_INFO, scp, "timeout command 0x%x\n", opcode);
70abb3e2434633 Wenchao Hao     2023-04-28  7863  		return 0;
70abb3e2434633 Wenchao Hao     2023-04-28  7864  	}
70abb3e2434633 Wenchao Hao     2023-04-28  7865  
b3f5d28c11bee2 Wenchao Hao     2023-04-28  7866  	ret = sdebug_fail_queue_cmd(scp);
b3f5d28c11bee2 Wenchao Hao     2023-04-28  7867  	if (ret) {
                                                            ^^^

b3f5d28c11bee2 Wenchao Hao     2023-04-28  7868  		scmd_printk(KERN_INFO, scp, "fail queue command 0x%x with 0x%x\n",
b3f5d28c11bee2 Wenchao Hao     2023-04-28  7869  				opcode, ret);
b3f5d28c11bee2 Wenchao Hao     2023-04-28  7870  		return ret;
b3f5d28c11bee2 Wenchao Hao     2023-04-28  7871  	}
b3f5d28c11bee2 Wenchao Hao     2023-04-28  7872  
ef1cd466d439a1 Wenchao Hao     2023-04-28  7873  	if (sdebug_fail_cmd(scp, &ret, &err)) {
ef1cd466d439a1 Wenchao Hao     2023-04-28  7874  		scmd_printk(KERN_INFO, scp,
ef1cd466d439a1 Wenchao Hao     2023-04-28  7875  			"fail command 0x%x with hostbyte=0x%x, "
ef1cd466d439a1 Wenchao Hao     2023-04-28  7876  			"driverbyte=0x%x, statusbyte=0x%x, "
ef1cd466d439a1 Wenchao Hao     2023-04-28  7877  			"sense_key=0x%x, asc=0x%x, asq=0x%x\n",
ef1cd466d439a1 Wenchao Hao     2023-04-28  7878  			opcode, err.host_byte, err.driver_byte,
ef1cd466d439a1 Wenchao Hao     2023-04-28  7879  			err.status_byte, err.sense_key, err.asc, err.asq);
ef1cd466d439a1 Wenchao Hao     2023-04-28 @7880  		return ret;

ret is success.

ef1cd466d439a1 Wenchao Hao     2023-04-28  7881  	}
ef1cd466d439a1 Wenchao Hao     2023-04-28  7882  
3a90a63d02b8b7 Douglas Gilbert 2020-07-12  7883  	if (unlikely(inject_now && !atomic_read(&sdeb_inject_pending)))
3a90a63d02b8b7 Douglas Gilbert 2020-07-12  7884  		atomic_set(&sdeb_inject_pending, 1);
3a90a63d02b8b7 Douglas Gilbert 2020-07-12  7885  
c2248fc974df7b Douglas Gilbert 2014-11-24  7886  	na = oip->num_attached;
c2248fc974df7b Douglas Gilbert 2014-11-24  7887  	r_pfp = oip->pfp;
  

Patch

diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index 340299e63069..1e2aab708a8b 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -7762,6 +7762,41 @@  static int sdebug_fail_queue_cmd(struct scsi_cmnd *cmnd)
 	return 0;
 }
 
+static int sdebug_fail_cmd(struct scsi_cmnd *cmnd, int *retval,
+			   struct sdebug_err_inject *info)
+{
+	struct scsi_device *sdp = cmnd->device;
+	struct sdebug_dev_info *devip = (struct sdebug_dev_info *)sdp->hostdata;
+	struct sdebug_err_inject *err;
+	unsigned char *cmd = cmnd->cmnd;
+	int ret = 0;
+	int result;
+
+	if (devip == NULL)
+		return 0;
+
+	list_for_each_entry(err, &devip->inject_err_list, list) {
+		if (err->type == ERR_FAIL_CMD &&
+		    (err->cmd == cmd[0] || err->cmd == 0xff)) {
+			if (!err->cnt)
+				return 0;
+			ret = !!err->cnt;
+			goto out_handle;
+		}
+	}
+	return 0;
+
+out_handle:
+	if (err->cnt < 0)
+		err->cnt++;
+	mk_sense_buffer(cmnd, err->sense_key, err->asc, err->asq);
+	result = err->status_byte | err->host_byte << 16 | err->driver_byte << 24;
+	*info = *err;
+	*retval = schedule_resp(cmnd, devip, result, NULL, 0, 0);
+
+	return ret;
+}
+
 static int scsi_debug_queuecommand(struct Scsi_Host *shost,
 				   struct scsi_cmnd *scp)
 {
@@ -7782,6 +7817,7 @@  static int scsi_debug_queuecommand(struct Scsi_Host *shost,
 	bool has_wlun_rl;
 	bool inject_now;
 	int ret = 0;
+	struct sdebug_err_inject err;
 
 	scsi_set_resid(scp, 0);
 	if (sdebug_statistics) {
@@ -7834,6 +7870,16 @@  static int scsi_debug_queuecommand(struct Scsi_Host *shost,
 		return ret;
 	}
 
+	if (sdebug_fail_cmd(scp, &ret, &err)) {
+		scmd_printk(KERN_INFO, scp,
+			"fail command 0x%x with hostbyte=0x%x, "
+			"driverbyte=0x%x, statusbyte=0x%x, "
+			"sense_key=0x%x, asc=0x%x, asq=0x%x\n",
+			opcode, err.host_byte, err.driver_byte,
+			err.status_byte, err.sense_key, err.asc, err.asq);
+		return ret;
+	}
+
 	if (unlikely(inject_now && !atomic_read(&sdeb_inject_pending)))
 		atomic_set(&sdeb_inject_pending, 1);