Gerd Hoffmann wrote: > On 11/26/09 11:57, Hannes Reinecke wrote: >> Then the guest would see a partial request and retry the >> remainder of the request, which (possibly after some iterations) >> would result in all data transferred, albeit at a lower speed. > > Except they don't. > > /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); /* * 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); } scsi_io_completion(cmd, good_bytes); and in 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; No-one forces us to complete the _entire_ request; just completing the request partially is perfectly okay as long as we mark it properly. 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)