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
This commit is contained in:
Alan Somers 2019-05-13 23:30:06 +00:00
parent 5940f822ae
commit 96658124d7
2 changed files with 10 additions and 8 deletions

View File

@ -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;
}

View File

@ -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;