--- zzzz-none-000/linux-3.10.107/include/linux/fsnotify.h 2017-06-27 09:49:32.000000000 +0000 +++ scorpion-7490-727/linux-3.10.107/include/linux/fsnotify.h 2021-02-04 17:41:59.000000000 +0000 @@ -34,11 +34,21 @@ 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) { struct path *path = &file->f_path; - struct inode *inode = path->dentry->d_inode; + struct inode *inode = file_inode(file); __u32 fsnotify_mask = 0; int ret; @@ -57,6 +67,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); } @@ -80,6 +94,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 */ @@ -92,19 +107,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); @@ -112,6 +135,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); } /* @@ -141,6 +167,7 @@ mask |= FS_ISDIR; fsnotify_parent(NULL, dentry, mask); + fsnotify_parent_recursive(NULL, dentry, NULL, NULL, mask, 0); } /* @@ -159,6 +186,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); } @@ -172,6 +200,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); } @@ -185,6 +214,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); } @@ -194,7 +224,7 @@ static inline void fsnotify_access(struct file *file) { struct path *path = &file->f_path; - struct inode *inode = path->dentry->d_inode; + struct inode *inode = file_inode(file); __u32 mask = FS_ACCESS; if (S_ISDIR(inode->i_mode)) @@ -202,6 +232,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); } } @@ -212,7 +243,7 @@ static inline void fsnotify_modify(struct file *file) { struct path *path = &file->f_path; - struct inode *inode = path->dentry->d_inode; + struct inode *inode = file_inode(file); __u32 mask = FS_MODIFY; if (S_ISDIR(inode->i_mode)) @@ -220,6 +251,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); } } @@ -230,13 +262,14 @@ static inline void fsnotify_open(struct file *file) { struct path *path = &file->f_path; - struct inode *inode = path->dentry->d_inode; + struct inode *inode = file_inode(file); __u32 mask = FS_OPEN; if (S_ISDIR(inode->i_mode)) 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); } @@ -255,6 +288,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); } } @@ -271,6 +305,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); } @@ -306,39 +341,9 @@ 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); } } -#if defined(CONFIG_FSNOTIFY) /* notify helpers */ - -/* - * fsnotify_oldname_init - save off the old filename before we change it - */ -static inline const unsigned char *fsnotify_oldname_init(const unsigned char *name) -{ - return kstrdup(name, GFP_KERNEL); -} - -/* - * fsnotify_oldname_free - free the name we got from fsnotify_oldname_init - */ -static inline void fsnotify_oldname_free(const unsigned char *old_name) -{ - kfree(old_name); -} - -#else /* CONFIG_FSNOTIFY */ - -static inline const char *fsnotify_oldname_init(const unsigned char *name) -{ - return NULL; -} - -static inline void fsnotify_oldname_free(const unsigned char *old_name) -{ -} - -#endif /* CONFIG_FSNOTIFY */ - #endif /* _LINUX_FS_NOTIFY_H */