From 194e691aaf96c98d44ff04ea634fc4acf9d86a19 Mon Sep 17 00:00:00 2001 From: Conrad Meyer Date: Fri, 15 Feb 2019 22:51:09 +0000 Subject: [PATCH] FUSE: Only "dirty" cached file size when data is dirty Most users of fuse_vnode_setsize() set the cached fvdat->filesize and update the buf cache bounds as a result of either a read from the underlying FUSE filesystem, or as part of a write-through type operation (like truncate => VOP_SETATTR). In these cases, do not set the FN_SIZECHANGE flag, which indicates that an inode's data is dirty (in particular, that the local buf cache and fvdat->filesize have dirty extended data). PR: 230258 (related) --- sys/fs/fuse/fuse_io.c | 5 ++++- sys/fs/fuse/fuse_node.c | 1 + sys/fs/fuse/fuse_vnops.c | 5 +++-- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/sys/fs/fuse/fuse_io.c b/sys/fs/fuse/fuse_io.c index 8fa7dc06f79d..25f63a9511fc 100644 --- a/sys/fs/fuse/fuse_io.c +++ b/sys/fs/fuse/fuse_io.c @@ -362,8 +362,11 @@ fuse_write_directbackend(struct vnode *vp, struct uio *uio, } uio->uio_resid += diff; uio->uio_offset -= diff; - if (uio->uio_offset > fvdat->filesize) + if (uio->uio_offset > fvdat->filesize && + fuse_data_cache_enable) { fuse_vnode_setsize(vp, cred, uio->uio_offset); + fvdat->flag &= ~FN_SIZECHANGE; + } } fdisp_destroy(&fdi); diff --git a/sys/fs/fuse/fuse_node.c b/sys/fs/fuse/fuse_node.c index e8b16335272d..dee7f328b5ac 100644 --- a/sys/fs/fuse/fuse_node.c +++ b/sys/fs/fuse/fuse_node.c @@ -375,6 +375,7 @@ fuse_vnode_refreshsize(struct vnode *vp, struct ucred *cred) struct vattr va; if ((fvdat->flag & FN_SIZECHANGE) != 0 || + fuse_data_cache_enable == 0 || (fuse_refresh_size == 0 && fvdat->filesize != 0)) return; diff --git a/sys/fs/fuse/fuse_vnops.c b/sys/fs/fuse/fuse_vnops.c index 618b01944712..6ab93bb16f36 100644 --- a/sys/fs/fuse/fuse_vnops.c +++ b/sys/fs/fuse/fuse_vnops.c @@ -538,6 +538,7 @@ fuse_vnop_getattr(struct vop_getattr_args *ap) if (fvdat->filesize != new_filesize) { fuse_vnode_setsize(vp, cred, new_filesize); + fvdat->flag &= ~FN_SIZECHANGE; } } debug_printf("fuse_getattr e: returning 0\n"); @@ -1637,9 +1638,9 @@ fuse_vnop_setattr(struct vop_setattr_args *ap) err = EAGAIN; } } - if (!err && !sizechanged) { + if (err == 0) cache_attrs(vp, (struct fuse_attr_out *)fdi.answ, NULL); - } + out: fdisp_destroy(&fdi); if (!err && sizechanged) {