aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--example/notify_inval_inode.c32
1 files changed, 27 insertions, 5 deletions
diff --git a/example/notify_inval_inode.c b/example/notify_inval_inode.c
index b3b50aa..b1fb8f7 100644
--- a/example/notify_inval_inode.c
+++ b/example/notify_inval_inode.c
@@ -71,6 +71,8 @@
#include <stddef.h>
#include <unistd.h>
#include <pthread.h>
+#include <stdbool.h>
+#include <stdatomic.h>
/* We can't actually tell the kernel that there is no
timeout, so we just send a big value */
@@ -82,6 +84,7 @@
static char file_contents[MAX_STR_LEN];
static int lookup_cnt = 0;
static size_t file_size;
+static _Atomic bool is_stop = false;
/* Command line parsing */
struct options {
@@ -120,6 +123,13 @@ static int tfs_stat(fuse_ino_t ino, struct stat *stbuf) {
return 0;
}
+static void tfs_destroy(void *userarg)
+{
+ (void)userarg;
+
+ is_stop = true;
+}
+
static void tfs_lookup(fuse_req_t req, fuse_ino_t parent,
const char *name) {
struct fuse_entry_param e;
@@ -240,6 +250,7 @@ static void tfs_read(fuse_req_t req, fuse_ino_t ino, size_t size,
}
static const struct fuse_lowlevel_ops tfs_oper = {
+ .destroy = tfs_destroy,
.lookup = tfs_lookup,
.getattr = tfs_getattr,
.readdir = tfs_readdir,
@@ -263,13 +274,24 @@ static void update_fs(void) {
static void* update_fs_loop(void *data) {
struct fuse_session *se = (struct fuse_session*) data;
- while(1) {
+ while(!is_stop) {
update_fs();
if (!options.no_notify && lookup_cnt) {
- /* Only send notification if the kernel
- is aware of the inode */
- assert(fuse_lowlevel_notify_inval_inode
- (se, FILE_INO, 0, 0) == 0);
+ /* Only send notification if the kernel is aware of the inode */
+
+ /* Some errors (ENOENT, EBADFD, ENODEV) have to be accepted as the
+ * might come up during umount, when kernel side already releases
+ * all inodes, but does not send FUSE_DESTROY yet.
+ */
+ int ret =
+ fuse_lowlevel_notify_inval_inode(se, FILE_INO, 0, 0);
+ if ((ret != 0 && !is_stop) &&
+ ret != -ENOENT && ret != -EBADFD && ret != -ENODEV) {
+ fprintf(stderr,
+ "ERROR: fuse_lowlevel_notify_store() failed with %s (%d)\n",
+ strerror(-ret), -ret);
+ abort();
+ }
}
sleep(options.update_interval);
}