diff --git a/sys/vfs/ufs/ufs_readwrite.c b/sys/vfs/ufs/ufs_readwrite.c --- a/sys/vfs/ufs/ufs_readwrite.c +++ b/sys/vfs/ufs/ufs_readwrite.c @@ -65,7 +65,7 @@ struct buf *bp; off_t bytesinfile; int xfersize, blkoffset; - int error, orig_resid; + int error; size_t orig_resid; int seqcount; int ioflag; @@ -217,7 +217,7 @@ off_t osize; off_t nsize; int seqcount; - int blkoffset, error, extended, flags, ioflag, resid, size, xfersize; + int blkoffset, error, extended, flags, ioflag, size, xfersize, xferred; size_t resid; struct thread *td; extended = 0; @@ -287,6 +287,7 @@ else vclrflags(vp, VLASTWRITETS); + xferred = 0; for (error = 0; uio->uio_resid > 0;) { lbn = lblkno(fs, uio->uio_offset); blkoffset = blkoff(fs, uio->uio_offset); @@ -330,6 +331,7 @@ ap->a_cred, flags, &bp); if (error != 0) break; + xferred = 1; /* * If the buffer is not valid and we did not clear garbage * out above, we have to do so here even though the write @@ -397,9 +399,9 @@ * we clear the setuid and setgid bits as a precaution against * tampering. */ - if (resid > uio->uio_resid && ap->a_cred && ap->a_cred->cr_uid != 0) + if ((xferred || resid > uio->uio_resid) && ap->a_cred && ap->a_cred->cr_uid != 0) ip->i_mode &= ~(ISUID | ISGID); - if (resid > uio->uio_resid) + if (xferred || resid > uio->uio_resid) VN_KNOTE(vp, NOTE_WRITE | (extended ? NOTE_EXTEND : 0)); if (error) { if (ioflag & IO_UNIT) { @@ -408,7 +410,7 @@ uio->uio_offset -= resid - uio->uio_resid; uio->uio_resid = resid; } - } else if (resid > uio->uio_resid && (ioflag & IO_SYNC)) { + } else if ((xferred || resid > uio->uio_resid) && (ioflag & IO_SYNC)) { error = ffs_update(vp, 1); } else { ufs_itimes(vp);