From 96658124d7a806ad833be3de9ffd1fb121811145 Mon Sep 17 00:00:00 2001 From: Alan Somers Date: Mon, 13 May 2019 23:30:06 +0000 Subject: [PATCH] fusefs: eliminate superfluous FUSE_GETATTR when filesize=0 fuse_vnode_refreshsize was using 0 as a flag value for filesize meaning "uninitialized" (thanks to the malloc(...M_ZERO) in fuse_vnode_alloc. But this led to unnecessary getattr operations when the filesize legitimately happened to be zero. Fix by adding a distinct flag value. Sponsored by: The FreeBSD Foundation --- sys/fs/fuse/fuse_node.c | 10 +++------- sys/fs/fuse/fuse_node.h | 8 +++++++- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/sys/fs/fuse/fuse_node.c b/sys/fs/fuse/fuse_node.c index 2c6fe6f86ce6..83b93f2a255c 100644 --- a/sys/fs/fuse/fuse_node.c +++ b/sys/fs/fuse/fuse_node.c @@ -143,6 +143,7 @@ fuse_vnode_init(struct vnode *vp, struct fuse_vnode_data *fvdat, fvdat->nid = nodeid; LIST_INIT(&fvdat->handles); vattr_null(&fvdat->cached_attrs); + fvdat->filesize = FUSE_FILESIZE_UNINITIALIZED; if (nodeid == FUSE_ROOT_ID) { vp->v_vflag |= VV_ROOT; } @@ -388,15 +389,10 @@ fuse_vnode_refreshsize(struct vnode *vp, struct ucred *cred) if ((fvdat->flag & FN_SIZECHANGE) != 0 || fuse_data_cache_mode == FUSE_CACHE_UC || - fvdat->filesize != 0) + fvdat->filesize != FUSE_FILESIZE_UNINITIALIZED) return 0; - /* - * TODO: replace VOP_GETATTR with fuse_internal_getattr to use the - * cached attributes. Better yet, replace fvdat->filesize with - * attrs->va_size - */ - err = VOP_GETATTR(vp, &va, cred); + err = fuse_internal_getattr(vp, &va, cred, curthread); SDT_PROBE2(fusefs, , node, trace, 1, "refreshed file size"); return err; } diff --git a/sys/fs/fuse/fuse_node.h b/sys/fs/fuse/fuse_node.h index 315635d55db3..8e7500d24fe7 100644 --- a/sys/fs/fuse/fuse_node.h +++ b/sys/fs/fuse/fuse_node.h @@ -71,6 +71,8 @@ #define FN_SIZECHANGE 0x00000100 #define FN_DIRECTIO 0x00000200 +#define FUSE_FILESIZE_UNINITIALIZED -1 + struct fuse_vnode_data { /** self **/ uint64_t nid; @@ -89,7 +91,11 @@ struct fuse_vnode_data { /* The monotonic time after which the attr cache is invalid */ struct bintime attr_cache_timeout; struct vattr cached_attrs; - /* TODO: use cached_attrs.size instead */ + /* + * File size according to the kernel, not the daemon. + * May differ from cached_attrs.st_size due to write caching. Unlike + * cached_attrs.st_size, filesize never expires. + */ off_t filesize; uint64_t nlookup; enum vtype vtype;