Date: Thu, 8 Jul 2004 07:20:27 GMT From: Bruce Evans <bde@zeta.org.au> To: freebsd-bugs@FreeBSD.org Subject: Re: kern/68690: write(2) returns wrong vlalue when EFAULT Message-ID: <200407080720.i687KRQ1085978@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
The following reply was made to PR kern/68690; it has been noted by GNATS. From: Bruce Evans <bde@zeta.org.au> To: KOIE Hidetaka <koie@suri.co.jp> Cc: freebsd-gnats-submit@freebsd.org, freebsd-bugs@freebsd.org Subject: Re: kern/68690: write(2) returns wrong vlalue when EFAULT Date: Thu, 8 Jul 2004 17:19:51 +1000 (EST) On Thu, 8 Jul 2004, KOIE Hidetaka wrote: > From: Bruce Evans <bde@zeta.org.au> > | 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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200407080720.i687KRQ1085978>