[SCSI] Fix printing of failed 32-byte commands
authorMartin K. Petersen <martin.petersen@oracle.com>
Wed, 20 Jan 2010 07:20:43 +0000 (02:20 -0500)
committerJames Bottomley <James.Bottomley@suse.de>
Fri, 19 Feb 2010 17:15:33 +0000 (11:15 -0600)
Having the large CDB allocation logic in sd.c means that
scsi_io_completion does not have access to the command buffer. That in
turn causes garbage to be printed when a 32-byte command fails. Move the
command printing to sd_done where the command buffer is intact.  Clear
the command buffer pointer after the extended CDB has been freed.

Make scsi_print_command ignore commands with NULL CDB pointers to
inhibit printing of garbled command strings.

Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Reviewed-by: Boaz Harrosh <bharrosh@panasas.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
drivers/scsi/constants.c
drivers/scsi/sd.c

index 7092ff67ecd39fdef1d932887e8c568494430c4f..cd05e049d5f6ad7164c6485ee336db00933c63b0 100644 (file)
@@ -346,6 +346,9 @@ void scsi_print_command(struct scsi_cmnd *cmd)
 {
        int k;
 
+       if (cmd->cmnd == NULL)
+               return;
+
        scmd_printk(KERN_INFO, cmd, "CDB: ");
        print_opcode_name(cmd->cmnd, cmd->cmd_len);
 
index 908d400b601a2e773d3b16db3e4386dc5273975f..1dd4d8407694b44fac24501ffd0b8db5bf8cd7e5 100644 (file)
@@ -1209,8 +1209,19 @@ static int sd_done(struct scsi_cmnd *SCpnt)
                sd_dif_complete(SCpnt, good_bytes);
 
        if (scsi_host_dif_capable(sdkp->device->host, sdkp->protection_type)
-           == SD_DIF_TYPE2_PROTECTION && SCpnt->cmnd != SCpnt->request->cmd)
+           == SD_DIF_TYPE2_PROTECTION && SCpnt->cmnd != SCpnt->request->cmd) {
+
+               /* We have to print a failed command here as the
+                * extended CDB gets freed before scsi_io_completion()
+                * is called.
+                */
+               if (result)
+                       scsi_print_command(SCpnt);
+
                mempool_free(SCpnt->cmnd, sd_cdb_pool);
+               SCpnt->cmnd = NULL;
+               SCpnt->cmd_len = 0;
+       }
 
        return good_bytes;
 }