07_scsi_consolidate_prep_fn_error_handling.patch

        When scsi_init_io() returns BLKPREP_DEFER or BLKPREP_KILL,
        it's supposed to free resources itself.  This patch
        consolidates defer and kill handling into scsi_prep_fn().
        This fixes a queue stall bug which occurred when sgtable
        allocation failed and device_busy == 0.

Signed-off-by: Tejun Heo <[EMAIL PROTECTED]>

 scsi_lib.c |   23 ++++++++++++-----------
 1 files changed, 12 insertions(+), 11 deletions(-)

Index: scsi-export/drivers/scsi/scsi_lib.c
===================================================================
--- scsi-export.orig/drivers/scsi/scsi_lib.c    2005-03-31 18:06:21.000000000 
+0900
+++ scsi-export/drivers/scsi/scsi_lib.c 2005-03-31 18:06:21.000000000 +0900
@@ -960,9 +960,6 @@ static int scsi_init_io(struct scsi_cmnd
        printk(KERN_ERR "req nr_sec %lu, cur_nr_sec %u\n", req->nr_sectors,
                        req->current_nr_sectors);
 
-       /* release the command and kill it */
-       scsi_release_buffers(cmd);
-       scsi_put_command(cmd);
        return BLKPREP_KILL;
 }
 
@@ -1130,18 +1127,17 @@ static int scsi_prep_fn(struct request_q
                 * required).
                 */
                ret = scsi_init_io(cmd);
-               if (ret)        /* BLKPREP_KILL return also releases the 
command */
-                       return ret;
-               
+               if (ret == BLKPREP_DEFER)
+                       goto defer;
+               else if (ret == BLKPREP_KILL)
+                       goto kill;
+
                /*
                 * Initialize the actual SCSI command for this request.
                 */
                drv = *(struct scsi_driver **)req->rq_disk->private_data;
-               if (unlikely(!drv->init_command(cmd))) {
-                       scsi_release_buffers(cmd);
-                       scsi_put_command(cmd);
-                       return BLKPREP_KILL;
-               }
+               if (unlikely(!drv->init_command(cmd)))
+                       goto kill;
        }
 
        /*
@@ -1157,6 +1153,11 @@ static int scsi_prep_fn(struct request_q
        if (sdev->device_busy == 0)
                blk_plug_device(q);
        return BLKPREP_DEFER;
+
+ kill:
+       scsi_release_buffers(cmd);
+       scsi_put_command(cmd);
+       return BLKPREP_KILL;
 }
 
 /*

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to