Lines Matching +full:parent +full:- +full:child
1 // SPDX-License-Identifier: GPL-2.0-or-later
32 * fsnotify_unmount_inodes - an sb is unmounting. handle any watched inodes.
36 * concurrent modifiers. We temporarily drop sb->s_inode_list_lock and CAN block.
42 spin_lock(&sb->s_inode_list_lock); in fsnotify_unmount_inodes()
43 list_for_each_entry(inode, &sb->s_inodes, i_sb_list) { in fsnotify_unmount_inodes()
49 spin_lock(&inode->i_lock); in fsnotify_unmount_inodes()
50 if (inode->i_state & (I_FREEING|I_WILL_FREE|I_NEW)) { in fsnotify_unmount_inodes()
51 spin_unlock(&inode->i_lock); in fsnotify_unmount_inodes()
64 if (!atomic_read(&inode->i_count)) { in fsnotify_unmount_inodes()
65 spin_unlock(&inode->i_lock); in fsnotify_unmount_inodes()
70 spin_unlock(&inode->i_lock); in fsnotify_unmount_inodes()
71 spin_unlock(&sb->s_inode_list_lock); in fsnotify_unmount_inodes()
84 spin_lock(&sb->s_inode_list_lock); in fsnotify_unmount_inodes()
86 spin_unlock(&sb->s_inode_list_lock); in fsnotify_unmount_inodes()
91 wait_var_event(&sb->s_fsnotify_inode_refs, in fsnotify_unmount_inodes()
92 !atomic_long_read(&sb->s_fsnotify_inode_refs)); in fsnotify_unmount_inodes()
104 * on a child we run all of our children and set a dentry flag saying that the
105 * parent cares. Thus when an event happens on a child it can quickly tell if
106 * if there is a need to find a parent and send the event to the parent.
113 if (!S_ISDIR(inode->i_mode)) in __fsnotify_update_child_dentry_flags()
119 spin_lock(&inode->i_lock); in __fsnotify_update_child_dentry_flags()
122 hlist_for_each_entry(alias, &inode->i_dentry, d_u.d_alias) { in __fsnotify_update_child_dentry_flags()
123 struct dentry *child; in __fsnotify_update_child_dentry_flags() local
126 * d_flags to indicate parental interest (their parent is the in __fsnotify_update_child_dentry_flags()
128 spin_lock(&alias->d_lock); in __fsnotify_update_child_dentry_flags()
129 list_for_each_entry(child, &alias->d_subdirs, d_child) { in __fsnotify_update_child_dentry_flags()
130 if (!child->d_inode) in __fsnotify_update_child_dentry_flags()
133 spin_lock_nested(&child->d_lock, DENTRY_D_LOCK_NESTED); in __fsnotify_update_child_dentry_flags()
135 child->d_flags |= DCACHE_FSNOTIFY_PARENT_WATCHED; in __fsnotify_update_child_dentry_flags()
137 child->d_flags &= ~DCACHE_FSNOTIFY_PARENT_WATCHED; in __fsnotify_update_child_dentry_flags()
138 spin_unlock(&child->d_lock); in __fsnotify_update_child_dentry_flags()
140 spin_unlock(&alias->d_lock); in __fsnotify_update_child_dentry_flags()
142 spin_unlock(&inode->i_lock); in __fsnotify_update_child_dentry_flags()
145 /* Are inode/sb/mount interested in parent and name info with this event? */
151 /* We only send parent/name to inode/sb/mount for events on non-dir */ in fsnotify_event_needs_parent()
156 * All events that are possible on child can also may be reported with in fsnotify_event_needs_parent()
157 * parent/name info to inode/sb/mount. Otherwise, a watching parent in fsnotify_event_needs_parent()
162 /* Did either inode/sb/mount subscribe for events with parent/name? */ in fsnotify_event_needs_parent()
163 marks_mask |= fsnotify_parent_needed_mask(inode->i_fsnotify_mask); in fsnotify_event_needs_parent()
164 marks_mask |= fsnotify_parent_needed_mask(inode->i_sb->s_fsnotify_mask); in fsnotify_event_needs_parent()
166 marks_mask |= fsnotify_parent_needed_mask(mnt->mnt_fsnotify_mask); in fsnotify_event_needs_parent()
168 /* Did they subscribe for this event with parent/name info? */ in fsnotify_event_needs_parent()
173 * Notify this dentry's parent about a child's events with child name info
174 * if parent is watching or if inode/sb/mount are interested in events with
175 * parent and name info.
177 * Notify only the child without name info if parent is not watching and
178 * inode/sb/mount are not interested in events with parent and name info.
184 struct mount *mnt = path ? real_mount(path->mnt) : NULL; in __fsnotify_parent()
186 struct dentry *parent; in __fsnotify_parent() local
187 bool parent_watched = dentry->d_flags & DCACHE_FSNOTIFY_PARENT_WATCHED; in __fsnotify_parent()
196 * Do inode/sb/mount care about parent and name info on non-dir? in __fsnotify_parent()
199 if (!inode->i_fsnotify_marks && !inode->i_sb->s_fsnotify_marks && in __fsnotify_parent()
200 (!mnt || !mnt->mnt_fsnotify_marks) && !parent_watched) in __fsnotify_parent()
203 parent = NULL; in __fsnotify_parent()
208 /* Does parent inode care about events on children? */ in __fsnotify_parent()
209 parent = dget_parent(dentry); in __fsnotify_parent()
210 p_inode = parent->d_inode; in __fsnotify_parent()
216 * Include parent/name in notification either if some notification in __fsnotify_parent()
217 * groups require parent info or the parent is interested in this event. in __fsnotify_parent()
221 /* When notifying parent, child should be passed as data */ in __fsnotify_parent()
224 /* Notify both parent and child with child name info */ in __fsnotify_parent()
236 dput(parent); in __fsnotify_parent()
250 const struct fsnotify_ops *ops = group->ops; in fsnotify_handle_inode_event()
252 if (WARN_ON_ONCE(!ops->handle_inode_event)) in fsnotify_handle_inode_event()
255 if ((inode_mark->mask & FS_EXCL_UNLINK) && in fsnotify_handle_inode_event()
256 path && d_unlinked(path->dentry)) in fsnotify_handle_inode_event()
260 if (!(mask & inode_mark->mask & ALL_FSNOTIFY_EVENTS)) in fsnotify_handle_inode_event()
263 return ops->handle_inode_event(inode_mark, mask, inode, dir, name, cookie); in fsnotify_handle_inode_event()
281 * parent_mark indicates that the parent inode is watching in fsnotify_handle_event()
283 * possible on child. But is *this mark* watching children and in fsnotify_handle_event()
286 if (parent_mark->mask & FS_EVENT_ON_CHILD) { in fsnotify_handle_event()
298 * Some events can be sent on both parent dir and child marks in fsnotify_handle_event()
299 * (e.g. FS_ATTRIB). If both parent dir and child are in fsnotify_handle_event()
300 * watching, report the event once to parent dir with name (if in fsnotify_handle_event()
301 * interested) and once to child without name (if interested). in fsnotify_handle_event()
302 * The child watcher is expecting an event without a file name in fsnotify_handle_event()
325 if (WARN_ON(!iter_info->report_mask)) in send_to_group()
333 mark = iter_info->marks[type]; in send_to_group()
335 !(mark->flags & FSNOTIFY_MARK_FLAG_IGNORED_SURV_MODIFY)) in send_to_group()
336 mark->ignored_mask = 0; in send_to_group()
343 mark = iter_info->marks[type]; in send_to_group()
346 group = mark->group; in send_to_group()
347 marks_mask |= mark->mask; in send_to_group()
348 marks_ignored_mask |= mark->ignored_mask; in send_to_group()
359 if (group->ops->handle_event) { in send_to_group()
360 return group->ops->handle_event(group, mask, data, data_type, dir, in send_to_group()
375 node = srcu_dereference(conn->list.first, &fsnotify_mark_srcu); in fsnotify_first_mark()
385 node = srcu_dereference(mark->obj_list.next, in fsnotify_next_mark()
406 mark = iter_info->marks[type]; in fsnotify_iter_select_report_types()
408 fsnotify_compare_groups(max_prio_group, mark->group) > 0) in fsnotify_iter_select_report_types()
409 max_prio_group = mark->group; in fsnotify_iter_select_report_types()
416 iter_info->report_mask = 0; in fsnotify_iter_select_report_types()
418 mark = iter_info->marks[type]; in fsnotify_iter_select_report_types()
420 fsnotify_compare_groups(max_prio_group, mark->group) == 0) in fsnotify_iter_select_report_types()
424 return iter_info->report_mask; in fsnotify_iter_select_report_types()
437 iter_info->marks[type] = in fsnotify_iter_next()
438 fsnotify_next_mark(iter_info->marks[type]); in fsnotify_iter_next()
443 * fsnotify - This is the main call to fsnotify.
453 * @dir: optional directory associated with event -
457 * @inode: optional inode associated with event -
458 * either @dir or @inode must be non-NULL.
459 * if both are non-NULL event may be reported to both.
469 struct inode *parent = NULL; in fsnotify() local
474 mnt = real_mount(path->mnt); in fsnotify()
477 /* Dirent event - report on TYPE_INODE to dir */ in fsnotify()
481 * Event on child - report on TYPE_PARENT to dir if it is in fsnotify()
482 * watching children and on TYPE_INODE to child. in fsnotify()
484 parent = dir; in fsnotify()
486 sb = inode->i_sb; in fsnotify()
495 if (!sb->s_fsnotify_marks && in fsnotify()
496 (!mnt || !mnt->mnt_fsnotify_marks) && in fsnotify()
497 (!inode || !inode->i_fsnotify_marks) && in fsnotify()
498 (!parent || !parent->i_fsnotify_marks)) in fsnotify()
501 marks_mask = sb->s_fsnotify_mask; in fsnotify()
503 marks_mask |= mnt->mnt_fsnotify_mask; in fsnotify()
505 marks_mask |= inode->i_fsnotify_mask; in fsnotify()
506 if (parent) in fsnotify()
507 marks_mask |= parent->i_fsnotify_mask; in fsnotify()
521 fsnotify_first_mark(&sb->s_fsnotify_marks); in fsnotify()
524 fsnotify_first_mark(&mnt->mnt_fsnotify_marks); in fsnotify()
528 fsnotify_first_mark(&inode->i_fsnotify_marks); in fsnotify()
530 if (parent) { in fsnotify()
532 fsnotify_first_mark(&parent->i_fsnotify_marks); in fsnotify()