--- zzzz-none-000/linux-4.19.183/include/linux/fsnotify.h 2021-03-24 10:07:39.000000000 +0000 +++ bcm63-7530ax-756/linux-4.19.183/include/linux/fsnotify.h 2023-06-28 08:54:20.000000000 +0000 @@ -26,6 +26,16 @@ return __fsnotify_parent(path, dentry, mask); } + +/* Notify this dentry's parent about a child's events. */ +static inline int fsnotify_parent_recursive(const struct path *path, struct dentry *dentry, struct dentry *first_parent, const unsigned 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) { @@ -49,6 +59,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); } @@ -60,6 +74,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 */ @@ -72,19 +87,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); @@ -92,6 +115,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); } /* @@ -121,6 +147,7 @@ mask |= FS_ISDIR; fsnotify_parent(NULL, dentry, mask); + fsnotify_parent_recursive(NULL, dentry, NULL, NULL, mask, 0); } /* @@ -139,6 +166,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); } @@ -152,6 +180,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); } @@ -165,6 +194,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); } @@ -182,6 +212,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); } } @@ -200,6 +231,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); } } @@ -217,6 +249,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); } @@ -235,6 +268,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); } } @@ -251,6 +285,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); } @@ -286,6 +321,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); } }