scsi,block: update SCSI to handle mixed merge failures
authorTejun Heo <tj@kernel.org>
Fri, 11 Sep 2009 12:26:40 +0000 (14:26 +0200)
committerJens Axboe <jens.axboe@oracle.com>
Fri, 11 Sep 2009 12:33:30 +0000 (14:33 +0200)
Update scsi_io_completion() such that it only fails requests till the
next error boundary and retry the leftover.  This enables block layer
to merge requests with different failfast settings and still behave
correctly on errors.  Allow merge of requests of different failfast
settings.

As SCSI is currently the only subsystem which follows failfast status,
there's no need to worry about other block drivers for now.

Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: Niel Lambrechts <niel.lambrechts@gmail.com>
Cc: James Bottomley <James.Bottomley@HansenPartnership.com>
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
block/blk-merge.c
block/elevator.c
drivers/scsi/scsi_lib.c

index 7c9ca01baa45eb33a4b14316a34a4c14c9a72115..b0de8574fdc84e40e1bdf87dea4eb1af98769bb4 100644 (file)
@@ -380,12 +380,6 @@ static int attempt_merge(struct request_queue *q, struct request *req,
        if (blk_integrity_rq(req) != blk_integrity_rq(next))
                return 0;
 
-       /* don't merge requests of different failfast settings */
-       if (blk_failfast_dev(req)       != blk_failfast_dev(next)       ||
-           blk_failfast_transport(req) != blk_failfast_transport(next) ||
-           blk_failfast_driver(req)    != blk_failfast_driver(next))
-               return 0;
-
        /*
         * If we are allowed to merge, then append bio list
         * from next to rq and release next. merge_requests_fn
index 2d511f9105e16abcf93cad6ac849ad9996661a32..ca861927ba41b2dfc9ff80c139f6c8cc162fc251 100644 (file)
@@ -100,19 +100,6 @@ int elv_rq_merge_ok(struct request *rq, struct bio *bio)
        if (bio_integrity(bio) != blk_integrity_rq(rq))
                return 0;
 
-       /*
-        * Don't merge if failfast settings don't match.
-        *
-        * FIXME: The negation in front of each condition is necessary
-        * because bio and request flags use different bit positions
-        * and the accessors return those bits directly.  This
-        * ugliness will soon go away.
-        */
-       if (!bio_failfast_dev(bio)       != !blk_failfast_dev(rq)       ||
-           !bio_failfast_transport(bio) != !blk_failfast_transport(rq) ||
-           !bio_failfast_driver(bio)    != !blk_failfast_driver(rq))
-               return 0;
-
        if (!elv_iosched_allow_merge(rq, bio))
                return 0;
 
index f3c40898fc7d305a9815acccc1e6e366c9f3dd5b..90c94da8baa445030265b85fa480a0d254a0ac98 100644 (file)
@@ -897,8 +897,10 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
                        if (driver_byte(result) & DRIVER_SENSE)
                                scsi_print_sense("", cmd);
                }
-               blk_end_request_all(req, -EIO);
-               scsi_next_command(cmd);
+               if (blk_end_request_err(req, -EIO))
+                       scsi_requeue_command(q, cmd);
+               else
+                       scsi_next_command(cmd);
                break;
        case ACTION_REPREP:
                /* Unprep the request and put it back at the head of the queue.