Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 19 May 2003 22:23:57 +0400
From:      Yar Tikhiy <yar@freebsd.org>
To:        Bruce Evans <bde@zeta.org.au>
Cc:        joerg@freebsd.org
Subject:   Re: kern/52338: fd(4) floppy disk driver & non-blocking I/O
Message-ID:  <20030519182357.GA99588@comp.chem.msu.su>
In-Reply-To: <20030517235738.U16304@gamplex.bde.org>
References:  <200305161646.h4GGkdDS000677@stylish.chem.msu.su> <20030517165718.B15076@gamplex.bde.org> <20030517091047.GA82314@comp.chem.msu.su> <20030517235738.U16304@gamplex.bde.org>

next in thread | previous in thread | raw e-mail | index | archive | help
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;
 			}
=================================================================



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20030519182357.GA99588>