From owner-freebsd-bugs@FreeBSD.ORG Thu May 22 05:20:10 2003 Return-Path: Delivered-To: freebsd-bugs@hub.freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 1513A37B401 for ; Thu, 22 May 2003 05:20:10 -0700 (PDT) Received: from freefall.freebsd.org (freefall.freebsd.org [216.136.204.21]) by mx1.FreeBSD.org (Postfix) with ESMTP id 8DD7743F3F for ; Thu, 22 May 2003 05:20:09 -0700 (PDT) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) by freefall.freebsd.org (8.12.9/8.12.9) with ESMTP id h4MCK9Up046314 for ; Thu, 22 May 2003 05:20:09 -0700 (PDT) (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.12.9/8.12.9/Submit) id h4MCK9Fw046313; Thu, 22 May 2003 05:20:09 -0700 (PDT) Date: Thu, 22 May 2003 05:20:09 -0700 (PDT) Message-Id: <200305221220.h4MCK9Fw046313@freefall.freebsd.org> To: freebsd-bugs@FreeBSD.org From: Bruce Evans Subject: Re: kern/52338: fd(4) floppy disk driver & non-blocking I/O X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list Reply-To: Bruce Evans List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 22 May 2003 12:20:10 -0000 The following reply was made to PR kern/52338; it has been noted by GNATS. From: Bruce Evans To: Yar Tikhiy Cc: FreeBSD-gnats-submit@freebsd.org, freebsd-bugs@freebsd.org, joerg@freebsd.org Subject: Re: kern/52338: fd(4) floppy disk driver & non-blocking I/O Date: Thu, 22 May 2003 22:19:20 +1000 (EST) On Mon, 19 May 2003, Yar Tikhiy wrote: > On Sun, May 18, 2003 at 12:39:03AM +1000, Bruce Evans wrote: > > > > It should set bp->bio_resid (to bp->bio_bcount) (bio_resid and bio_bcount > > are the same as b_resid and b_bcount here; strategy routines only have > > access to a struct bio so they must use the former). > > What do you think about the following straightforward patch to fd.c? > It catches all spots where BIO_ERROR is set, but bio_resid isn't. > In fd.c, bio_resid is never set in advance, so the simplest approach > should work. > > OTOH, I wonder if bio_resid could be set equal to bio_bcount at the > beginning of fdstrategy() and changed only if needed. Does this have > any obscure implications? I think that is the right place to set it. The residual count really is the full count initially. Any obfuscations come later. The driver might prefer to only set bio_resid to its final value at the end of normal i/o instead of as every block is finished. Then the initial setting would only used for abnormal i/o. This is essentially what the fd driver does (except it just forgets to set bio_resid for abnormal i/o). > And my other thought is: What if physio() sets bio_resid equal to > bio_bcount before calling DEV_STRATEGY()? Currently, physio() > leaves bio_resid unset. An obvious drawback of this approach is > that it would encourage poor coding in drivers, though. Rev.1.37 of kern/subr_disk.c sets bio_resid to bio_bcount in the generic strategy routine. This is a better place than physio(). The fd driver didn't benefit from this because it never used the disk mini-layer. Now geom is used instead of the disk mini-layer. geom now uses essentially the same method as the fd driver for normal i/o -- it keeps track of the amount of i/o completed and subtracts this from bio_bcount to get bio_resid when i/o completes, and it doesn't set bio_resid initially. The fd driver doesn't benefit from this because it doesn't use geom either. > --- fd.c.dist Fri Apr 11 15:39:24 2003 > +++ fd.c Mon May 19 21:48:11 2003 > @@ -1668,8 +1668,9 @@ fdstrategy(struct bio *bp) > (u_long)major(bp->bio_dev), (u_long)minor(bp->bio_dev)); > fdc = fd->fdc; > if (fd->type == FDT_NONE || fd->ft == 0) { > - bp->bio_error = ENXIO; > + bp->bio_error = fd->type == FDT_NONE ? ENXIO : EAGAIN; > bp->bio_flags |= BIO_ERROR; > + bp->bio_resid = bp->bio_bcount; > goto bad; > } > fdblk = 128 << (fd->ft->secsize); I think this should check FD_NONBLOCK like the next clause does, and only return EAGAIN when FD_NONBLOCK is set. This is clearer even if it is equivalent (can we get here with a type but no ft?). Bruce