On Sun, Apr 03, 2016 at 11:52:20PM -0700, Christoph Hellwig wrote: > On Mon, Apr 04, 2016 at 04:38:45AM +0100, Al Viro wrote: > > I've no idea if anything is still using SG_DXFER_TO_FROM_DEV, but this > > behaviour AFAICS doesn't match that of write() on /dev/sg* (both > > in and out are done) or normal SG_IO (either both in and out, in case if it > > hits bio_map_user_iov(), or only out if it hits bio_copy_user_iov()). In > > all cases the out part is done. Here it is skipped. > > > > Not sure who (if anybody) maintains it these days, but that behaviour looks > > wrong... > > The right fix is to kill the duplicate SG_IO implementation and use > the block layer one. The driver actually is a pretty straight SCSI > implementation, so making it a block driver has been a mistake from the > start. I'll see if I can maybe get hold of hardware for the driver - it > seems pretty much unmaintained unfortunately. OK... FWIW, that's the last remaining user of iov_shorten(); I have a patch getting rid of it (preserving the behaviour of that driver), but behaviour appears to be bogus... Another fun question: should the normal sg_io() copy the buffer in on SG_DXFER_TO_FROM_DEV? Right now it doesn't; in !copy case (when it goes through bio_map_user_iov()) the effect is achieved simply by doing the read into the pages user has mapped in that area, but bio_copy_user_iov() doesn't do it: /* * success */ if (((iter->type & WRITE) && (!map_data || !map_data->null_mapped)) || (map_data && map_data->from_user)) { ret = bio_copy_from_iter(bio, *iter); if (ret) goto cleanup; } will see NULL map_data; the ->from_user case is sg_start_req() stuff. IOW, SG_IO behaviour for /dev/sg* is different from the generic one... -- To unsubscribe from this list: send the line "unsubscribe linux-block" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html