From: Jan Kara Currently, no notification event has been sent when inode's link count changed. This is inconvenient for the application in some cases: Suppose you have the following directory structure foo/test bar/ and you watch test. If someone does "mv foo/test bar/", you get event IN_MOVE_SELF and you know something has happened with the file "test". However if someone does "ln foo/test bar/test" and "rm foo/test" you get no inotify event for the file "test" (only directories "foo" and "bar" receive events). Furthermore it could be argued that link count belongs to file's metadata and thus IN_ATTRIB should be sent when it changes. The following patch implements sending of IN_ATTRIB inotify events when link count of the inode changes, i.e., when a hardlink to the inode is created or when it is removed. This event is sent in addition to all the events sent so far. In particular, when a last link to a file is removed, IN_ATTRIB event is sent in addition to IN_DELETE_SELF event. Signed-off-by: Jan Kara Acked-by: Morten Welinder Cc: Robert Love Cc: John McCutchan Signed-off-by: Andrew Morton --- fs/namei.c | 3 ++- include/linux/fsnotify.h | 20 ++++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff -puN fs/namei.c~inotify-send-in_attrib-events-when-link-count-changes fs/namei.c --- a/fs/namei.c~inotify-send-in_attrib-events-when-link-count-changes +++ a/fs/namei.c @@ -2189,6 +2189,7 @@ int vfs_unlink(struct inode *dir, struct /* We don't d_delete() NFS sillyrenamed files--they still exist. */ if (!error && !(dentry->d_flags & DCACHE_NFSFS_RENAMED)) { + fsnotify_link_count(dentry->d_inode); d_delete(dentry); } @@ -2361,7 +2362,7 @@ int vfs_link(struct dentry *old_dentry, error = dir->i_op->link(old_dentry, dir, new_dentry); mutex_unlock(&old_dentry->d_inode->i_mutex); if (!error) - fsnotify_create(dir, new_dentry); + fsnotify_link(dir, new_dentry); return error; } diff -puN include/linux/fsnotify.h~inotify-send-in_attrib-events-when-link-count-changes include/linux/fsnotify.h --- a/include/linux/fsnotify.h~inotify-send-in_attrib-events-when-link-count-changes +++ a/include/linux/fsnotify.h @@ -92,6 +92,14 @@ static inline void fsnotify_inoderemove( } /* + * fsnotify_link_count - inode's link count changed + */ +static inline void fsnotify_link_count(struct inode *inode) +{ + inotify_inode_queue_event(inode, IN_ATTRIB, 0, NULL, NULL); +} + +/* * fsnotify_create - 'name' was linked in */ static inline void fsnotify_create(struct inode *inode, struct dentry *dentry) @@ -103,6 +111,18 @@ static inline void fsnotify_create(struc } /* + * fsnotify_link - new hardlink in 'inode' directory + */ +static inline void fsnotify_link(struct inode *inode, struct dentry *new_dentry) +{ + inode_dir_notify(inode, DN_CREATE); + inotify_inode_queue_event(inode, IN_CREATE, 0, new_dentry->d_name.name, + new_dentry->d_inode); + fsnotify_link_count(new_dentry->d_inode); + audit_inode_child(new_dentry->d_name.name, new_dentry, inode); +} + +/* * fsnotify_mkdir - directory 'name' was created */ static inline void fsnotify_mkdir(struct inode *inode, struct dentry *dentry) _