diff options
Diffstat (limited to 'example')
-rw-r--r-- | example/notify_inval_entry.c | 41 |
1 files changed, 33 insertions, 8 deletions
diff --git a/example/notify_inval_entry.c b/example/notify_inval_entry.c index 8af31bc..ea3d43f 100644 --- a/example/notify_inval_entry.c +++ b/example/notify_inval_entry.c @@ -85,6 +85,7 @@ #include <errno.h> #include <fcntl.h> #include <assert.h> +#include <signal.h> #include <stddef.h> #include <unistd.h> #include <pthread.h> @@ -93,6 +94,7 @@ static char file_name[MAX_STR_LEN]; static fuse_ino_t file_ino = 2; static int lookup_cnt = 0; +static pthread_t main_thread; /* Command line parsing */ struct options { @@ -253,14 +255,32 @@ static void* update_fs_loop(void *data) { struct fuse_session *se = (struct fuse_session*) data; char *old_name; - while(1) { + + while(!fuse_session_exited(se)) { old_name = strdup(file_name); update_fs(); + if (!options.no_notify && lookup_cnt) { - if(options.only_expire) { - assert(fuse_lowlevel_notify_expire_entry - (se, FUSE_ROOT_ID, old_name, strlen(old_name), FUSE_LL_EXPIRE_ONLY) == 0); - } else { + if(options.only_expire) { // expire entry + int 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 { // invalidate entry assert(fuse_lowlevel_notify_inval_entry (se, FUSE_ROOT_ID, old_name, strlen(old_name)) == 0); } @@ -312,7 +332,7 @@ int main(int argc, char *argv[]) { update_fs(); se = fuse_session_new(&args, &tfs_oper, - sizeof(tfs_oper), NULL); + sizeof(tfs_oper), &se); if (se == NULL) goto err_out1; @@ -324,6 +344,11 @@ int main(int argc, char *argv[]) { fuse_daemonize(opts.foreground); + // Needed to ensure that the main thread continues/restarts processing as soon + // as the fuse session ends (immediately after calling fuse_session_exit() ) + // and not only on the next request from userspace + main_thread = pthread_self(); + /* Start thread to update file contents */ ret = pthread_create(&updater, NULL, update_fs_loop, (void *)se); if (ret != 0) { @@ -333,9 +358,9 @@ int main(int argc, char *argv[]) { } /* Block until ctrl+c or fusermount -u */ - if (opts.singlethread) + if (opts.singlethread) { ret = fuse_session_loop(se); - else { + } else { config.clone_fd = opts.clone_fd; config.max_idle_threads = opts.max_idle_threads; ret = fuse_session_loop_mt(se, &config); |