aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorGravatar SÅ‚awek Rudnicki <slawek.rudnicki@editshare.com>2017-08-07 12:41:33 +0200
committerGravatar Nikolaus Rath <Nikolaus@rath.org>2017-08-24 14:20:37 +0200
commit89f2bae00c1b87580f432f9a719ba8998493e6df (patch)
tree896d41f64caeef13a4c35f5a6333348067f5dfae /lib
parent4eed36910fa73cfe3fe62530850d427e6841e14f (diff)
Allow inode cache invalidation in high-level API
We re-introduce the functionality of invalidating the caches for an inode specified by path by adding a new routine fuse_invalidate_path. This is useful for network-based file systems which use the high-level API, enabling them to notify the kernel about external changes. This is a revival of Miklos Szeredi's original code for the fuse_invalidate routine.
Diffstat (limited to 'lib')
-rw-r--r--lib/fuse.c40
-rw-r--r--lib/fuse_versionscript1
2 files changed, 41 insertions, 0 deletions
diff --git a/lib/fuse.c b/lib/fuse.c
index a5df0b8..0f2a6d6 100644
--- a/lib/fuse.c
+++ b/lib/fuse.c
@@ -893,6 +893,36 @@ out_err:
return node;
}
+static int lookup_path_in_cache(struct fuse *f,
+ const char *path, fuse_ino_t *inop)
+{
+ char *tmp = strdup(path);
+ if (!tmp)
+ return -ENOMEM;
+
+ pthread_mutex_lock(&f->lock);
+ fuse_ino_t ino = FUSE_ROOT_ID;
+
+ int err = 0;
+ char *save_ptr;
+ char *path_element = strtok_r(tmp, "/", &save_ptr);
+ while (path_element != NULL) {
+ struct node *node = lookup_node(f, ino, path_element);
+ if (node == NULL) {
+ err = -ENOENT;
+ break;
+ }
+ ino = node->nodeid;
+ path_element = strtok_r(NULL, "/", &save_ptr);
+ }
+ pthread_mutex_unlock(&f->lock);
+ free(tmp);
+
+ if (!err)
+ *inop = ino;
+ return err;
+}
+
static char *add_name(char **buf, unsigned *bufsize, char *s, const char *name)
{
size_t len = strlen(name);
@@ -4400,6 +4430,16 @@ int fuse_interrupted(void)
return 0;
}
+int fuse_invalidate_path(struct fuse *f, const char *path) {
+ fuse_ino_t ino;
+ int err = lookup_path_in_cache(f, path, &ino);
+ if (err) {
+ return err;
+ }
+
+ return fuse_lowlevel_notify_inval_inode(f->se, ino, 0, 0);
+}
+
#define FUSE_LIB_OPT(t, p, v) { t, offsetof(struct fuse_config, p), v }
static const struct fuse_opt fuse_lib_opts[] = {
diff --git a/lib/fuse_versionscript b/lib/fuse_versionscript
index 5fa3264..e1eba6b 100644
--- a/lib/fuse_versionscript
+++ b/lib/fuse_versionscript
@@ -136,6 +136,7 @@ FUSE_3.1 {
global:
fuse_lib_help;
fuse_new_30;
+ fuse_invalidate_path;
} FUSE_3.0;
# Local Variables: