linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Stef Bon <stef@bononline.nl>
To: linux-fsdevel@vger.kernel.org
Cc: rlove@rlove.org, eparis@parisplace.org
Subject: [PATCH] VFS/inotify: send netlink messages when an inotify watch has been set or removed.
Date: Sat, 07 Jan 2012 14:36:12 +0100	[thread overview]
Message-ID: <4F084A4C.6080207@bononline.nl> (raw)

from: Stef Bon

I would like to apply a patch to the kernel to enable the sending of a
netlink message when setting or removing an inotify watch. My goal is
to make FUSE filesystems notify aware.

Since inotify works in the kernel space, and FUSE filesystems are in
userspace, FUSE fs's do not "know" when a watch has been set or
removed.

I think it's a good thing the fs "knows" about a watch, since it can
then set a backend specific notify watch on the backend, and report
anything back to the kernel when something changes.

The new netlink.c file is almost a copy of the netlink.c file in
fs/quota.

I've got a testprogram which receives messages in the group
GENERIC/VFS_INOTIFY.
If you want to test please email me. It just gives the information a
watch has been set (by who, and where, which mask) and when removed
(pid/fd/wd).

Signed-off-by: Stef Bon <stef@bononline.nl>

---

diff --git a/fs/notify/inotify/Kconfig b/fs/notify/inotify/Kconfig
index b981fc0..07f9bfc 100644
--- a/fs/notify/inotify/Kconfig
+++ b/fs/notify/inotify/Kconfig
@@ -15,3 +15,11 @@ config INOTIFY_USER
          For more information, see
<file:Documentation/filesystems/inotify.txt>
 
          If unsure, say Y.
+
+config INOTIFY_USER_NETLINK_INTERFACE
+       bool "Report inotify add/remove watch messages through netlink
interface"
+       depends on INOTIFY_USER && NET
+       ---help---
+         If you say Y here, inotify messages (about a watch being set
or removed
+         , not the events!) will be reported through netlink interface.
If unsure,
+         say Y.
diff --git a/fs/notify/inotify/Makefile b/fs/notify/inotify/Makefile
index a380dab..f977eaa 100644
--- a/fs/notify/inotify/Makefile
+++ b/fs/notify/inotify/Makefile
@@ -1 +1,2 @@
 obj-$(CONFIG_INOTIFY_USER)     += inotify_fsnotify.o inotify_user.o
+obj-$(CONFIG_INOTIFY_USER_NETLINK_INTERFACE)   += netlink.o
\ No newline at end of file
diff --git a/fs/notify/inotify/inotify_user.c
b/fs/notify/inotify/inotify_user.c
index 8445fbc..3f056b9 100644
--- a/fs/notify/inotify/inotify_user.c
+++ b/fs/notify/inotify/inotify_user.c
@@ -786,6 +786,9 @@ SYSCALL_DEFINE3(inotify_add_watch, int, fd, const
char __user *, pathname,
 
        /* create/update an inode mark */
        ret = inotify_update_watch(group, inode,
mask);                                                                
+                                                                                                                      

+       if ( ret>=0 ) inotify_send_add_message(fd, ret, mask,
pathname);                                               
+                                                                                                                      

       
path_put(&path);                                                                                               

 fput_and_out:                                                                                                         

        fput_light(filp, fput_needed);
@@ -822,6 +825,8 @@ SYSCALL_DEFINE2(inotify_rm_watch, int, fd, __s32, wd)
        /* match ref taken by inotify_idr_find */
        fsnotify_put_mark(&i_mark->fsn_mark);
 
+       inotify_send_remove_message(fd, wd);
+
 out:
        fput_light(filp, fput_needed);
        return ret;
diff --git a/fs/notify/inotify/netlink.c b/fs/notify/inotify/netlink.c
new file mode 100644
index 0000000..b965c7f
--- /dev/null
+++ b/fs/notify/inotify/netlink.c
@@ -0,0 +1,151 @@
+
+#include <linux/cred.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/inotify.h>
+#include <net/netlink.h>
+#include <net/genetlink.h>
+
+
+/* Netlink family structure for inotify */
+static struct genl_family inotify_genl_family = {
+       .id = GENL_ID_GENERATE,
+       .hdrsize = 0,
+       .name = "VFS_INOTIFY",
+       .version = 1,
+       .maxattr = INOTIFY_NL_A_MAX,
+};
+
+/**
+ * inotify_send_add_message
+ * @fd: inotify fd
+ * @wd: watch descriptor
+ * @mask: the mask
+ * @path: path
+ *
+ */
+
+void inotify_send_add_message(u32 fd, u32 wd, u32 mask, const char *path)
+{
+       static atomic_t seq;
+       struct sk_buff *skb;
+       void *msg_head;
+       int ret;
+       int msg_size = 4 * nla_total_size(sizeof(u32)) +
nla_total_size(strlen(path)) + 1;
+
+       skb = genlmsg_new(msg_size, GFP_KERNEL);
+
+       if (!skb) {
+
+               printk(KERN_ERR "VFS: Not enough memory to compose
inotify add wd netlink message.\n");
+               return;
+
+       }
+
+       msg_head = genlmsg_put(skb, 0, atomic_add_return(1, &seq),
+                       &inotify_genl_family, 0, INOTIFY_NL_C_ADD_MESSAGE);
+
+       if (!msg_head) {
+
+               printk(KERN_ERR "VFS: Cannot store netlink header in
inotify add wd netlink message.\n");
+               goto err_out;
+
+       }
+
+       ret = nla_put_u32(skb, INOTIFY_NL_A_PID, current->pid);
+       if (ret) goto attr_err_out;
+
+       ret = nla_put_u32(skb, INOTIFY_NL_A_FD, fd);
+       if (ret) goto attr_err_out;
+
+       ret = nla_put_u32(skb, INOTIFY_NL_A_WD, wd);
+       if (ret) goto attr_err_out;
+
+
+       ret = nla_put_u32(skb, INOTIFY_NL_A_MASK, mask);
+       if (ret) goto attr_err_out;
+
+       ret = nla_put_string(skb, INOTIFY_NL_A_PATH, path);
+       if (ret) goto attr_err_out;
+
+       genlmsg_end(skb, msg_head);
+
+       genlmsg_multicast(skb, 0, inotify_genl_family.id, GFP_KERNEL);
+
+       return;
+attr_err_out:
+       printk(KERN_ERR "VFS: Error when writing attributes to inotify
add wd netlink message!\n");
+err_out:
+       kfree_skb(skb);
+}
+EXPORT_SYMBOL(inotify_send_add_message);
+
+/**
+ * inotify_send_remove_message
+ * @fd: inotify fd
+ * @wd: watch descriptor
+ *
+ */
+
+void inotify_send_remove_message(u32 fd, u32 wd)
+{
+       static atomic_t seq;
+       struct sk_buff *skb;
+       void *msg_head;
+       int ret;
+       int msg_size = 3 * nla_total_size(sizeof(u32));
+
+       skb = genlmsg_new(msg_size, GFP_KERNEL);
+
+       if (!skb) {
+
+               printk(KERN_ERR "VFS: Not enough memory to send inotify
remove wd netlink message.\n");
+               return;
+
+       }
+
+       msg_head = genlmsg_put(skb, 0, atomic_add_return(1, &seq),
+                       &inotify_genl_family, 0,
INOTIFY_NL_C_REMOVE_MESSAGE);
+
+       if (!msg_head) {
+
+               printk(KERN_ERR "VFS: Cannot store netlink header in
inotify remove wd netlink message.\n");
+               goto err_out;
+
+       }
+
+       ret = nla_put_u32(skb, INOTIFY_NL_A_PID, current->pid);
+       if (ret) goto attr_err_out;
+
+       ret = nla_put_u32(skb, INOTIFY_NL_A_FD, fd);
+       if (ret) goto attr_err_out;
+
+       ret = nla_put_u32(skb, INOTIFY_NL_A_WD, wd);
+       if (ret) goto attr_err_out;
+
+       genlmsg_end(skb, msg_head);
+
+       genlmsg_multicast(skb, 0, inotify_genl_family.id, GFP_KERNEL);
+
+       return;
+attr_err_out:
+       printk(KERN_ERR "VFS: Error when writing attributes to inotify
remove wd netlink message\n");
+err_out:
+       kfree_skb(skb);
+}
+EXPORT_SYMBOL(inotify_send_remove_message);
+
+
+
+
+static int __init inotify_init(void)
+{
+       if (genl_register_family(&inotify_genl_family) != 0)
+               printk(KERN_ERR"VFS: Failed to create inotify_user
netlink interface.\n");
+       return 0;
+};
+
+module_init(inotify_init);
diff --git a/include/linux/inotify.h b/include/linux/inotify.h
index d33041e..4ad0b4f 100644
--- a/include/linux/inotify.h
+++ b/include/linux/inotify.h
@@ -84,4 +84,44 @@ extern struct ctl_table inotify_table[]; /* for sysctl */
 
 #endif
 
+/* commands */
+
+enum {
+       INOTIFY_NL_C_UNSPEC,
+       INOTIFY_NL_C_ADD_MESSAGE,
+       INOTIFY_NL_C_REMOVE_MESSAGE,
+       __INOTIFY_NL_C_MAX,
+};
+
+#define INOTIFY_NL_C_MAX (__INOTIFY_NL_C_MAX - 1)
+
+/* attributes */
+
+enum {
+       INOTIFY_NL_A_UNSPEC,
+       INOTIFY_NL_A_PID,
+       INOTIFY_NL_A_FD,
+       INOTIFY_NL_A_WD,
+       INOTIFY_NL_A_MASK,
+       INOTIFY_NL_A_PATH,
+       __INOTIFY_NL_A_MAX,
+};
+
+#define INOTIFY_NL_A_MAX (__INOTIFY_NL_A_MAX - 1)
+
+
+#ifdef CONFIG_INOTIFY_USER_NETLINK_INTERFACE
+extern void inotify_send_add_message(u32 fd, u32 wd, u32 mask, const
char *path);
+extern void inotify_send_remove_message(u32 fd, u32 wd);
+#else
+static inline void inotify_send_add_message(u32 fd, u32 wd, u32 mask,
const char *path)
+{
+       return;
+}
+static inline void inotify_send_remove_message(u32 fd, u32 wd);
+{
+       return;
+}
+#endif /* CONFIG_INOTIFY_USER_NETLINK_INTERFACE */
+
 #endif /* _LINUX_INOTIFY_H */

             reply	other threads:[~2012-01-07 13:51 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-01-07 13:36 Stef Bon [this message]
2012-01-07 14:38 ` [PATCH] VFS/inotify: send netlink messages when an inotify watch has been set or removed Al Viro
2012-01-07 15:03   ` Stef Bon
2012-01-07 15:42     ` Al Viro
2012-01-07 15:57     ` Al Viro
2012-01-07 16:59       ` Stef Bon
2012-01-07 19:05         ` Al Viro
2012-01-07 21:13           ` Stef Bon
  -- strict thread matches above, loose matches on Subject: below --
2012-01-05 20:56 Stef Bon
2012-01-06 14:13 ` Stef Bon

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4F084A4C.6080207@bononline.nl \
    --to=stef@bononline.nl \
    --cc=eparis@parisplace.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=rlove@rlove.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).