aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLuis Henriques <luis@igalia.com>2025-06-18 10:42:32 +0100
committerBernd Schubert <bernd@bsbernd.com>2025-06-18 13:47:11 +0200
commit1caf8162d5b08bd32cc311c001c277067bd572c0 (patch)
treee327cc384cbca22f85ca8c5415ac6298813e6892
parent5ceb0b05cb48e6cfa2c81160df9f1212623e86eb (diff)
downloadlibfuse-1caf8162d5b08bd32cc311c001c277067bd572c0.tar.gz
tests: example: add new test for increment epoch
This patch modifies the notify_inval_entry.c example so that it includes an extra option to use fuse_lowlevel_notify_increment_epoch(). The test test_notify_inval_entry() was also modified to test this extra option. Signed-off-by: Luis Henriques <luis@igalia.com>
-rw-r--r--example/notify_inval_entry.c47
-rwxr-xr-xtest/test_examples.py7
2 files changed, 43 insertions, 11 deletions
diff --git a/example/notify_inval_entry.c b/example/notify_inval_entry.c
index 1060d50..728a9dc 100644
--- a/example/notify_inval_entry.c
+++ b/example/notify_inval_entry.c
@@ -67,6 +67,12 @@
* To use the function fuse_lowlevel_notify_expire_entry() instead of
* fuse_lowlevel_notify_inval_entry(), use the command line option --only-expire
*
+ * Another possible command-line option is --inc-epoch, which will use the FUSE
+ * low-level function fuse_lowlevel_notify_increment_epoch() instead. This will
+ * function will force the invalidation of all dentries next time they are
+ * revalidated. Note that --inc-epoch and --only-expire options are mutually
+ * exclusive.
+ *
* ## Compilation ##
*
* gcc -Wall notify_inval_entry.c `pkg-config fuse3 --cflags --libs` -o notify_inval_entry
@@ -103,12 +109,14 @@ struct options {
float timeout;
int update_interval;
int only_expire;
+ int inc_epoch;
};
static struct options options = {
.timeout = 5,
.no_notify = 0,
.update_interval = 1,
.only_expire = 0,
+ .inc_epoch = 0,
};
#define OPTION(t, p) \
@@ -118,6 +126,7 @@ static const struct fuse_opt option_spec[] = {
OPTION("--update-interval=%d", update_interval),
OPTION("--timeout=%f", timeout),
OPTION("--only-expire", only_expire),
+ OPTION("--inc-epoch", inc_epoch),
FUSE_OPT_END
};
@@ -263,7 +272,7 @@ static void update_fs(void) {
static void* update_fs_loop(void *data) {
struct fuse_session *se = (struct fuse_session*) data;
char *old_name;
-
+ int ret = 0;
while(!fuse_session_exited(se)) {
old_name = strdup(file_name);
@@ -271,24 +280,27 @@ static void* update_fs_loop(void *data) {
if (!options.no_notify && lookup_cnt) {
if(options.only_expire) { // expire entry
- int ret = fuse_lowlevel_notify_expire_entry
- (se, FUSE_ROOT_ID, old_name, strlen(old_name));
+ ret = fuse_lowlevel_notify_expire_entry
+ (se, FUSE_ROOT_ID, old_name, strlen(old_name));
// no kernel support
if (ret == -ENOSYS) {
printf("fuse_lowlevel_notify_expire_entry not supported by kernel\n");
- printf("Exiting...\n");
-
- fuse_session_exit(se);
- // Make sure to exit now, rather than on next request from userspace
- pthread_kill(main_thread, SIGPIPE);
-
break;
}
+
// 1) ret == 0: successful expire of an existing entry
// 2) ret == -ENOENT: kernel has already expired the entry /
// entry does not exist anymore in the kernel
assert(ret == 0 || ret == -ENOENT);
+ } else if (options.inc_epoch) { // increment epoch
+ ret = fuse_lowlevel_notify_increment_epoch(se);
+
+ if (ret == -ENOSYS) {
+ printf("fuse_lowlevel_notify_increment_epoch not supported by kernel\n");
+ break;
+ }
+ assert(ret == 0);
} else { // invalidate entry
assert(fuse_lowlevel_notify_inval_entry
(se, FUSE_ROOT_ID, old_name, strlen(old_name)) == 0);
@@ -297,6 +309,15 @@ static void* update_fs_loop(void *data) {
free(old_name);
sleep(options.update_interval);
}
+
+ if (ret == -ENOSYS) {
+ printf("Exiting...\n");
+
+ fuse_session_exit(se);
+ // Make sure to exit now, rather than on next request from userspace
+ pthread_kill(main_thread, SIGPIPE);
+ }
+
return NULL;
}
@@ -307,7 +328,8 @@ static void show_help(const char *progname)
" --timeout=<secs> Timeout for kernel caches\n"
" --update-interval=<secs> Update-rate of file system contents\n"
" --no-notify Disable kernel notifications\n"
- " --only-expire Expire entries instead of invalidating them\n"
+ " --only-expire Expire entries instead of invalidating them\n"
+ " --inc-epoch Increment epoch, invalidating all dentries\n"
"\n");
}
@@ -336,6 +358,11 @@ int main(int argc, char *argv[]) {
ret = 0;
goto err_out1;
}
+ if (options.only_expire && options.inc_epoch) {
+ printf("'only-expire' and 'inc-epoch' options are exclusive\n");
+ ret = 0;
+ goto err_out1;
+ }
/* Initial contents */
update_fs();
diff --git a/test/test_examples.py b/test/test_examples.py
index 2e23697..2658081 100755
--- a/test/test_examples.py
+++ b/test/test_examples.py
@@ -376,7 +376,8 @@ def test_null(tmpdir, output_checker):
@pytest.mark.skipif(fuse_proto < (7,12),
reason='not supported by running kernel')
-@pytest.mark.parametrize("only_expire", ("invalidate_entries", "expire_entries"))
+@pytest.mark.parametrize("only_expire", ("invalidate_entries",
+ "expire_entries", "inc_epoch"))
@pytest.mark.parametrize("notify", (True, False))
def test_notify_inval_entry(tmpdir, only_expire, notify, output_checker):
mnt_dir = str(tmpdir)
@@ -390,6 +391,10 @@ def test_notify_inval_entry(tmpdir, only_expire, notify, output_checker):
cmdline.append('--only-expire')
if "FUSE_CAP_EXPIRE_ONLY" not in fuse_caps:
pytest.skip('only-expire not supported by running kernel')
+ elif only_expire == "inc_epoch":
+ cmdline.append('--inc-epoch')
+ if fuse_proto < (7,44):
+ pytest.skip('inc-epoch not supported by running kernel')
mount_process = subprocess.Popen(cmdline, stdout=output_checker.fd,
stderr=output_checker.fd)
try: