From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756280AbcDDRQa (ORCPT ); Mon, 4 Apr 2016 13:16:30 -0400 Received: from zeniv.linux.org.uk ([195.92.253.2]:54052 "EHLO ZenIV.linux.org.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752410AbcDDRQ3 (ORCPT ); Mon, 4 Apr 2016 13:16:29 -0400 Date: Mon, 4 Apr 2016 18:16:12 +0100 From: Al Viro To: Christoph Hellwig Cc: Jens Axboe , linux-kernel@vger.kernel.org, linux-block@vger.kernel.org Subject: Re: [RFC] weird semantics of SG_DXFER_TO_FROM_DEV in BLK_DEV_SKD (drivers/block/skd*) Message-ID: <20160404171611.GF17997@ZenIV.linux.org.uk> References: <20160404033845.GE17997@ZenIV.linux.org.uk> <20160404065220.GA9447@infradead.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20160404065220.GA9447@infradead.org> User-Agent: Mutt/1.5.21 (2010-09-15) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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...