aboutsummaryrefslogtreecommitdiffstats
path: root/fs/notify
diff options
context:
space:
mode:
authorEric Paris <eparis@redhat.com>2010-10-28 17:21:56 -0400
committerEric Paris <eparis@redhat.com>2010-10-28 17:22:13 -0400
commit4231a23530a30e86eb32fbe869bbef1b3e54d5aa (patch)
treebb268ea2e6cb50e8ea46e1f5a536ae0f0afb4e06 /fs/notify
parent6ad2d4e3e97ee4bfde0b45e8dfe37911330fc4aa (diff)
fanotify: implement fanotify listener ordering
The fanotify listeners needs to be able to specify what types of operations they are going to perform so they can be ordered appropriately between other listeners doing other types of operations. They need this to be able to make sure that things like hierarchichal storage managers will get access to inodes before processes which need the data. This patch defines 3 possible uses which groups must indicate in the fanotify_init() flags. FAN_CLASS_PRE_CONTENT FAN_CLASS_CONTENT FAN_CLASS_NOTIF Groups will receive notification in that order. The order between 2 groups in the same class is undeterministic. FAN_CLASS_PRE_CONTENT is intended to be used by listeners which need access to the inode before they are certain that the inode contains it's final data. A hierarchical storage manager should choose to use this class. FAN_CLASS_CONTENT is intended to be used by listeners which need access to the inode after it contains its intended contents. This would be the appropriate level for an AV solution or document control system. FAN_CLASS_NOTIF is intended for normal async notification about access, much the same as inotify and dnotify. Syncronous permissions events are not permitted at this class. Signed-off-by: Eric Paris <eparis@redhat.com>
Diffstat (limited to 'fs/notify')
-rw-r--r--fs/notify/fanotify/fanotify_user.c25
1 files changed, 24 insertions, 1 deletions
diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c
index bbcb98e7fcc6..1c09e6321c5e 100644
--- a/fs/notify/fanotify/fanotify_user.c
+++ b/fs/notify/fanotify/fanotify_user.c
@@ -664,6 +664,20 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags)
664 init_waitqueue_head(&group->fanotify_data.access_waitq); 664 init_waitqueue_head(&group->fanotify_data.access_waitq);
665 INIT_LIST_HEAD(&group->fanotify_data.access_list); 665 INIT_LIST_HEAD(&group->fanotify_data.access_list);
666#endif 666#endif
667 switch (flags & FAN_ALL_CLASS_BITS) {
668 case FAN_CLASS_NOTIF:
669 group->priority = FS_PRIO_0;
670 break;
671 case FAN_CLASS_CONTENT:
672 group->priority = FS_PRIO_1;
673 break;
674 case FAN_CLASS_PRE_CONTENT:
675 group->priority = FS_PRIO_2;
676 break;
677 default:
678 fd = -EINVAL;
679 goto out_put_group;
680 }
667 681
668 fd = anon_inode_getfd("[fanotify]", &fanotify_fops, group, f_flags); 682 fd = anon_inode_getfd("[fanotify]", &fanotify_fops, group, f_flags);
669 if (fd < 0) 683 if (fd < 0)
@@ -719,6 +733,16 @@ SYSCALL_DEFINE(fanotify_mark)(int fanotify_fd, unsigned int flags,
719 ret = -EINVAL; 733 ret = -EINVAL;
720 if (unlikely(filp->f_op != &fanotify_fops)) 734 if (unlikely(filp->f_op != &fanotify_fops))
721 goto fput_and_out; 735 goto fput_and_out;
736 group = filp->private_data;
737
738 /*
739 * group->priority == FS_PRIO_0 == FAN_CLASS_NOTIF. These are not
740 * allowed to set permissions events.
741 */
742 ret = -EINVAL;
743 if (mask & FAN_ALL_PERM_EVENTS &&
744 group->priority == FS_PRIO_0)
745 goto fput_and_out;
722 746
723 ret = fanotify_find_path(dfd, pathname, &path, flags); 747 ret = fanotify_find_path(dfd, pathname, &path, flags);
724 if (ret) 748 if (ret)
@@ -729,7 +753,6 @@ SYSCALL_DEFINE(fanotify_mark)(int fanotify_fd, unsigned int flags,
729 inode = path.dentry->d_inode; 753 inode = path.dentry->d_inode;
730 else 754 else
731 mnt = path.mnt; 755 mnt = path.mnt;
732 group = filp->private_data;
733 756
734 /* create/update an inode mark */ 757 /* create/update an inode mark */
735 switch (flags & (FAN_MARK_ADD | FAN_MARK_REMOVE | FAN_MARK_FLUSH)) { 758 switch (flags & (FAN_MARK_ADD | FAN_MARK_REMOVE | FAN_MARK_FLUSH)) {