129 lines
4.6 KiB
Diff
129 lines
4.6 KiB
Diff
|
From 91083df90eadc0e69e4ce6956f823a2acb602f25 Mon Sep 17 00:00:00 2001
|
||
|
From: HereThereBeDragons <HereThereBeDragons@users.noreply.github.com>
|
||
|
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 <preichl@redhat.com>
|
||
|
---
|
||
|
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
|
||
|
|