diff options
author | Eric Paris <eparis@redhat.com> | 2009-12-17 21:24:29 -0500 |
---|---|---|
committer | Eric Paris <eparis@redhat.com> | 2010-07-28 09:58:59 -0400 |
commit | 0ff21db9fcc39042b814dad8a4b7508710a75235 (patch) | |
tree | a650b240f64893f86626b8b4a4b694446190aa3a | |
parent | 90dd201d1ab064512078a77762a793e0bf5f3040 (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.c | 15 | ||||
-rw-r--r-- | include/linux/fanotify.h | 4 |
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 |