From 91083df90eadc0e69e4ce6956f823a2acb602f25 Mon Sep 17 00:00:00 2001 From: HereThereBeDragons Date: Thu, 27 Oct 2022 17:52:10 +0200 Subject: [PATCH] adding comments and capability discovery, enum for flags moved to top of file Signed-off-by: Pavel Reichl --- example/printcap.c | 2 ++ include/fuse_common.h | 16 ++++++++++++++++ include/fuse_lowlevel.h | 40 ++++++++++++++++++++++++++++++++++++---- lib/fuse_lowlevel.c | 2 ++ 4 files changed, 56 insertions(+), 4 deletions(-) diff --git a/example/printcap.c b/example/printcap.c index edfd8f5..4867988 100644 --- a/example/printcap.c +++ b/example/printcap.c @@ -81,6 +81,8 @@ static void pc_init(void *userdata, printf("\tFUSE_CAP_NO_OPENDIR_SUPPORT\n"); if(conn->capable & FUSE_CAP_EXPLICIT_INVAL_DATA) printf("\tFUSE_CAP_EXPLICIT_INVAL_DATA\n"); + if(conn->capable & FUSE_CAP_EXPIRE_ONLY) + printf("\tFUSE_CAP_EXPIRE_ONLY\n"); fuse_session_exit(se); } diff --git a/include/fuse_common.h b/include/fuse_common.h index e9d8745..dbba05a 100644 --- a/include/fuse_common.h +++ b/include/fuse_common.h @@ -408,6 +408,22 @@ struct fuse_loop_config_v1 { */ #define FUSE_CAP_EXPLICIT_INVAL_DATA (1 << 25) +/** + * Indicates support that dentries can be expired or invalidated. + * + * Expiring dentries, instead of invalidating them, makes a difference for + * overmounted dentries, where plain invalidation would detach all submounts + * before dropping the dentry from the cache. If only expiry is set on the + * dentry, then any overmounts are left alone and until ->d_revalidate() + * is called. + * + * Note: ->d_revalidate() is not called for the case of following a submount, + * so invalidation will only be triggered for the non-overmounted case. + * The dentry could also be mounted in a different mount instance, in which case + * any submounts will still be detached. +*/ +#define FUSE_CAP_EXPIRE_ONLY (1 << 26) + /** * Ioctl flags * diff --git a/include/fuse_lowlevel.h b/include/fuse_lowlevel.h index cceb9be..6bad70e 100644 --- a/include/fuse_lowlevel.h +++ b/include/fuse_lowlevel.h @@ -127,6 +127,15 @@ struct fuse_forget_data { uint64_t nlookup; }; +/** + * Flags for fuse_lowlevel_notify_expire_entry() + * 0 = invalidate entry + * FUSE_LL_EXPIRE_ONLY = expire entry +*/ +enum fuse_expire_flags { + FUSE_LL_EXPIRE_ONLY = (1 << 0), +}; + /* 'to_set' flags in setattr */ #define FUSE_SET_ATTR_MODE (1 << 0) #define FUSE_SET_ATTR_UID (1 << 1) @@ -1675,10 +1684,33 @@ int fuse_lowlevel_notify_inval_inode(struct fuse_session *se, fuse_ino_t ino, int fuse_lowlevel_notify_inval_entry(struct fuse_session *se, fuse_ino_t parent, const char *name, size_t namelen); -enum fuse_expire_flags { - FUSE_LL_EXPIRE_ONLY = (1 << 0), -}; - +/** + * Notify to expire or invalidate parent attributes and the dentry + * matching parent/name + * + * Underlying function for fuse_lowlevel_notify_inval_entry(). + * + * In addition to invalidating an entry, it also allows to expire an entry. + * In that case, the entry is not forcefully removed from kernel cache + * but instead the next access to it forces a lookup from the filesystem. + * + * This makes a difference for overmounted dentries, where plain invalidation + * would detach all submounts before dropping the dentry from the cache. + * If only expiry is set on the dentry, then any overmounts are left alone and + * until ->d_revalidate() is called. + * + * Note: ->d_revalidate() is not called for the case of following a submount, + * so invalidation will only be triggered for the non-overmounted case. + * The dentry could also be mounted in a different mount instance, in which case + * any submounts will still be detached. + * + * @param se the session object + * @param parent inode number + * @param name file name + * @param namelen strlen() of file name + * @param flags flags to control if the entry should be expired or invalidated + * @return zero for success, -errno for failure +*/ int fuse_lowlevel_notify_expire_entry(struct fuse_session *se, fuse_ino_t parent, const char *name, size_t namelen, enum fuse_expire_flags flags); diff --git a/lib/fuse_lowlevel.c b/lib/fuse_lowlevel.c index 7b9d710..7d76309 100644 --- a/lib/fuse_lowlevel.c +++ b/lib/fuse_lowlevel.c @@ -1991,6 +1991,8 @@ void do_init(fuse_req_t req, fuse_ino_t nodeid, const void *inarg) bufsize = max_bufsize; } } + if (arg->minor >= 38) + se->conn.capable |= FUSE_CAP_EXPIRE_ONLY; } else { se->conn.max_readahead = 0; } -- 2.41.0