diff options
author | SÅ‚awek Rudnicki <slawek.rudnicki@editshare.com> | 2017-08-07 12:41:33 +0200 |
---|---|---|
committer | Nikolaus Rath <Nikolaus@rath.org> | 2017-08-24 14:20:37 +0200 |
commit | 89f2bae00c1b87580f432f9a719ba8998493e6df (patch) | |
tree | 896d41f64caeef13a4c35f5a6333348067f5dfae /lib | |
parent | 4eed36910fa73cfe3fe62530850d427e6841e14f (diff) | |
download | libfuse-89f2bae00c1b87580f432f9a719ba8998493e6df.tar.gz |
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.c | 40 | ||||
-rw-r--r-- | lib/fuse_versionscript | 1 |
2 files changed, 41 insertions, 0 deletions
@@ -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: |