aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Paris <eparis@redhat.com>2009-12-17 21:24:29 -0500
committerEric Paris <eparis@redhat.com>2010-07-28 09:58:59 -0400
commit0ff21db9fcc39042b814dad8a4b7508710a75235 (patch)
treea650b240f64893f86626b8b4a4b694446190aa3a
parent90dd201d1ab064512078a77762a793e0bf5f3040 (diff)
fanotify: hooks the fanotify_mark syscall to the vfsmount code
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>
-rw-r--r--fs/notify/fanotify/fanotify_user.c15
-rw-r--r--include/linux/fanotify.h4
2 files changed, 14 insertions, 5 deletions
diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c
index db80a0d89d24..81267260d1b9 100644
--- a/fs/notify/fanotify/fanotify_user.c
+++ b/fs/notify/fanotify/fanotify_user.c
@@ -485,7 +485,8 @@ SYSCALL_DEFINE(fanotify_mark)(int fanotify_fd, unsigned int flags,
485 __u64 mask, int dfd, 485 __u64 mask, int dfd,
486 const char __user * pathname) 486 const char __user * pathname)
487{ 487{
488 struct inode *inode; 488 struct inode *inode = NULL;
489 struct vfsmount *mnt = NULL;
489 struct fsnotify_group *group; 490 struct fsnotify_group *group;
490 struct file *filp; 491 struct file *filp;
491 struct path path; 492 struct path path;
@@ -515,16 +516,22 @@ SYSCALL_DEFINE(fanotify_mark)(int fanotify_fd, unsigned int flags,
515 goto fput_and_out; 516 goto fput_and_out;
516 517
517 /* inode held in place by reference to path; group by fget on fd */ 518 /* inode held in place by reference to path; group by fget on fd */
518 inode = path.dentry->d_inode; 519 if (!(flags & FAN_MARK_ON_VFSMOUNT))
520 inode = path.dentry->d_inode;
521 else
522 mnt = path.mnt;
519 group = filp->private_data; 523 group = filp->private_data;
520 524
521 /* create/update an inode mark */ 525 /* create/update an inode mark */
522 switch (flags & (FAN_MARK_ADD | FAN_MARK_REMOVE)) { 526 switch (flags & (FAN_MARK_ADD | FAN_MARK_REMOVE)) {
523 case FAN_MARK_ADD: 527 case FAN_MARK_ADD:
524 ret = fanotify_add_inode_mark(group, inode, mask); 528 if (flags & FAN_MARK_ON_VFSMOUNT)
529 ret = fanotify_add_vfsmount_mark(group, mnt, mask);
530 else
531 ret = fanotify_add_inode_mark(group, inode, mask);
525 break; 532 break;
526 case FAN_MARK_REMOVE: 533 case FAN_MARK_REMOVE:
527 ret = fanotify_remove_mark(group, inode, NULL, mask); 534 ret = fanotify_remove_mark(group, inode, mnt, mask);
528 break; 535 break;
529 default: 536 default:
530 ret = -EINVAL; 537 ret = -EINVAL;
diff --git a/include/linux/fanotify.h b/include/linux/fanotify.h
index 5f633af4d1b0..e25d348188ca 100644
--- a/include/linux/fanotify.h
+++ b/include/linux/fanotify.h
@@ -29,11 +29,13 @@
29#define FAN_MARK_REMOVE 0x00000002 29#define FAN_MARK_REMOVE 0x00000002
30#define FAN_MARK_DONT_FOLLOW 0x00000004 30#define FAN_MARK_DONT_FOLLOW 0x00000004
31#define FAN_MARK_ONLYDIR 0x00000008 31#define FAN_MARK_ONLYDIR 0x00000008
32#define FAN_MARK_ON_VFSMOUNT 0x00000010
32 33
33#define FAN_ALL_MARK_FLAGS (FAN_MARK_ADD |\ 34#define FAN_ALL_MARK_FLAGS (FAN_MARK_ADD |\
34 FAN_MARK_REMOVE |\ 35 FAN_MARK_REMOVE |\
35 FAN_MARK_DONT_FOLLOW |\ 36 FAN_MARK_DONT_FOLLOW |\
36 FAN_MARK_ONLYDIR) 37 FAN_MARK_ONLYDIR |\
38 FAN_MARK_ON_VFSMOUNT)
37 39
38/* 40/*
39 * All of the events - we build the list by hand so that we can add flags in 41 * All of the events - we build the list by hand so that we can add flags in