summaryrefslogtreecommitdiffstats
path: root/fs/notify
diff options
context:
space:
mode:
authorEric Paris <eparis@redhat.com>2010-10-28 17:21:59 -0400
committerEric Paris <eparis@redhat.com>2010-10-28 17:22:16 -0400
commit8fcd65280abc4699510f1853ede31f43e8a3783a (patch)
tree9ef20b7c3ee0a4130d88922d7d4115beaa0c9dc0 /fs/notify
parentb29866aab8489487f11cc4506590ac31bdbae22a (diff)
downloadlinux-8fcd65280abc4699510f1853ede31f43e8a3783a.tar.gz
linux-8fcd65280abc4699510f1853ede31f43e8a3783a.tar.bz2
linux-8fcd65280abc4699510f1853ede31f43e8a3783a.zip
fanotify: ignore events on directories unless specifically requested
fanotify has a very limited number of events it sends on directories. The usefulness of these events is yet to be seen and still we send them. This is particularly painful for mount marks where one might receive many of these useless events. As such this patch will drop events on IS_DIR() inodes unless they were explictly requested with FAN_ON_DIR. This means that a mark on a directory without FAN_EVENT_ON_CHILD or FAN_ON_DIR is meaningless and will result in no events ever (although it will still be allowed since detecting it is hard) Signed-off-by: Eric Paris <eparis@redhat.com>
Diffstat (limited to 'fs/notify')
-rw-r--r--fs/notify/fanotify/fanotify.c5
-rw-r--r--fs/notify/fanotify/fanotify_user.c12
2 files changed, 17 insertions, 0 deletions
diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c
index 8d98e1f5817b..b04f88eed09e 100644
--- a/fs/notify/fanotify/fanotify.c
+++ b/fs/notify/fanotify/fanotify.c
@@ -131,6 +131,7 @@ static int fanotify_handle_event(struct fsnotify_group *group,
BUILD_BUG_ON(FAN_Q_OVERFLOW != FS_Q_OVERFLOW);
BUILD_BUG_ON(FAN_OPEN_PERM != FS_OPEN_PERM);
BUILD_BUG_ON(FAN_ACCESS_PERM != FS_ACCESS_PERM);
+ BUILD_BUG_ON(FAN_ONDIR != FS_ISDIR);
pr_debug("%s: group=%p event=%p\n", __func__, group, event);
@@ -195,6 +196,10 @@ static bool fanotify_should_send_event(struct fsnotify_group *group,
BUG();
}
+ if (S_ISDIR(path->dentry->d_inode->i_mode) &&
+ (marks_ignored_mask & FS_ISDIR))
+ return false;
+
if (event_mask & marks_mask & ~marks_ignored_mask)
return true;
diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c
index a7d9369482d5..ff1a908c9708 100644
--- a/fs/notify/fanotify/fanotify_user.c
+++ b/fs/notify/fanotify/fanotify_user.c
@@ -570,6 +570,12 @@ static __u32 fanotify_mark_add_to_mask(struct fsnotify_mark *fsn_mark,
if (flags & FAN_MARK_IGNORED_SURV_MODIFY)
fsn_mark->flags |= FSNOTIFY_MARK_FLAG_IGNORED_SURV_MODIFY;
}
+
+ if (!(flags & FAN_MARK_ONDIR)) {
+ __u32 tmask = fsn_mark->ignored_mask | FAN_ONDIR;
+ fsnotify_set_mark_ignored_mask_locked(fsn_mark, tmask);
+ }
+
spin_unlock(&fsn_mark->lock);
return mask & ~oldmask;
@@ -766,6 +772,12 @@ SYSCALL_DEFINE(fanotify_mark)(int fanotify_fd, unsigned int flags,
default:
return -EINVAL;
}
+
+ if (mask & FAN_ONDIR) {
+ flags |= FAN_MARK_ONDIR;
+ mask &= ~FAN_ONDIR;
+ }
+
#ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS
if (mask & ~(FAN_ALL_EVENTS | FAN_ALL_PERM_EVENTS | FAN_EVENT_ON_CHILD))
#else