Hi, I want 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/netlink.c. For testing I've got a testprogram also supplied. Compile it with: gcc -Wall -I/usr/include/libnl3 -lnl-3 -lnl-genl-3 testnetlink.c -o testnetlink This testprogram just report's anything it receives on the new created GENERIC/VFS_INOTIFY group. The netlink messages can be usefull for other filesystems as well (nfs, cifs). 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 */
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/poll.h> #include <sys/socket.h> #include <sys/types.h> #include <unistd.h> #include <linux/types.h> #include <linux/netlink.h> #include <netlink/genl/genl.h> #include <netlink/genl/ctrl.h> #include <netlink/msg.h> #include <linux/inotify.h> #define MAX_PAYLOAD 4100 /* 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) static struct nla_policy inotify_nl_message_policy[INOTIFY_NL_A_MAX+1] = { [INOTIFY_NL_A_PID] = { .type = NLA_U32 }, [INOTIFY_NL_A_FD] = { .type = NLA_U32 }, [INOTIFY_NL_A_WD] = { .type = NLA_U32 }, [INOTIFY_NL_A_MASK] = { .type = NLA_U32 }, [INOTIFY_NL_A_PATH] = { .type = NLA_STRING }, }; static void print_mask(unsigned int mask) { if ( mask & IN_ACCESS ) fprintf(stderr, "IN_ACCESS\n"); if ( mask & IN_MODIFY ) fprintf(stderr, "IN_MODIFY\n"); if ( mask & IN_ATTRIB ) fprintf(stderr, "IN_ATTRIB\n"); if ( mask & IN_CLOSE_WRITE ) fprintf(stderr, "IN_CLOSE_WRITE\n"); if ( mask & IN_CLOSE_NOWRITE ) fprintf(stderr, "IN_CLOSE_NOWRITE\n"); if ( mask & IN_OPEN ) fprintf(stderr, "IN_OPEN\n"); if ( mask & IN_MOVED_FROM ) fprintf(stderr, "IN_MOVED_FROM\n"); if ( mask & IN_MOVED_TO ) fprintf(stderr, "IN_MOVED_TO\n"); if ( mask & IN_CREATE ) fprintf(stderr, "IN_CREATE\n"); if ( mask & IN_DELETE ) fprintf(stderr, "IN_DELETE\n"); if ( mask & IN_DELETE_SELF ) fprintf(stderr, "IN_DELETE_SELF\n"); if ( mask & IN_MOVE_SELF ) fprintf(stderr, "IN_MOVE_SELF\n"); if ( mask & IN_ONLYDIR ) fprintf(stderr, "IN_ONLYDIR\n"); if ( mask & IN_DONT_FOLLOW ) fprintf(stderr, "IN_DONT_FOLLOW\n"); if ( mask & IN_EXCL_UNLINK ) fprintf(stderr, "IN_EXCL_UNLINK\n"); if ( mask & IN_MASK_ADD ) fprintf(stderr, "IN_MASK_ADD\n"); if ( mask & IN_ISDIR ) fprintf(stderr, "IN_ISDIR\n"); if ( mask & IN_ONESHOT ) fprintf(stderr, "IN_ONESHOT\n"); } /* Parse netlink message and process it. */ static int inotify_nl_parser_payload(struct nlmsghdr *nlh) { struct genlmsghdr *ghdr; struct nlattr *attrs[INOTIFY_NL_A_MAX+1]; int ret; if (!genlmsg_valid_hdr(nlh, 0)) { fprintf(stderr, "header not valid.\n"); return 0; } ghdr = nlmsg_data(nlh); /* Unknown message? Ignore... */ if (ghdr->cmd != INOTIFY_NL_C_ADD_MESSAGE && ghdr->cmd != INOTIFY_NL_C_REMOVE_MESSAGE) { fprintf(stderr, "message not reckognized.\n"); return 0; } ret = genlmsg_parse(nlh, 0, attrs, INOTIFY_NL_A_MAX, inotify_nl_message_policy); if (ret < 0) { fprintf(stderr, "Error parsing netlink message.\n"); return ret; } if ( ! attrs[INOTIFY_NL_A_PID] ) { fprintf(stderr, "Missing mask in message.\n"); } if ( ! attrs[INOTIFY_NL_A_FD] ) { fprintf(stderr, "Missing mask in message.\n"); } if ( ! attrs[INOTIFY_NL_A_WD] ) { fprintf(stderr, "Missing mask in message.\n"); } if ( ghdr->cmd == INOTIFY_NL_C_ADD_MESSAGE ) { if ( ! attrs[INOTIFY_NL_A_MASK] ) fprintf(stderr, "Missing mask in message.\n"); if ( ! attrs[INOTIFY_NL_A_PATH] ) fprintf(stderr, "Missing path in message.\n"); fprintf(stdout, "inotify_add: pid: %i fd:%i wd: %i mask: %i path: %s\n", nla_get_u32(attrs[INOTIFY_NL_A_PID]), nla_get_u32(attrs[INOTIFY_NL_A_FD]), nla_get_u32(attrs[INOTIFY_NL_A_WD]), nla_get_u32(attrs[INOTIFY_NL_A_MASK]), nla_get_string(attrs[INOTIFY_NL_A_PATH])); print_mask(nla_get_u32(attrs[INOTIFY_NL_A_MASK])); } else { fprintf(stdout, "inotify_remove: pid: %i fd:%i wd: %i\n", nla_get_u32(attrs[INOTIFY_NL_A_PID]), nla_get_u32(attrs[INOTIFY_NL_A_FD]), nla_get_u32(attrs[INOTIFY_NL_A_WD])); } return 0; } int main(int argc, char *argv[]) { struct sockaddr_nl nls; struct pollfd pfd; // struct msghdr msg; char buf[4100]; struct iovec iov = { buf, sizeof(buf) }; struct nlmsghdr *nlh; int len, i; struct msghdr msg = { .msg_name=(void *) &nls, .msg_namelen=sizeof(nls), .msg_iov=&iov, .msg_iovlen=1, .msg_control=NULL, .msg_controllen=0, .msg_flags=0 }; // netlink socket memset(&nls,0,sizeof(struct sockaddr_nl)); nls.nl_family = AF_NETLINK; nls.nl_pid = getpid(); nls.nl_groups = -1; /* multicast */ pfd.events = POLLIN; pfd.fd = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_GENERIC); if (pfd.fd==-1) { fprintf(stderr, "Not root\n"); exit(1); } // Listen to netlink socket if ( bind(pfd.fd, (void *) &nls, sizeof(struct sockaddr_nl)) ) { fprintf(stderr, "Bind failed\n"); exit(1); } while (-1!=poll(&pfd, 1, -1)) { len = recvmsg(pfd.fd, &msg, 0); if (len == -1) { fprintf(stderr, "recv\n"); } else { // Parse the message fprintf(stdout, "activity....\n"); for (nlh=(struct nlmsghdr *) buf; NLMSG_OK(nlh, len); nlh=NLMSG_NEXT(nlh, len)) { if ( nlh->nlmsg_type==NLMSG_DONE ) { fprintf(stdout, "ready with message\n"); } else if ( nlh->nlmsg_type==NLMSG_ERROR ) { fprintf(stdout, "error message\n"); } else { fprintf(stdout, "parsing message\n"); i=inotify_nl_parser_payload(nlh); } } } } // Dear gcc: shut up. return 0; }
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 */