From 89f2bae00c1b87580f432f9a719ba8998493e6df Mon Sep 17 00:00:00 2001 From: SÅ‚awek Rudnicki Date: Mon, 7 Aug 2017 12:41:33 +0200 Subject: 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. --- lib/fuse.c | 40 ++++++++++++++++++++++++++++++++++++++++ lib/fuse_versionscript | 1 + 2 files changed, 41 insertions(+) (limited to 'lib') 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: -- cgit v1.2.3