From owner-freebsd-bugs@FreeBSD.ORG Thu Jul 8 07:19:56 2004 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 6B54416A4CE; Thu, 8 Jul 2004 07:19:56 +0000 (GMT) Received: from mailout1.pacific.net.au (mailout1.pacific.net.au [61.8.0.84]) by mx1.FreeBSD.org (Postfix) with ESMTP id E386D43D49; Thu, 8 Jul 2004 07:19:55 +0000 (GMT) (envelope-from bde@zeta.org.au) Received: from mailproxy2.pacific.net.au (mailproxy2.pacific.net.au [61.8.0.87])i687Js4u009025; Thu, 8 Jul 2004 17:19:54 +1000 Received: from gamplex.bde.org (katana.zip.com.au [61.8.7.246]) i687Jpnl031936; Thu, 8 Jul 2004 17:19:53 +1000 Date: Thu, 8 Jul 2004 17:19:51 +1000 (EST) From: Bruce Evans X-X-Sender: bde@gamplex.bde.org To: KOIE Hidetaka In-Reply-To: <20040708.120756.104051089.koie@suri.co.jp> Message-ID: <20040708170007.J706@gamplex.bde.org> References: <200407051221.i65CLC3Q057710@www.freebsd.org> <20040708.120756.104051089.koie@suri.co.jp> MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII cc: freebsd-bugs@freebsd.org cc: freebsd-gnats-submit@freebsd.org Subject: Re: kern/68690: write(2) returns wrong vlalue when EFAULT 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: Thu, 08 Jul 2004 07:19:56 -0000 On Thu, 8 Jul 2004, KOIE Hidetaka wrote: > From: Bruce Evans > | Do you actually see the file pointer advanced? This may be file system > | dependent. ffs is supposed to back out of the write, and it does so > | for me. Output: > | > | %%% > | pos=0 > | write(20480)->-1 (should be 12288) > | write: Bad address > | pos=0 (should be 12288) > | %%% > > I was unaware of examining on NFS. I think you mean that you saw this error for nfs. > %%% > pos=0 > write(20480)->-1 (should be 12288) > write: Bad address > pos=8192 (should be 12288) > %%% > > The file pointer is not backed. I see this behaviour for nfs to. It is because nfs_write() just doesn't back out of the write like ffs_write does. From nfs_bio.c rev.1.132: % int % nfs_write(struct vop_write_args *ap) % { % ... % do { % ... % error = uiomove((char *)bp->b_data + on, n, uio); % % /* % * Since this block is being modified, it must be written % * again and not just committed. Since write clustering does % * not work for the stage 1 data write, only the stage 2 % * commit rpc, we have to clear B_CLUSTEROK as well. % */ % bp->b_flags &= ~(B_NEEDCOMMIT | B_CLUSTEROK); % % if (error) { % bp->b_ioflags |= BIO_ERROR; % brelse(bp); % break; % } % } while (uio->uio_resid > 0 && n > 0); % % if (haverslock) % nfs_rsunlock(np, td); % % return (error); % } After an error in uiomove(), nfs_write() just unlocks and returns, so it provides no protection from the bug in dofilewrite() even if the i/o was at the end of the file. Only the case where the error occurs before any i/o is done is handled correctly. Bruce