diff options
author | Eric Paris <eparis@redhat.com> | 2010-07-28 10:18:37 -0400 |
---|---|---|
committer | Eric Paris <eparis@redhat.com> | 2010-07-28 10:18:49 -0400 |
commit | 8c1934c8d70b22ca8333b216aec6c7d09fdbd6a6 (patch) | |
tree | 25fffb46e0b1594aa692ed10e755b6ae041022bc /fs | |
parent | 611da04f7a31b2208e838be55a42c7a1310ae321 (diff) | |
download | linux-stable-8c1934c8d70b22ca8333b216aec6c7d09fdbd6a6.tar.gz linux-stable-8c1934c8d70b22ca8333b216aec6c7d09fdbd6a6.tar.bz2 linux-stable-8c1934c8d70b22ca8333b216aec6c7d09fdbd6a6.zip |
inotify: allow users to request not to recieve events on unlinked children
An inotify watch on a directory will send events for children even if those
children have been unlinked. This patch add a new inotify flag IN_EXCL_UNLINK
which allows a watch to specificy they don't care about unlinked children.
This should fix performance problems seen by tasks which add a watch to
/tmp and then are overrun with events when other processes are reading and
writing to unlinked files they created in /tmp.
https://bugzilla.kernel.org/show_bug.cgi?id=16296
Requested-by: Matthias Clasen <mclasen@redhat.com>
Signed-off-by: Eric Paris <eparis@redhat.com>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/notify/inotify/inotify_fsnotify.c | 9 | ||||
-rw-r--r-- | fs/notify/inotify/inotify_user.c | 2 |
2 files changed, 10 insertions, 1 deletions
diff --git a/fs/notify/inotify/inotify_fsnotify.c b/fs/notify/inotify/inotify_fsnotify.c index 388a150c3d4a..9d332e7f5a5c 100644 --- a/fs/notify/inotify/inotify_fsnotify.c +++ b/fs/notify/inotify/inotify_fsnotify.c @@ -22,6 +22,7 @@ * General Public License for more details. */ +#include <linux/dcache.h> /* d_unlinked */ #include <linux/fs.h> /* struct inode */ #include <linux/fsnotify_backend.h> #include <linux/inotify.h> @@ -157,6 +158,14 @@ static bool inotify_should_send_event(struct fsnotify_group *group, struct inode mask = (mask & ~FS_EVENT_ON_CHILD); send = (fsn_mark->mask & mask); + if (send && (fsn_mark->mask & FS_EXCL_UNLINK) && + (data_type == FSNOTIFY_EVENT_PATH)) { + struct path *path = data; + + if (d_unlinked(path->dentry)) + send = false; + } + /* find took a reference */ fsnotify_put_mark(fsn_mark); diff --git a/fs/notify/inotify/inotify_user.c b/fs/notify/inotify/inotify_user.c index f381dafe8efb..dfc80f70e517 100644 --- a/fs/notify/inotify/inotify_user.c +++ b/fs/notify/inotify/inotify_user.c @@ -97,7 +97,7 @@ static inline __u32 inotify_arg_to_mask(u32 arg) mask = (FS_IN_IGNORED | FS_EVENT_ON_CHILD | FS_UNMOUNT); /* mask off the flags used to open the fd */ - mask |= (arg & (IN_ALL_EVENTS | IN_ONESHOT)); + mask |= (arg & (IN_ALL_EVENTS | IN_ONESHOT | IN_EXCL_UNLINK)); return mask; } |