aboutsummaryrefslogtreecommitdiffstats
path: root/example/notify_inval_entry.c
diff options
context:
space:
mode:
Diffstat (limited to 'example/notify_inval_entry.c')
-rw-r--r--example/notify_inval_entry.c41
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);