--- zzzz-none-000/linux-4.9.276/include/linux/fsnotify.h 2021-07-20 14:21:16.000000000 +0000 +++ falcon-5530-750/linux-4.9.276/include/linux/fsnotify.h 2023-04-05 08:19:02.000000000 +0000 @@ -25,6 +25,16 @@ return __fsnotify_parent(path, dentry, mask); } + +/* Notify this dentry's parent about a child's events. */ +static inline int fsnotify_parent_recursive(struct path *path, struct dentry *dentry, struct dentry *first_parent, const char *name, __u32 mask, u32 fs_cookie) +{ + if (!dentry) + dentry = path->dentry; + + return __fsnotify_parent_recursive(path, dentry, first_parent, name, mask, fs_cookie); +} + /* simple call site for access decisions */ static inline int fsnotify_perm(struct file *file, int mask) { @@ -52,6 +62,10 @@ if (ret) return ret; + ret = fsnotify_parent_recursive(path, NULL, NULL, NULL, fsnotify_mask, 0); + if (ret) + return ret; + return fsnotify(inode, fsnotify_mask, path, FSNOTIFY_EVENT_PATH, NULL, 0); } @@ -63,6 +77,7 @@ fsnotify(inode, FS_ATTRIB, inode, FSNOTIFY_EVENT_INODE, NULL, 0); } +extern void __fsnotify_update_child_dentry_flags(struct inode *inode); /* * fsnotify_move - file old_name at old_dir was moved to new_name at new_dir */ @@ -75,19 +90,27 @@ __u32 old_dir_mask = (FS_EVENT_ON_CHILD | FS_MOVED_FROM); __u32 new_dir_mask = (FS_EVENT_ON_CHILD | FS_MOVED_TO); const unsigned char *new_name = moved->d_name.name; + struct dentry *old_dir_dentry; - if (old_dir == new_dir) + if (old_dir == new_dir) { old_dir_mask |= FS_DN_RENAME; + old_dir_dentry = NULL; + } else { + old_dir_dentry = d_find_any_alias(old_dir); + } if (isdir) { old_dir_mask |= FS_ISDIR; new_dir_mask |= FS_ISDIR; } + fsnotify_parent_recursive(NULL, moved, old_dir_dentry, old_name, old_dir_mask, fs_cookie); fsnotify(old_dir, old_dir_mask, source, FSNOTIFY_EVENT_INODE, old_name, fs_cookie); + fsnotify_parent_recursive(NULL, moved, NULL, new_name, new_dir_mask, fs_cookie); fsnotify(new_dir, new_dir_mask, source, FSNOTIFY_EVENT_INODE, new_name, fs_cookie); + __fsnotify_update_child_dentry_flags(new_dir); if (target) fsnotify_link_count(target); @@ -95,6 +118,9 @@ if (source) fsnotify(source, FS_MOVE_SELF, moved->d_inode, FSNOTIFY_EVENT_INODE, NULL, 0); audit_inode_child(new_dir, moved, AUDIT_TYPE_CHILD_CREATE); + + if (old_dir_dentry) + dput(old_dir_dentry); } /* @@ -124,6 +150,7 @@ mask |= FS_ISDIR; fsnotify_parent(NULL, dentry, mask); + fsnotify_parent_recursive(NULL, dentry, NULL, NULL, mask, 0); } /* @@ -142,6 +169,7 @@ { audit_inode_child(inode, dentry, AUDIT_TYPE_CHILD_CREATE); + fsnotify_parent_recursive(NULL, dentry, NULL, NULL, FS_CREATE, 0); fsnotify(inode, FS_CREATE, dentry->d_inode, FSNOTIFY_EVENT_INODE, dentry->d_name.name, 0); } @@ -155,6 +183,7 @@ fsnotify_link_count(inode); audit_inode_child(dir, new_dentry, AUDIT_TYPE_CHILD_CREATE); + fsnotify_parent_recursive(NULL, new_dentry, NULL, NULL, FS_CREATE, 0); fsnotify(dir, FS_CREATE, inode, FSNOTIFY_EVENT_INODE, new_dentry->d_name.name, 0); } @@ -168,6 +197,7 @@ audit_inode_child(inode, dentry, AUDIT_TYPE_CHILD_CREATE); + fsnotify_parent_recursive(NULL, dentry, NULL, NULL, mask, 0); fsnotify(inode, mask, d_inode, FSNOTIFY_EVENT_INODE, dentry->d_name.name, 0); } @@ -185,6 +215,7 @@ if (!(file->f_mode & FMODE_NONOTIFY)) { fsnotify_parent(path, NULL, mask); + fsnotify_parent_recursive(path, NULL, NULL, NULL, mask, 0); fsnotify(inode, mask, path, FSNOTIFY_EVENT_PATH, NULL, 0); } } @@ -203,6 +234,7 @@ if (!(file->f_mode & FMODE_NONOTIFY)) { fsnotify_parent(path, NULL, mask); + fsnotify_parent_recursive(path, NULL, NULL, NULL, mask, 0); fsnotify(inode, mask, path, FSNOTIFY_EVENT_PATH, NULL, 0); } } @@ -220,6 +252,7 @@ mask |= FS_ISDIR; fsnotify_parent(path, NULL, mask); + fsnotify_parent_recursive(path, NULL, NULL, NULL, mask, 0); fsnotify(inode, mask, path, FSNOTIFY_EVENT_PATH, NULL, 0); } @@ -238,6 +271,7 @@ if (!(file->f_mode & FMODE_NONOTIFY)) { fsnotify_parent(path, NULL, mask); + fsnotify_parent_recursive(path, NULL, NULL, NULL, mask, 0); fsnotify(inode, mask, path, FSNOTIFY_EVENT_PATH, NULL, 0); } } @@ -254,6 +288,7 @@ mask |= FS_ISDIR; fsnotify_parent(NULL, dentry, mask); + fsnotify_parent_recursive(NULL, dentry, NULL, NULL, mask, 0); fsnotify(inode, mask, inode, FSNOTIFY_EVENT_INODE, NULL, 0); } @@ -289,6 +324,7 @@ mask |= FS_ISDIR; fsnotify_parent(NULL, dentry, mask); + fsnotify_parent_recursive(NULL, dentry, NULL, NULL, mask, 0); fsnotify(inode, mask, inode, FSNOTIFY_EVENT_INODE, NULL, 0); } }