summaryrefslogtreecommitdiff
path: root/fs/notify/fanotify
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 /fs/notify/fanotify
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>
Diffstat (limited to 'fs/notify/fanotify')
-rw-r--r--fs/notify/fanotify/fanotify_user.c15
1 files changed, 11 insertions, 4 deletions
diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c
index db80a0d89d2..81267260d1b 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,
__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;