From owner-freebsd-bugs@FreeBSD.ORG Sat May 17 07:40:08 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 3AB0637B401 for ; Sat, 17 May 2003 07:40:08 -0700 (PDT) Received: from freefall.freebsd.org (freefall.freebsd.org [216.136.204.21]) by mx1.FreeBSD.org (Postfix) with ESMTP id B49FA43F75 for ; Sat, 17 May 2003 07:40:07 -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 h4HEe7Up002648 for ; Sat, 17 May 2003 07:40:07 -0700 (PDT) (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.12.9/8.12.9/Submit) id h4HEe7VT002647; Sat, 17 May 2003 07:40:07 -0700 (PDT) Date: Sat, 17 May 2003 07:40:07 -0700 (PDT) Message-Id: <200305171440.h4HEe7VT002647@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: Sat, 17 May 2003 14:40:08 -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: Sun, 18 May 2003 00:39:03 +1000 (EST) 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