aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Paris <eparis@redhat.com>2010-07-28 10:18:37 -0400
committerEric Paris <eparis@redhat.com>2010-07-28 10:18:49 -0400
commit8c1934c8d70b22ca8333b216aec6c7d09fdbd6a6 (patch)
tree25fffb46e0b1594aa692ed10e755b6ae041022bc
parent611da04f7a31b2208e838be55a42c7a1310ae321 (diff)
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>
-rw-r--r--fs/notify/inotify/inotify_fsnotify.c9
-rw-r--r--fs/notify/inotify/inotify_user.c2
-rw-r--r--include/linux/fsnotify_backend.h1
-rw-r--r--include/linux/inotify.h1
4 files changed, 12 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 @@
22 * General Public License for more details. 22 * General Public License for more details.
23 */ 23 */
24 24
25#include <linux/dcache.h> /* d_unlinked */
25#include <linux/fs.h> /* struct inode */ 26#include <linux/fs.h> /* struct inode */
26#include <linux/fsnotify_backend.h> 27#include <linux/fsnotify_backend.h>
27#include <linux/inotify.h> 28#include <linux/inotify.h>
@@ -157,6 +158,14 @@ static bool inotify_should_send_event(struct fsnotify_group *group, struct inode
157 mask = (mask & ~FS_EVENT_ON_CHILD); 158 mask = (mask & ~FS_EVENT_ON_CHILD);
158 send = (fsn_mark->mask & mask); 159 send = (fsn_mark->mask & mask);
159 160
161 if (send && (fsn_mark->mask & FS_EXCL_UNLINK) &&
162 (data_type == FSNOTIFY_EVENT_PATH)) {
163 struct path *path = data;
164
165 if (d_unlinked(path->dentry))
166 send = false;
167 }
168
160 /* find took a reference */ 169 /* find took a reference */
161 fsnotify_put_mark(fsn_mark); 170 fsnotify_put_mark(fsn_mark);
162 171
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)
97 mask = (FS_IN_IGNORED | FS_EVENT_ON_CHILD | FS_UNMOUNT); 97 mask = (FS_IN_IGNORED | FS_EVENT_ON_CHILD | FS_UNMOUNT);
98 98
99 /* mask off the flags used to open the fd */ 99 /* mask off the flags used to open the fd */
100 mask |= (arg & (IN_ALL_EVENTS | IN_ONESHOT)); 100 mask |= (arg & (IN_ALL_EVENTS | IN_ONESHOT | IN_EXCL_UNLINK));
101 101
102 return mask; 102 return mask;
103} 103}
diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h
index b9b3f24ad4fc..4b809fcd4996 100644
--- a/include/linux/fsnotify_backend.h
+++ b/include/linux/fsnotify_backend.h
@@ -44,6 +44,7 @@
44#define FS_OPEN_PERM 0x00010000 /* open event in an permission hook */ 44#define FS_OPEN_PERM 0x00010000 /* open event in an permission hook */
45#define FS_ACCESS_PERM 0x00020000 /* access event in a permissions hook */ 45#define FS_ACCESS_PERM 0x00020000 /* access event in a permissions hook */
46 46
47#define FS_EXCL_UNLINK 0x04000000 /* do not send events if object is unlinked */
47#define FS_IN_ISDIR 0x40000000 /* event occurred against dir */ 48#define FS_IN_ISDIR 0x40000000 /* event occurred against dir */
48#define FS_IN_ONESHOT 0x80000000 /* only send event once */ 49#define FS_IN_ONESHOT 0x80000000 /* only send event once */
49 50
diff --git a/include/linux/inotify.h b/include/linux/inotify.h
index 94d209a1b689..b74f2ef2c368 100644
--- a/include/linux/inotify.h
+++ b/include/linux/inotify.h
@@ -51,6 +51,7 @@ struct inotify_event {
51/* special flags */ 51/* special flags */
52#define IN_ONLYDIR 0x01000000 /* only watch the path if it is a directory */ 52#define IN_ONLYDIR 0x01000000 /* only watch the path if it is a directory */
53#define IN_DONT_FOLLOW 0x02000000 /* don't follow a sym link */ 53#define IN_DONT_FOLLOW 0x02000000 /* don't follow a sym link */
54#define IN_EXCL_UNLINK 0x04000000 /* exclude events on unlinked objects */
54#define IN_MASK_ADD 0x20000000 /* add to the mask of an already existing watch */ 55#define IN_MASK_ADD 0x20000000 /* add to the mask of an already existing watch */
55#define IN_ISDIR 0x40000000 /* event occurred against dir */ 56#define IN_ISDIR 0x40000000 /* event occurred against dir */
56#define IN_ONESHOT 0x80000000 /* only send event once */ 57#define IN_ONESHOT 0x80000000 /* only send event once */