From: David B. <and...@gm...> - 2013-04-24 00:50:35
|
Ping? On Wed, Apr 3, 2013 at 4:33 PM, David Bartley <and...@gm...> wrote: > --- > include/fuse.h | 14 ++++++++++++++ > include/fuse_common.h | 8 +++++++- > lib/fuse.c | 43 +++++++++++++++++++++++++++++++++++++++++++ > 3 files changed, 64 insertions(+), 1 deletion(-) > > diff --git a/include/fuse.h b/include/fuse.h > index 793862e..6efabc8 100644 > --- a/include/fuse.h > +++ b/include/fuse.h > @@ -833,6 +833,20 @@ void fuse_fs_destroy(struct fuse_fs *fs); > int fuse_notify_poll(struct fuse_pollhandle *ph); > > /** > + * Notifies the kernel that a path's attributes have changed in the > background. > + * > + * @param notify_data the data passed in fuse_conn_info->notify_data in > init > + * @param path the path to invalidate > + * @param off offset of the file cache mapping to invalidate, or -1 to > only > + * invalidate attributes > + * @param len size of file cache mapping to invalidate, or -1 to > invalidate file > + * pages from off up to the end of the file > + * @return 0 on success, negative error number on failure > + */ > +int fuse_notify_inval_inode(uint64_t notify_data, const char *path, > + off_t off, off_t len); > + > +/** > * Create a new fuse filesystem object > * > * This is usually called from the factory of a fuse module to create > diff --git a/include/fuse_common.h b/include/fuse_common.h > index af16203..6d854ca 100644 > --- a/include/fuse_common.h > +++ b/include/fuse_common.h > @@ -186,9 +186,15 @@ struct fuse_conn_info { > unsigned congestion_threshold; > > /** > + * Argument that can be passed to fuse_notify_inval. > + * This value is valid until the destroy callback returns. > + */ > + uint64_t notify_data; > + > + /** > * For future use. > */ > - unsigned reserved[23]; > + unsigned reserved[21]; > }; > > struct fuse_session; > diff --git a/lib/fuse.c b/lib/fuse.c > index e2d48d3..694c5a0 100644 > --- a/lib/fuse.c > +++ b/lib/fuse.c > @@ -2442,6 +2442,7 @@ static void fuse_lib_init(void *data, struct > fuse_conn_info *conn) > > fuse_create_context(f); > conn->want |= FUSE_CAP_EXPORT_SUPPORT; > + conn->notify_data = (uint64_t) f; > fuse_fs_init(f->fs, conn); > } > > @@ -4010,6 +4011,48 @@ int fuse_notify_poll(struct fuse_pollhandle *ph) > return fuse_lowlevel_notify_poll(ph); > } > > +static int find_node_path(struct fuse *f, const char *path, fuse_ino_t > *nodeid) > +{ > + char *path_copy, *name, *tok; > + int res = -ENOENT; > + fuse_ino_t id = FUSE_ROOT_ID; > + > + path_copy = strdup(path); > + if (path_copy == NULL) > + return -ENOMEM; > + > + pthread_mutex_lock(&f->lock); > + name = strtok_r(path_copy, "/", &tok); > + do { > + struct node *node = lookup_node(f, id, name); > + if (node == NULL) > + goto out; > + id = node->nodeid; > + } while ((name = strtok_r(NULL, "/", &tok))); > + *nodeid = id; > + res = 0; > + > +out: > + pthread_mutex_unlock(&f->lock); > + free(path_copy); > + return res; > +} > + > +int fuse_notify_inval_inode(uint64_t notify_data, const char *path, > + off_t off, off_t len) > +{ > + struct fuse *f = (struct fuse *) notify_data; > + fuse_ino_t node; > + int res; > + > + res = find_node_path(f, path, &node); > + if (!res) { > + struct fuse_chan *chan = fuse_session_next_chan(f->se, > NULL); > + res = fuse_lowlevel_notify_inval_inode(chan, node, off, > len); > + } > + return res; > +} > + > struct fuse_session *fuse_get_session(struct fuse *f) > { > return f->se; > -- > 1.8.1.2 > > |