--- zzzz-none-000/linux-2.6.39.4/include/linux/fsnotify.h 2011-08-03 19:43:28.000000000 +0000 +++ puma6-arm-6490-729/linux-2.6.39.4/include/linux/fsnotify.h 2021-11-10 13:23:10.000000000 +0000 @@ -33,6 +33,20 @@ 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) { @@ -56,6 +70,11 @@ 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); } @@ -79,6 +98,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 */ @@ -91,17 +111,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, old_dir, 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, new_dir, FSNOTIFY_EVENT_INODE, new_name, fs_cookie); + __fsnotify_update_child_dentry_flags(new_dir); if (target) fsnotify_link_count(target); @@ -109,6 +139,9 @@ if (source) fsnotify(source, FS_MOVE_SELF, moved->d_inode, FSNOTIFY_EVENT_INODE, NULL, 0); audit_inode_child(moved, new_dir); + + if (old_dir_dentry) + dput(old_dir_dentry); } /* @@ -138,6 +171,7 @@ mask |= FS_ISDIR; fsnotify_parent(NULL, dentry, mask); + fsnotify_parent_recursive(NULL, dentry, NULL, NULL, mask, 0); } /* @@ -156,6 +190,7 @@ { audit_inode_child(dentry, inode); + 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); } @@ -169,6 +204,7 @@ fsnotify_link_count(inode); audit_inode_child(new_dentry, dir); + 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); } @@ -182,6 +218,7 @@ audit_inode_child(dentry, inode); + fsnotify_parent_recursive(NULL, dentry, NULL, NULL, mask, 0); fsnotify(inode, mask, d_inode, FSNOTIFY_EVENT_INODE, dentry->d_name.name, 0); } @@ -199,6 +236,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 +255,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); } } @@ -234,6 +273,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); } @@ -252,6 +292,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); } } @@ -268,6 +309,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); } @@ -303,6 +345,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); } }