Skip to content

Commit 8c1934c

Browse files
committed
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>
1 parent 611da04 commit 8c1934c

File tree

4 files changed

+12
-1
lines changed

4 files changed

+12
-1
lines changed

fs/notify/inotify/inotify_fsnotify.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
* General Public License for more details.
2323
*/
2424

25+
#include <linux/dcache.h> /* d_unlinked */
2526
#include <linux/fs.h> /* struct inode */
2627
#include <linux/fsnotify_backend.h>
2728
#include <linux/inotify.h>
@@ -157,6 +158,14 @@ static bool inotify_should_send_event(struct fsnotify_group *group, struct inode
157158
mask = (mask & ~FS_EVENT_ON_CHILD);
158159
send = (fsn_mark->mask & mask);
159160

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+
160169
/* find took a reference */
161170
fsnotify_put_mark(fsn_mark);
162171

fs/notify/inotify/inotify_user.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ static inline __u32 inotify_arg_to_mask(u32 arg)
9797
mask = (FS_IN_IGNORED | FS_EVENT_ON_CHILD | FS_UNMOUNT);
9898

9999
/* 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));
101101

102102
return mask;
103103
}

include/linux/fsnotify_backend.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
#define FS_OPEN_PERM 0x00010000 /* open event in an permission hook */
4545
#define FS_ACCESS_PERM 0x00020000 /* access event in a permissions hook */
4646

47+
#define FS_EXCL_UNLINK 0x04000000 /* do not send events if object is unlinked */
4748
#define FS_IN_ISDIR 0x40000000 /* event occurred against dir */
4849
#define FS_IN_ONESHOT 0x80000000 /* only send event once */
4950

include/linux/inotify.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ struct inotify_event {
5151
/* special flags */
5252
#define IN_ONLYDIR 0x01000000 /* only watch the path if it is a directory */
5353
#define IN_DONT_FOLLOW 0x02000000 /* don't follow a sym link */
54+
#define IN_EXCL_UNLINK 0x04000000 /* exclude events on unlinked objects */
5455
#define IN_MASK_ADD 0x20000000 /* add to the mask of an already existing watch */
5556
#define IN_ISDIR 0x40000000 /* event occurred against dir */
5657
#define IN_ONESHOT 0x80000000 /* only send event once */

0 commit comments

Comments
 (0)