fusefs: simplify fuse_write_biobackend. No functional change.

Sponsored by:	The FreeBSD Foundation
This commit is contained in:
Alan Somers 2019-06-05 20:18:56 +00:00
parent d2654efffe
commit 011bca9948
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/projects/fuse2/; revision=348700

View File

@ -594,6 +594,8 @@ fuse_write_biobackend(struct vnode *vp, struct uio *uio,
* no point optimizing for something that really won't ever happen.
*/
do {
bool direct_append, extending;
if (fuse_isdeadfs(vp)) {
err = ENXIO;
break;
@ -603,68 +605,54 @@ fuse_write_biobackend(struct vnode *vp, struct uio *uio,
n = MIN((unsigned)(biosize - on), uio->uio_resid);
again:
/*
* Handle direct append and file extension cases, calculate
* unaligned buffer size.
*/
if (uio->uio_offset == filesize && n) {
/*
* Get the buffer (in its pre-append state to maintain
* B_CACHE if it was previously set). Resize the
* nfsnode after we have locked the buffer to prevent
* readers from reading garbage.
*/
bcount = on;
SDT_PROBE6(fusefs, , io, write_biobackend_start,
lbn, on, n, uio, bcount, true);
bp = getblk(vp, lbn, bcount, PCATCH, 0, 0);
/* Get or create a buffer for the write */
direct_append = uio->uio_offset == filesize && n;
if ((off_t)lbn * biosize + on + n < filesize) {
extending = false;
if ((off_t)(lbn + 1) * biosize < filesize) {
/* Not the file's last block */
bcount = biosize;
} else {
/* The file's last block */
bcount = filesize - (off_t)lbn *biosize;
}
} else {
extending = true;
bcount = on + n;
}
if (direct_append) {
/*
* Take care to preserve the buffer's B_CACHE state so
* as not to cause an unnecessary read.
*/
bp = getblk(vp, lbn, on, PCATCH, 0, 0);
if (bp != NULL) {
long save;
err = fuse_vnode_setsize(vp, cred,
uio->uio_offset + n);
fvdat->flag |= FN_SIZECHANGE;
if (err) {
brelse(bp);
break;
}
save = bp->b_flags & B_CACHE;
bcount += n;
uint32_t save = bp->b_flags & B_CACHE;
allocbuf(bp, bcount);
bp->b_flags |= save;
}
} else {
/*
* Obtain the locked cache block first, and then
* adjust the file's size as appropriate.
*/
bcount = on + n;
if ((off_t)lbn * biosize + bcount < filesize) {
if ((off_t)(lbn + 1) * biosize < filesize)
bcount = biosize;
else
bcount = filesize - (off_t)lbn *biosize;
}
SDT_PROBE6(fusefs, , io, write_biobackend_start,
lbn, on, n, uio, bcount, false);
bp = getblk(vp, lbn, bcount, PCATCH, 0, 0);
if (bp && uio->uio_offset + n > filesize) {
err = fuse_vnode_setsize(vp, cred,
uio->uio_offset + n);
fvdat->flag |= FN_SIZECHANGE;
if (err) {
brelse(bp);
break;
}
}
}
if (!bp) {
err = EINTR;
break;
}
if (extending) {
/*
* Extend file _after_ locking buffer so we won't race
* with other readers
*/
err = fuse_vnode_setsize(vp, cred, uio->uio_offset + n);
fvdat->flag |= FN_SIZECHANGE;
if (err) {
brelse(bp);
break;
}
}
SDT_PROBE6(fusefs, , io, write_biobackend_start,
lbn, on, n, uio, bcount, direct_append);
/*
* Issue a READ if B_CACHE is not set. In special-append
* mode, B_CACHE is based on the buffer prior to the write