From 5a44747054926c2683a28392869c4f8603f5e70a Mon Sep 17 00:00:00 2001 From: John Muir Date: Tue, 6 Dec 2011 21:56:34 +0100 Subject: [PATCH] libfuse: Notifying the kernel of deletion. libfuse part to allow a FUSE file-system to tell the kernel when a file or directory is deleted. If the specified dentry has the specified inode number, the kernel will unhash it. Signed-off-by: John Muir Signed-off-by: Miklos Szeredi --- ChangeLog | 5 +++++ include/fuse_kernel.h | 9 +++++++++ include/fuse_lowlevel.h | 16 ++++++++++++++++ lib/fuse_lowlevel.c | 28 ++++++++++++++++++++++++++++ lib/fuse_versionscript | 1 + 5 files changed, 59 insertions(+) diff --git a/ChangeLog b/ChangeLog index 636dddc..3f6133d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-12-07 Miklos Szeredi + + * Add fuse_lowlevel_notify_delete() which tells the kernel that a + file or directory is deleted. Patch by John Muir + 2011-12-06 Miklos Szeredi * Add mmap() and munmap() methods to low level API. Currently diff --git a/include/fuse_kernel.h b/include/fuse_kernel.h index 039eb1f..89e941a 100644 --- a/include/fuse_kernel.h +++ b/include/fuse_kernel.h @@ -79,6 +79,7 @@ * * 7.18 * - add FUSE_IOCTL_DIR flag + * - add FUSE_NOTIFY_DELETE * - add FUSE_MMAP and FUSE_MUNMAP */ @@ -322,6 +323,7 @@ enum fuse_notify_code { FUSE_NOTIFY_INVAL_ENTRY = 3, FUSE_NOTIFY_STORE = 4, FUSE_NOTIFY_RETRIEVE = 5, + FUSE_NOTIFY_DELETE = 6, FUSE_NOTIFY_CODE_MAX, }; @@ -667,6 +669,13 @@ struct fuse_notify_inval_entry_out { __u32 padding; }; +struct fuse_notify_delete_out { + __u64 parent; + __u64 child; + __u32 namelen; + __u32 padding; +}; + struct fuse_notify_store_out { __u64 nodeid; __u64 offset; diff --git a/include/fuse_lowlevel.h b/include/fuse_lowlevel.h index 6435937..8ed555e 100644 --- a/include/fuse_lowlevel.h +++ b/include/fuse_lowlevel.h @@ -1322,6 +1322,22 @@ int fuse_lowlevel_notify_inval_inode(struct fuse_chan *ch, fuse_ino_t ino, int fuse_lowlevel_notify_inval_entry(struct fuse_chan *ch, fuse_ino_t parent, const char *name, size_t namelen); +/** + * Notify to invalidate parent attributes and delete the dentry matching + * parent/name if the dentry's inode number matches child (otherwise it + * will invalidate the matching dentry). + * + * @param ch the channel through which to send the notification + * @param parent inode number + * @param child inode number + * @param name file name + * @param namelen strlen() of file name + * @return zero for success, -errno for failure + */ +int fuse_lowlevel_notify_delete(struct fuse_chan *ch, + fuse_ino_t parent, fuse_ino_t child, + const char *name, size_t namelen); + /** * Store data to the kernel buffers * diff --git a/lib/fuse_lowlevel.c b/lib/fuse_lowlevel.c index f69b2b1..3bfc993 100644 --- a/lib/fuse_lowlevel.c +++ b/lib/fuse_lowlevel.c @@ -2054,6 +2054,34 @@ int fuse_lowlevel_notify_inval_entry(struct fuse_chan *ch, fuse_ino_t parent, return send_notify_iov(f, ch, FUSE_NOTIFY_INVAL_ENTRY, iov, 3); } +int fuse_lowlevel_notify_delete(struct fuse_chan *ch, + fuse_ino_t parent, fuse_ino_t child, + const char *name, size_t namelen) +{ + struct fuse_notify_delete_out outarg; + struct fuse_ll *f; + struct iovec iov[3]; + + if (!ch) + return -EINVAL; + + f = (struct fuse_ll *)fuse_session_data(fuse_chan_session(ch)); + if (!f) + return -ENODEV; + + outarg.parent = parent; + outarg.child = child; + outarg.namelen = namelen; + outarg.padding = 0; + + iov[1].iov_base = &outarg; + iov[1].iov_len = sizeof(outarg); + iov[2].iov_base = (void *)name; + iov[2].iov_len = namelen + 1; + + return send_notify_iov(f, ch, FUSE_NOTIFY_DELETE, iov, 3); +} + int fuse_lowlevel_notify_store(struct fuse_chan *ch, fuse_ino_t ino, off_t offset, struct fuse_bufvec *bufv, enum fuse_buf_copy_flags flags) diff --git a/lib/fuse_versionscript b/lib/fuse_versionscript index 1ee1c9d..95bc7d9 100644 --- a/lib/fuse_versionscript +++ b/lib/fuse_versionscript @@ -195,6 +195,7 @@ FUSE_2.9 { fuse_stop_cleanup_thread; fuse_clean_cache; fuse_reply_mmap; + fuse_lowlevel_notify_delete; local: *; -- 2.30.2