summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHereThereBeDragons <HereThereBeDragons@users.noreply.github.com>2022-10-27 17:52:10 +0200
committerNikolaus Rath <Nikolaus@rath.org>2023-01-06 18:35:52 +0000
commit91083df90eadc0e69e4ce6956f823a2acb602f25 (patch)
treeb83b5c7122fec12a0f4424fd5c1fdb1a39b0caf8
parent7f430a39db5a30979d75a906af891a38ebce1a3c (diff)
downloadfuse-91083df90eadc0e69e4ce6956f823a2acb602f25.tar.gz
adding comments and capability discovery, enum for flags moved to top of file
-rw-r--r--example/printcap.c2
-rw-r--r--include/fuse_common.h16
-rw-r--r--include/fuse_lowlevel.h40
-rw-r--r--lib/fuse_lowlevel.c2
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
@@ -409,6 +409,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
*
* FUSE_IOCTL_COMPAT: 32bit compat ioctl on 64bit machine
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;
}