From owner-freebsd-bugs@FreeBSD.ORG Mon May 19 11:30:11 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 7F8B737B401 for ; Mon, 19 May 2003 11:30:11 -0700 (PDT) Received: from freefall.freebsd.org (freefall.freebsd.org [216.136.204.21]) by mx1.FreeBSD.org (Postfix) with ESMTP id EECBB43F75 for ; Mon, 19 May 2003 11:30:10 -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 h4JIUAUp070399 for ; Mon, 19 May 2003 11:30:10 -0700 (PDT) (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.12.9/8.12.9/Submit) id h4JIUAjP070398; Mon, 19 May 2003 11:30:10 -0700 (PDT) Date: Mon, 19 May 2003 11:30:10 -0700 (PDT) Message-Id: <200305191830.h4JIUAjP070398@freefall.freebsd.org> To: freebsd-bugs@FreeBSD.org From: Yar Tikhiy 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: Yar Tikhiy List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 19 May 2003 18:30:11 -0000 The following reply was made to PR kern/52338; it has been noted by GNATS. From: Yar Tikhiy To: Bruce Evans 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: Mon, 19 May 2003 22:23:57 +0400 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? 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. -- Yar --- 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); @@ -1677,6 +1678,7 @@ fdstrategy(struct bio *bp) if (fd->flags & FD_NONBLOCK) { bp->bio_error = EAGAIN; bp->bio_flags |= BIO_ERROR; + bp->bio_resid = bp->bio_bcount; goto bad; } if (bp->bio_blkno < 0) { @@ -1685,11 +1687,13 @@ fdstrategy(struct bio *bp) fdu, (u_long)bp->bio_blkno, bp->bio_bcount); bp->bio_error = EINVAL; bp->bio_flags |= BIO_ERROR; + bp->bio_resid = bp->bio_bcount; goto bad; } if ((bp->bio_bcount % fdblk) != 0) { bp->bio_error = EINVAL; bp->bio_flags |= BIO_ERROR; + bp->bio_resid = bp->bio_bcount; goto bad; } } @@ -1704,15 +1708,15 @@ fdstrategy(struct bio *bp) */ bp->bio_error = EINVAL; bp->bio_flags |= BIO_ERROR; + bp->bio_resid = bp->bio_bcount; goto bad; } blknum = bp->bio_blkno * DEV_BSIZE / fdblk; nblocks = fd->ft->size; if (blknum + bp->bio_bcount / fdblk > nblocks) { if (blknum >= nblocks) { - if (bp->bio_cmd == BIO_READ) - bp->bio_resid = bp->bio_bcount; - else { + bp->bio_resid = bp->bio_bcount; + if (bp->bio_cmd != BIO_READ) { bp->bio_error = ENOSPC; bp->bio_flags |= BIO_ERROR; } =================================================================