kern/68690: write(2) returns wrong vlalue when EFAULT
Bruce Evans
bde at zeta.org.au
Thu Jul 8 00:20:28 PDT 2004
The following reply was made to PR kern/68690; it has been noted by GNATS.
From: Bruce Evans <bde at zeta.org.au>
To: KOIE Hidetaka <koie at suri.co.jp>
Cc: freebsd-gnats-submit at freebsd.org, freebsd-bugs at 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 at 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
More information about the freebsd-bugs
mailing list