fanotify: hooks the fanotify_mark syscall to the vfsmount code
authorEric Paris <eparis@redhat.com>
Fri, 18 Dec 2009 02:24:29 +0000 (21:24 -0500)
committerEric Paris <eparis@redhat.com>
Wed, 28 Jul 2010 13:58:59 +0000 (09:58 -0400)
Create a new fanotify_mark flag which indicates we should attach the mark
to the vfsmount holding the object referenced by dfd and pathname rather
than the inode itself.

Signed-off-by: Eric Paris <eparis@redhat.com>
fs/notify/fanotify/fanotify_user.c
include/linux/fanotify.h

index db80a0d89d24ba0f80d426f4df25a09a463297aa..81267260d1b9c91c5abdc7b826e6da3ed3590f6f 100644 (file)
@@ -485,7 +485,8 @@ SYSCALL_DEFINE(fanotify_mark)(int fanotify_fd, unsigned int flags,
                              __u64 mask, int dfd,
                              const char  __user * pathname)
 {
-       struct inode *inode;
+       struct inode *inode = NULL;
+       struct vfsmount *mnt = NULL;
        struct fsnotify_group *group;
        struct file *filp;
        struct path path;
@@ -515,16 +516,22 @@ SYSCALL_DEFINE(fanotify_mark)(int fanotify_fd, unsigned int flags,
                goto fput_and_out;
 
        /* inode held in place by reference to path; group by fget on fd */
-       inode = path.dentry->d_inode;
+       if (!(flags & FAN_MARK_ON_VFSMOUNT))
+               inode = path.dentry->d_inode;
+       else
+               mnt = path.mnt;
        group = filp->private_data;
 
        /* create/update an inode mark */
        switch (flags & (FAN_MARK_ADD | FAN_MARK_REMOVE)) {
        case FAN_MARK_ADD:
-               ret = fanotify_add_inode_mark(group, inode, mask);
+               if (flags & FAN_MARK_ON_VFSMOUNT)
+                       ret = fanotify_add_vfsmount_mark(group, mnt, mask);
+               else
+                       ret = fanotify_add_inode_mark(group, inode, mask);
                break;
        case FAN_MARK_REMOVE:
-               ret = fanotify_remove_mark(group, inode, NULL, mask);
+               ret = fanotify_remove_mark(group, inode, mnt, mask);
                break;
        default:
                ret = -EINVAL;
index 5f633af4d1b0d751ab271c049da9d66473fdb01e..e25d348188ca69bf8d623ddbc4a533007a825e1d 100644 (file)
 #define FAN_MARK_REMOVE                0x00000002
 #define FAN_MARK_DONT_FOLLOW   0x00000004
 #define FAN_MARK_ONLYDIR       0x00000008
+#define FAN_MARK_ON_VFSMOUNT   0x00000010
 
 #define FAN_ALL_MARK_FLAGS     (FAN_MARK_ADD |\
                                 FAN_MARK_REMOVE |\
                                 FAN_MARK_DONT_FOLLOW |\
-                                FAN_MARK_ONLYDIR)
+                                FAN_MARK_ONLYDIR |\
+                                FAN_MARK_ON_VFSMOUNT)
 
 /*
  * All of the events - we build the list by hand so that we can add flags in