From: John McCutchan 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 Signed-off-by: Robert Love Signed-off-by: Andrew Morton --- fs/inotify.c | 9 ++++++++- include/linux/inotify.h | 1 + 2 files changed, 9 insertions(+), 1 deletion(-) diff -puN fs/inotify.c~inotify-fix-event-loss-on-hardlinked-files fs/inotify.c --- 25/fs/inotify.c~inotify-fix-event-loss-on-hardlinked-files Wed Aug 31 13:14:45 2005 +++ 25-akpm/fs/inotify.c Wed Aug 31 13:14:45 2005 @@ -925,6 +925,7 @@ asmlinkage long sys_inotify_add_watch(in struct nameidata nd; struct file *filp; int ret, fput_needed; + int mask_add = 0; filp = fget_light(fd, &fput_needed); if (unlikely(!filp)) @@ -947,6 +948,9 @@ asmlinkage long sys_inotify_add_watch(in 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)) { @@ -960,7 +964,10 @@ asmlinkage long sys_inotify_add_watch(in */ 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 -puN include/linux/inotify.h~inotify-fix-event-loss-on-hardlinked-files include/linux/inotify.h --- 25/include/linux/inotify.h~inotify-fix-event-loss-on-hardlinked-files Wed Aug 31 13:14:45 2005 +++ 25-akpm/include/linux/inotify.h Wed Aug 31 13:14:45 2005 @@ -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 */ _