--- zzzz-none-000/linux-2.6.39.4/include/linux/fsnotify_backend.h 2011-08-03 19:43:28.000000000 +0000 +++ puma6-atom-6490-729/linux-2.6.39.4/include/linux/fsnotify_backend.h 2021-11-10 13:38:17.000000000 +0000 @@ -54,6 +54,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 */ @@ -62,18 +67,25 @@ FS_MOVED_FROM | FS_MOVED_TO | FS_CREATE |\ FS_DELETE) +/** + * 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) -#define ALL_FSNOTIFY_EVENTS (FS_ACCESS | FS_MODIFY | FS_ATTRIB | \ - FS_CLOSE_WRITE | FS_CLOSE_NOWRITE | FS_OPEN | \ - FS_MOVED_FROM | FS_MOVED_TO | FS_CREATE | \ - FS_DELETE | FS_DELETE_SELF | FS_MOVE_SELF | \ - 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) +#define ALL_FSNOTIFY_EVENTS \ + (FS_ACCESS | FS_MODIFY | FS_ATTRIB | FS_CLOSE_WRITE | \ + FS_CLOSE_NOWRITE | FS_OPEN | FS_MOVED_FROM | FS_MOVED_TO | \ + FS_CREATE | FS_DELETE | FS_DELETE_SELF | FS_MOVE_SELF | 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_EVENT_ON_CHILD_RECURSIVLY) struct fsnotify_group; struct fsnotify_event; @@ -321,6 +333,21 @@ 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. @@ -343,6 +370,13 @@ 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; } /* @@ -465,6 +499,22 @@ #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 */