Gerd Hoffmann wrote: > On 11/26/09 12:20, Hannes Reinecke wrote: >> Gerd Hoffmann wrote: >>> /me looks at drivers/scsi/sd.c:sd_done() >>> >>> I can't see any sane way to tell linux that the request was too big. >>> >> residuals is the key: >> >> drivers/scsi/scsi.c:scsi_finish_command() >> >> >> good_bytes = scsi_bufflen(cmd); >> if (cmd->request->cmd_type != REQ_TYPE_BLOCK_PC) { >> int old_good_bytes = good_bytes; >> drv = scsi_cmd_to_driver(cmd); >> if (drv->done) >> good_bytes = drv->done(cmd); > > drv->done() actually is sd_done() mentioned above. > > sd_done() tries to figure how many sectors it actually got for serious > errors. I don't feel signaling "medium error" for the first sector > behind our limit just because we'd like to have smaller requests. > >> /* >> * USB may not give sense identifying bad sector and >> * simply return a residue instead, so subtract off the >> * residue if drv->done() error processing indicates no >> * change to the completion length. >> */ >> if (good_bytes == old_good_bytes) >> good_bytes -= scsi_get_resid(cmd); > > Poor mans bad sector identification. Same issue as above IMHO. On top > of that I wouldn't expect all other guest OSes having the same quirk in > there to handle usb disks. > Sigh. Communication seems to be tricky here.
Please, just ignore scsi_finish_command(), it's not doing anything useful here. Do skip this and study the next snipped, scsi_io_completion(): drivers/scsi/scsi_lib.c:scsi_io_completion() /* * 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, error, good_bytes, result == 0) == NULL) return; scsi_end_request is being called with the number of bytes _actually processed_, which might be less than the number of bytes requested. And the remainder will be retried by the upper layers. Cheers, Hannes -- Dr. Hannes Reinecke zSeries & Storage h...@suse.de +49 911 74053 688 SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg GF: Markus Rex, HRB 16746 (AG Nürnberg)