fuse/0007-BZ_2171095-cap.patch
Pavel Reichl e828426ddf Add feature: notify_inode_expire_only
Resolves: rhbz#2171095
Signed-off-by: Pavel Reichl <preichl@redhat.com>
2023-04-06 15:56:39 +02:00

126 lines
4.5 KiB
Diff

From 6b1612e3a85b993f82124cccf149df3830e4a9c5 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
---
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 edfd8f531..48679883c 100644
--- a/example/printcap.c
+++ b/example/printcap.c
@@ -79,6 +79,8 @@
printf("\tFUSE_CAP_POSIX_ACL\n");
if(conn->capable & FUSE_CAP_CACHE_SYMLINKS)
printf("\tFUSE_CAP_CACHE_SYMLINKS\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 e9d874556..dbba05af8 100644
--- a/include/fuse_common.h
+++ b/include/fuse_common.h
@@ -338,6 +338,22 @@
#define FUSE_CAP_CACHE_SYMLINKS (1 << 23)
/**
+ * 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 c955cc4bb..6a1a5d534 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 7b9d71043..7d7630925 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;
}