--- zzzz-none-000/linux-4.4.60/include/linux/fsnotify_backend.h 2017-04-08 07:53:53.000000000 +0000 +++ scorpion-1750e-727/linux-4.4.60/include/linux/fsnotify_backend.h 2021-02-04 17:41:59.000000000 +0000 @@ -53,6 +53,11 @@ /* This inode cares about things that happen to its children. Always set for * dnotify and inotify. */ #define FS_EVENT_ON_CHILD 0x08000000 +/** + * This inode cares about things that happen to its children and their children. + * May be configured for inotify by using the IN_RECURSIVE flag. + */ +#define FS_EVENT_ON_CHILD_RECURSIVLY 0x10000000 /* This is a list of all events that may get sent to a parernt based on fs event * happening to inodes inside that directory */ @@ -61,6 +66,14 @@ FS_MOVED_FROM | FS_MOVED_TO | FS_CREATE |\ FS_DELETE | FS_OPEN_PERM | FS_ACCESS_PERM) +/** + * This is a list of all events that are allowed to propagate recursivly upwards + * the dentry tree + */ +#define FS_EVENTS_POSS_ON_CHILD_RECURSIVLY (FS_CLOSE_WRITE | FS_CLOSE_NOWRITE |\ + FS_MOVED_FROM | FS_MOVED_TO | FS_CREATE |\ + FS_DELETE) + #define FS_MOVE (FS_MOVED_FROM | FS_MOVED_TO) #define ALL_FSNOTIFY_PERM_EVENTS (FS_OPEN_PERM | FS_ACCESS_PERM) @@ -72,7 +85,7 @@ FS_UNMOUNT | FS_Q_OVERFLOW | FS_IN_IGNORED | \ FS_OPEN_PERM | FS_ACCESS_PERM | FS_EXCL_UNLINK | \ FS_ISDIR | FS_IN_ONESHOT | FS_DN_RENAME | \ - FS_DN_MULTISHOT | FS_EVENT_ON_CHILD) + FS_DN_MULTISHOT | FS_EVENT_ON_CHILD | FS_EVENT_ON_CHILD_RECURSIVLY) struct fsnotify_group; struct fsnotify_event; @@ -263,6 +276,16 @@ return inode->i_fsnotify_mask & FS_EVENTS_POSS_ON_CHILD; } +static inline int fsnotify_inode_watches_children_recursivly(struct inode *inode) +{ + /* FS_EVENT_ON_CHILD is set if the inode may care */ + if (!(inode->i_fsnotify_mask & FS_EVENT_ON_CHILD_RECURSIVLY)) + return 0; + /* this inode might care about child events, does it care about the + * specific set of events that can happen on a child? */ + return inode->i_fsnotify_mask & FS_EVENTS_POSS_ON_CHILD_RECURSIVLY; +} + /* * Update the dentry with a flag indicating the interest of its parent to receive * filesystem events when those events happens to this dentry->d_inode. @@ -285,6 +308,12 @@ dentry->d_flags |= DCACHE_FSNOTIFY_PARENT_WATCHED; else dentry->d_flags &= ~DCACHE_FSNOTIFY_PARENT_WATCHED; + + if (parent->d_flags & DCACHE_FSNOTIFY_PARENT_WATCHED_RECURSIVLY + || (parent->d_inode && fsnotify_inode_watches_children_recursivly(parent->d_inode))) + dentry->d_flags |= DCACHE_FSNOTIFY_PARENT_WATCHED_RECURSIVLY; + else + dentry->d_flags &= ~DCACHE_FSNOTIFY_PARENT_WATCHED_RECURSIVLY; } /* @@ -409,6 +438,15 @@ #endif /* CONFIG_FSNOTIFY */ +#if defined(CONFIG_FSNOTIFY) && defined(CONFIG_FSNOTIFY_RECURSIVE) +extern int __fsnotify_parent_recursive(struct path *path, struct dentry *dentry, struct dentry *first_parent, const char* name, __u32 mask, u32 cookie); +#else +static inline int __fsnotify_parent_recursive(struct path *path, struct dentry *dentry, struct dentry *first_parent, const char *name, __u32 mask, u32 cookie) +{ + return 0; +} +#endif + #endif /* __KERNEL __ */ #endif /* __LINUX_FSNOTIFY_BACKEND_H */