aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAmir Goldstein <amir73il@gmail.com>2018-09-01 03:41:13 -0400
committerJan Kara <jack@suse.cz>2018-09-03 09:16:11 -0400
commitd54f4fba889b205e9cd8239182ca5d27d0ac3bc2 (patch)
tree2b0e5b709d0663942520d6aa830a7cd517db804d
parent60f7ed8c7c4d06aeda448c6da74621552ee739aa (diff)
fanotify: add API to attach/detach super block mark
Add another mark type flag FAN_MARK_FILESYSTEM for add/remove/flush of super block mark type. A super block watch gets all events on the filesystem, regardless of the mount from which the mark was added, unless an ignore mask exists on either the inode or the mount where the event was generated. Only one of FAN_MARK_MOUNT and FAN_MARK_FILESYSTEM mark type flags may be provided to fanotify_mark() or no mark type flag for inode mark. Cc: <linux-api@vger.kernel.org> Signed-off-by: Amir Goldstein <amir73il@gmail.com> Signed-off-by: Jan Kara <jack@suse.cz>
-rw-r--r--fs/notify/fanotify/fanotify_user.c42
-rw-r--r--include/uapi/linux/fanotify.h16
2 files changed, 49 insertions, 9 deletions
diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c
index 69054886915b..1347c588f778 100644
--- a/fs/notify/fanotify/fanotify_user.c
+++ b/fs/notify/fanotify/fanotify_user.c
@@ -563,6 +563,13 @@ static int fanotify_remove_vfsmount_mark(struct fsnotify_group *group,
563 mask, flags); 563 mask, flags);
564} 564}
565 565
566static int fanotify_remove_sb_mark(struct fsnotify_group *group,
567 struct super_block *sb, __u32 mask,
568 unsigned int flags)
569{
570 return fanotify_remove_mark(group, &sb->s_fsnotify_marks, mask, flags);
571}
572
566static int fanotify_remove_inode_mark(struct fsnotify_group *group, 573static int fanotify_remove_inode_mark(struct fsnotify_group *group,
567 struct inode *inode, __u32 mask, 574 struct inode *inode, __u32 mask,
568 unsigned int flags) 575 unsigned int flags)
@@ -658,6 +665,14 @@ static int fanotify_add_vfsmount_mark(struct fsnotify_group *group,
658 FSNOTIFY_OBJ_TYPE_VFSMOUNT, mask, flags); 665 FSNOTIFY_OBJ_TYPE_VFSMOUNT, mask, flags);
659} 666}
660 667
668static int fanotify_add_sb_mark(struct fsnotify_group *group,
669 struct super_block *sb, __u32 mask,
670 unsigned int flags)
671{
672 return fanotify_add_mark(group, &sb->s_fsnotify_marks,
673 FSNOTIFY_OBJ_TYPE_SB, mask, flags);
674}
675
661static int fanotify_add_inode_mark(struct fsnotify_group *group, 676static int fanotify_add_inode_mark(struct fsnotify_group *group,
662 struct inode *inode, __u32 mask, 677 struct inode *inode, __u32 mask,
663 unsigned int flags) 678 unsigned int flags)
@@ -806,6 +821,7 @@ static int do_fanotify_mark(int fanotify_fd, unsigned int flags, __u64 mask,
806 struct fd f; 821 struct fd f;
807 struct path path; 822 struct path path;
808 u32 valid_mask = FAN_ALL_EVENTS | FAN_EVENT_ON_CHILD; 823 u32 valid_mask = FAN_ALL_EVENTS | FAN_EVENT_ON_CHILD;
824 unsigned int mark_type = flags & FAN_MARK_TYPE_MASK;
809 int ret; 825 int ret;
810 826
811 pr_debug("%s: fanotify_fd=%d flags=%x dfd=%d pathname=%p mask=%llx\n", 827 pr_debug("%s: fanotify_fd=%d flags=%x dfd=%d pathname=%p mask=%llx\n",
@@ -817,6 +833,16 @@ static int do_fanotify_mark(int fanotify_fd, unsigned int flags, __u64 mask,
817 833
818 if (flags & ~FAN_ALL_MARK_FLAGS) 834 if (flags & ~FAN_ALL_MARK_FLAGS)
819 return -EINVAL; 835 return -EINVAL;
836
837 switch (mark_type) {
838 case FAN_MARK_INODE:
839 case FAN_MARK_MOUNT:
840 case FAN_MARK_FILESYSTEM:
841 break;
842 default:
843 return -EINVAL;
844 }
845
820 switch (flags & (FAN_MARK_ADD | FAN_MARK_REMOVE | FAN_MARK_FLUSH)) { 846 switch (flags & (FAN_MARK_ADD | FAN_MARK_REMOVE | FAN_MARK_FLUSH)) {
821 case FAN_MARK_ADD: /* fallthrough */ 847 case FAN_MARK_ADD: /* fallthrough */
822 case FAN_MARK_REMOVE: 848 case FAN_MARK_REMOVE:
@@ -824,7 +850,7 @@ static int do_fanotify_mark(int fanotify_fd, unsigned int flags, __u64 mask,
824 return -EINVAL; 850 return -EINVAL;
825 break; 851 break;
826 case FAN_MARK_FLUSH: 852 case FAN_MARK_FLUSH:
827 if (flags & ~(FAN_MARK_MOUNT | FAN_MARK_FLUSH)) 853 if (flags & ~(FAN_MARK_TYPE_MASK | FAN_MARK_FLUSH))
828 return -EINVAL; 854 return -EINVAL;
829 break; 855 break;
830 default: 856 default:
@@ -863,8 +889,10 @@ static int do_fanotify_mark(int fanotify_fd, unsigned int flags, __u64 mask,
863 889
864 if (flags & FAN_MARK_FLUSH) { 890 if (flags & FAN_MARK_FLUSH) {
865 ret = 0; 891 ret = 0;
866 if (flags & FAN_MARK_MOUNT) 892 if (mark_type == FAN_MARK_MOUNT)
867 fsnotify_clear_vfsmount_marks_by_group(group); 893 fsnotify_clear_vfsmount_marks_by_group(group);
894 else if (mark_type == FAN_MARK_FILESYSTEM)
895 fsnotify_clear_sb_marks_by_group(group);
868 else 896 else
869 fsnotify_clear_inode_marks_by_group(group); 897 fsnotify_clear_inode_marks_by_group(group);
870 goto fput_and_out; 898 goto fput_and_out;
@@ -875,7 +903,7 @@ static int do_fanotify_mark(int fanotify_fd, unsigned int flags, __u64 mask,
875 goto fput_and_out; 903 goto fput_and_out;
876 904
877 /* inode held in place by reference to path; group by fget on fd */ 905 /* inode held in place by reference to path; group by fget on fd */
878 if (!(flags & FAN_MARK_MOUNT)) 906 if (mark_type == FAN_MARK_INODE)
879 inode = path.dentry->d_inode; 907 inode = path.dentry->d_inode;
880 else 908 else
881 mnt = path.mnt; 909 mnt = path.mnt;
@@ -883,14 +911,18 @@ static int do_fanotify_mark(int fanotify_fd, unsigned int flags, __u64 mask,
883 /* create/update an inode mark */ 911 /* create/update an inode mark */
884 switch (flags & (FAN_MARK_ADD | FAN_MARK_REMOVE)) { 912 switch (flags & (FAN_MARK_ADD | FAN_MARK_REMOVE)) {
885 case FAN_MARK_ADD: 913 case FAN_MARK_ADD:
886 if (flags & FAN_MARK_MOUNT) 914 if (mark_type == FAN_MARK_MOUNT)
887 ret = fanotify_add_vfsmount_mark(group, mnt, mask, flags); 915 ret = fanotify_add_vfsmount_mark(group, mnt, mask, flags);
916 else if (mark_type == FAN_MARK_FILESYSTEM)
917 ret = fanotify_add_sb_mark(group, mnt->mnt_sb, mask, flags);
888 else 918 else
889 ret = fanotify_add_inode_mark(group, inode, mask, flags); 919 ret = fanotify_add_inode_mark(group, inode, mask, flags);
890 break; 920 break;
891 case FAN_MARK_REMOVE: 921 case FAN_MARK_REMOVE:
892 if (flags & FAN_MARK_MOUNT) 922 if (mark_type == FAN_MARK_MOUNT)
893 ret = fanotify_remove_vfsmount_mark(group, mnt, mask, flags); 923 ret = fanotify_remove_vfsmount_mark(group, mnt, mask, flags);
924 else if (mark_type == FAN_MARK_FILESYSTEM)
925 ret = fanotify_remove_sb_mark(group, mnt->mnt_sb, mask, flags);
894 else 926 else
895 ret = fanotify_remove_inode_mark(group, inode, mask, flags); 927 ret = fanotify_remove_inode_mark(group, inode, mask, flags);
896 break; 928 break;
diff --git a/include/uapi/linux/fanotify.h b/include/uapi/linux/fanotify.h
index 74247917de04..ad81234d1919 100644
--- a/include/uapi/linux/fanotify.h
+++ b/include/uapi/linux/fanotify.h
@@ -27,7 +27,7 @@
27#define FAN_CLOEXEC 0x00000001 27#define FAN_CLOEXEC 0x00000001
28#define FAN_NONBLOCK 0x00000002 28#define FAN_NONBLOCK 0x00000002
29 29
30/* These are NOT bitwise flags. Both bits are used togther. */ 30/* These are NOT bitwise flags. Both bits are used together. */
31#define FAN_CLASS_NOTIF 0x00000000 31#define FAN_CLASS_NOTIF 0x00000000
32#define FAN_CLASS_CONTENT 0x00000004 32#define FAN_CLASS_CONTENT 0x00000004
33#define FAN_CLASS_PRE_CONTENT 0x00000008 33#define FAN_CLASS_PRE_CONTENT 0x00000008
@@ -47,19 +47,27 @@
47#define FAN_MARK_REMOVE 0x00000002 47#define FAN_MARK_REMOVE 0x00000002
48#define FAN_MARK_DONT_FOLLOW 0x00000004 48#define FAN_MARK_DONT_FOLLOW 0x00000004
49#define FAN_MARK_ONLYDIR 0x00000008 49#define FAN_MARK_ONLYDIR 0x00000008
50#define FAN_MARK_MOUNT 0x00000010 50/* FAN_MARK_MOUNT is 0x00000010 */
51#define FAN_MARK_IGNORED_MASK 0x00000020 51#define FAN_MARK_IGNORED_MASK 0x00000020
52#define FAN_MARK_IGNORED_SURV_MODIFY 0x00000040 52#define FAN_MARK_IGNORED_SURV_MODIFY 0x00000040
53#define FAN_MARK_FLUSH 0x00000080 53#define FAN_MARK_FLUSH 0x00000080
54/* FAN_MARK_FILESYSTEM is 0x00000100 */
55
56/* These are NOT bitwise flags. Both bits can be used togther. */
57#define FAN_MARK_INODE 0x00000000
58#define FAN_MARK_MOUNT 0x00000010
59#define FAN_MARK_FILESYSTEM 0x00000100
60#define FAN_MARK_TYPE_MASK (FAN_MARK_INODE | FAN_MARK_MOUNT | \
61 FAN_MARK_FILESYSTEM)
54 62
55#define FAN_ALL_MARK_FLAGS (FAN_MARK_ADD |\ 63#define FAN_ALL_MARK_FLAGS (FAN_MARK_ADD |\
56 FAN_MARK_REMOVE |\ 64 FAN_MARK_REMOVE |\
57 FAN_MARK_DONT_FOLLOW |\ 65 FAN_MARK_DONT_FOLLOW |\
58 FAN_MARK_ONLYDIR |\ 66 FAN_MARK_ONLYDIR |\
59 FAN_MARK_MOUNT |\
60 FAN_MARK_IGNORED_MASK |\ 67 FAN_MARK_IGNORED_MASK |\
61 FAN_MARK_IGNORED_SURV_MODIFY |\ 68 FAN_MARK_IGNORED_SURV_MODIFY |\
62 FAN_MARK_FLUSH) 69 FAN_MARK_FLUSH|\
70 FAN_MARK_TYPE_MASK)
63 71
64/* 72/*
65 * All of the events - we build the list by hand so that we can add flags in 73 * All of the events - we build the list by hand so that we can add flags in