summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn McCutchan <ttb@tentacle.dhs.org>2005-09-07 00:18:02 +0200
committerLinus Torvalds <torvalds@g5.osdl.org>2005-09-08 01:57:39 +0200
commit7ea6040b0eff07d3a9a4e2d248ac137c6ad02d42 (patch)
tree0a7bcce73c623f89cd5e8a97d2da7946da3293e3
parent[PATCH] Consolidate the asm-ppc*/fcntl.h files into asm-powerpc (diff)
downloadlinux-7ea6040b0eff07d3a9a4e2d248ac137c6ad02d42.tar.xz
linux-7ea6040b0eff07d3a9a4e2d248ac137c6ad02d42.zip
[PATCH] inotify: fix event loss on hardlinked files
People have run into a problem when they do this: watch (file1, all_events); watch (file2, some_events); if file2 is a hard link to file1, some events will be missed because by default we replace the mask. The patch below adds a flag IN_MASK_ADD which will cause inotify to add to the existing mask if present. Signed-off-by: John McCutchan <ttb@tentacle.dhs.org> Signed-off-by: Robert Love <rml@novell.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--fs/inotify.c9
-rw-r--r--include/linux/inotify.h1
2 files changed, 9 insertions, 1 deletions
diff --git a/fs/inotify.c b/fs/inotify.c
index 2fd97ef547ff..a37e9fb1da58 100644
--- a/fs/inotify.c
+++ b/fs/inotify.c
@@ -931,6 +931,7 @@ asmlinkage long sys_inotify_add_watch(int fd, const char __user *path, u32 mask)
struct nameidata nd;
struct file *filp;
int ret, fput_needed;
+ int mask_add = 0;
filp = fget_light(fd, &fput_needed);
if (unlikely(!filp))
@@ -953,6 +954,9 @@ asmlinkage long sys_inotify_add_watch(int fd, const char __user *path, u32 mask)
down(&inode->inotify_sem);
down(&dev->sem);
+ if (mask & IN_MASK_ADD)
+ mask_add = 1;
+
/* don't let user-space set invalid bits: we don't want flags set */
mask &= IN_ALL_EVENTS;
if (unlikely(!mask)) {
@@ -966,7 +970,10 @@ asmlinkage long sys_inotify_add_watch(int fd, const char __user *path, u32 mask)
*/
old = inode_find_dev(inode, dev);
if (unlikely(old)) {
- old->mask = mask;
+ if (mask_add)
+ old->mask |= mask;
+ else
+ old->mask = mask;
ret = old->wd;
goto out;
}
diff --git a/include/linux/inotify.h b/include/linux/inotify.h
index 93bb3afe646b..ee5b239092ed 100644
--- a/include/linux/inotify.h
+++ b/include/linux/inotify.h
@@ -47,6 +47,7 @@ struct inotify_event {
#define IN_MOVE (IN_MOVED_FROM | IN_MOVED_TO) /* moves */
/* special flags */
+#define IN_MASK_ADD 0x20000000 /* add to the mask of an already existing watch */
#define IN_ISDIR 0x40000000 /* event occurred against dir */
#define IN_ONESHOT 0x80000000 /* only send event once */