From owner-freebsd-bugs@FreeBSD.ORG Sat May 17 07:39:18 2003 Return-Path: Delivered-To: freebsd-bugs@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id A899637B401; Sat, 17 May 2003 07:39:18 -0700 (PDT) Received: from mailman.zeta.org.au (mailman.zeta.org.au [203.26.10.16]) by mx1.FreeBSD.org (Postfix) with ESMTP id BCD1843F93; Sat, 17 May 2003 07:39:16 -0700 (PDT) (envelope-from bde@zeta.org.au) Received: from katana.zip.com.au (katana.zip.com.au [61.8.7.246]) by mailman.zeta.org.au (8.9.3p2/8.8.7) with ESMTP id AAA17952; Sun, 18 May 2003 00:39:04 +1000 Date: Sun, 18 May 2003 00:39:03 +1000 (EST) From: Bruce Evans X-X-Sender: bde@gamplex.bde.org To: Yar Tikhiy In-Reply-To: <20030517091047.GA82314@comp.chem.msu.su> Message-ID: <20030517235738.U16304@gamplex.bde.org> References: <200305161646.h4GGkdDS000677@stylish.chem.msu.su> <20030517091047.GA82314@comp.chem.msu.su> MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII cc: freebsd-bugs@freebsd.org cc: FreeBSD-gnats-submit@freebsd.org cc: joerg@freebsd.org 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 List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 17 May 2003 14:39:19 -0000 On Sat, 17 May 2003, Yar Tikhiy wrote: > I'm testing a somewhat different patch: > ... > But its first part yields an unexpected result: No error from > read() is reported at all! That happens because fdstrategy() doesn't > set bp->b_resid when indicating a error on a buffer; consequently, > the corresponding uio structure gets indication in physio() that > the data has been transferred; and dofileread() will clear the error > status if any bytes have been transferred and the error status is > EAGAIN or EINTR (see kern/sys_generic.c at line 195). 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). Strategy routines can return an error together with a count of bytes sucessfully transferred. They do this by setting BIO_ERROR and b_error as usual for an error, and returning the number of bytes _not_ successfully transferred in bio_resid. physio() actually understands this, although the upper layers are mostly broken (they should clear the error status and return the count of bytes successfully transferred in most cases, since there is no way to return both to the application layer and POSIX and POLA specify returning the count), but as you noticed they only do this for the EAGAIN and EINTR cases. This is a very old bug. Long ago, e.g., in FreeBSD-1, b_resid was (ab)used for a temporary variable by disksort(), so it was garbage in strategy routines unless they set it, but fdstrategy() didn't set it for early errors even in FreeBSD-1. Clobbering of b_resid in disksort() made early settings of it just bogus. Now, b_resid tends to stick at 0 which gives the fail-unsafe behaviour that you saw. Bruce