Re: [PATCH] SCSI: make use of the residue value

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Sat, 8 Mar 2008, James Bottomley wrote:

> > > The bottom line is that this patch won't work with variable length
> > > commands like inquiry that always return a residue.
> > 
> > You're saying that the amount of data returned is smaller that the 
> > amount requested because the data is variable length, right?
> 
> Yes.
> 
> > Under these circumstances the block layer should not resubmit anything.
> > That is, it should be smart enough to know that the "missing" data does
> > not in fact exist, as opposed to not being returned because of a
> > retryable device error.
> > 
> > Aren't requests for things like VPD distinguished from regular 
> > data-block accesses by a flag in the request structure already?  The 
> > block layer should take this flag into account when deciding whether to 
> > continue trying to transfer the "missing" data.  Maybe that needs to be 
> > fixed first.
> 
> I'm sure Jens will look at patches.

Actually it looks as though the faulty logic is in scsi_end_request()  
and/or scsi_io_completion().  The interface between those two routines
is quite confusing in regard to how the "requeue" argument is used.

At the site of the first call to scsi_end_request(), the code says:

	/* A number of bytes were successfully read.  If there
	 * are leftovers and there is some kind of error
	 * (result != 0), retry the rest.
	 */
	if (scsi_end_request(cmd, 0, good_bytes, result == 0) == NULL)
		return;

	/* good_bytes = 0, or (inclusive) there were leftovers and
	 * result = 0, so scsi_end_request couldn't retry.
	 */

These comments do a wonderful job of misdirecting the reader and 
encouraging him to conflate "requeue" with "retry".

If there are leftovers but error is 0, it seems reasonable to requeue
the remainder only when blk_fs_request(req) is true.  Anything else 
could simply be a short, variable-length response.

Do you think adding something like this is the right way to go?  I'm 
not sure it will work correctly.  What does one pass to 
blk_end_request() to indicate that the remaining data can't be 
transferred because it doesn't exist?

Or do you think that when blk_fs_request(req) isn't true, then 
scsi_io_completion() should get to decide whether or not to retry it?

Alan Stern


Index: usb-2.6/drivers/scsi/scsi_lib.c
===================================================================
--- usb-2.6.orig/drivers/scsi/scsi_lib.c
+++ usb-2.6/drivers/scsi/scsi_lib.c
@@ -667,10 +667,15 @@ static struct scsi_cmnd *scsi_end_reques
 		if (blk_pc_request(req))
 			leftover = req->data_len;
 
-		/* kill remainder if no retrys */
-		if (error && blk_noretry_request(req))
+		/* Kill remainder if no retrys.  For request types
+		 * other than REQ_TYPE_FS, !error indicates a normal
+		 * variable-length response so the remainder should
+		 * not be requeued.
+		 */
+		if ((error && blk_noretry_request(req)) ||
+		    (!error && !blk_fs_request(req))) {
 			blk_end_request(req, error, leftover);
-		else {
+		} else {
 			if (requeue) {
 				/*
 				 * Bleah.  Leftovers again.  Stick the
@@ -888,15 +893,16 @@ void scsi_io_completion(struct scsi_cmnd
 	if (clear_errors)
 		req->errors = 0;
 
-	/* A number of bytes were successfully read.  If there
-	 * are leftovers and there is some kind of error
-	 * (result != 0), retry the rest.
+	/* A number of bytes were successfully read.  If there are
+	 * leftovers and no error (result == 0), simply requeue them.
+	 * But if this isn't possible, we must figure out whether to
+	 * retry the command.
 	 */
 	if (scsi_end_request(cmd, 0, good_bytes, result == 0) == NULL)
 		return;
 
 	/* good_bytes = 0, or (inclusive) there were leftovers and
-	 * result = 0, so scsi_end_request couldn't retry.
+	 * result != 0, so scsi_end_request couldn't requeue.
 	 */
 	if (sense_valid && !sense_deferred) {
 		switch (sshdr.sense_key) {

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]
  Powered by Linux