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()
155 /* Did either inode/sb/mount subscribe for events with parent/name? */ in fsnotify_event_needs_parent()
156 marks_mask |= fsnotify_parent_needed_mask(inode->i_fsnotify_mask); in fsnotify_event_needs_parent()
157 marks_mask |= fsnotify_parent_needed_mask(inode->i_sb->s_fsnotify_mask); in fsnotify_event_needs_parent()
159 marks_mask |= fsnotify_parent_needed_mask(mnt->mnt_fsnotify_mask); in fsnotify_event_needs_parent()
161 /* Did they subscribe for this event with parent/name info? */ in fsnotify_event_needs_parent()
166 * Notify this dentry's parent about a child's events with child name info
167 * if parent is watching or if inode/sb/mount are interested in events with
168 * parent and name info.
170 * Notify only the child without name info if parent is not watching and
171 * inode/sb/mount are not interested in events with parent and name info.
177 struct mount *mnt = path ? real_mount(path->mnt) : NULL; in __fsnotify_parent()
179 struct dentry *parent; in __fsnotify_parent() local
180 bool parent_watched = dentry->d_flags & DCACHE_FSNOTIFY_PARENT_WATCHED; in __fsnotify_parent()
189 * Do inode/sb/mount care about parent and name info on non-dir? in __fsnotify_parent()
192 if (!inode->i_fsnotify_marks && !inode->i_sb->s_fsnotify_marks && in __fsnotify_parent()
193 (!mnt || !mnt->mnt_fsnotify_marks) && !parent_watched) in __fsnotify_parent()
196 parent = NULL; in __fsnotify_parent()
201 /* Does parent inode care about events on children? */ in __fsnotify_parent()
202 parent = dget_parent(dentry); in __fsnotify_parent()
203 p_inode = parent->d_inode; in __fsnotify_parent()
209 * Include parent/name in notification either if some notification in __fsnotify_parent()
210 * groups require parent info or the parent is interested in this event. in __fsnotify_parent()
214 /* When notifying parent, child should be passed as data */ in __fsnotify_parent()
217 /* Notify both parent and child with child name info */ in __fsnotify_parent()
229 dput(parent); in __fsnotify_parent()
243 const struct fsnotify_ops *ops = group->ops; in fsnotify_handle_event()
246 if (WARN_ON_ONCE(!ops->handle_inode_event)) in fsnotify_handle_event()
254 * An event can be sent on child mark iterator instead of inode mark in fsnotify_handle_event()
256 * and have marks on both parent and child. We can simplify this case. in fsnotify_handle_event()
265 ret = ops->handle_inode_event(inode_mark, mask, inode, dir, name); in fsnotify_handle_event()
270 * Some events can be sent on both parent dir and child marks in fsnotify_handle_event()
271 * (e.g. FS_ATTRIB). If both parent dir and child are watching, in fsnotify_handle_event()
272 * report the event once to parent dir with name and once to child in fsnotify_handle_event()
275 return ops->handle_inode_event(child_mark, mask, inode, NULL, NULL); in fsnotify_handle_event()
289 if (WARN_ON(!iter_info->report_mask)) in send_to_group()
297 mark = iter_info->marks[type]; in send_to_group()
299 !(mark->flags & FSNOTIFY_MARK_FLAG_IGNORED_SURV_MODIFY)) in send_to_group()
300 mark->ignored_mask = 0; in send_to_group()
307 mark = iter_info->marks[type]; in send_to_group()
310 group = mark->group; in send_to_group()
311 marks_mask |= mark->mask; in send_to_group()
312 marks_ignored_mask |= mark->ignored_mask; in send_to_group()
323 if (group->ops->handle_event) { in send_to_group()
324 return group->ops->handle_event(group, mask, data, data_type, dir, in send_to_group()
339 node = srcu_dereference(conn->list.first, &fsnotify_mark_srcu); in fsnotify_first_mark()
349 node = srcu_dereference(mark->obj_list.next, in fsnotify_next_mark()
370 mark = iter_info->marks[type]; in fsnotify_iter_select_report_types()
372 fsnotify_compare_groups(max_prio_group, mark->group) > 0) in fsnotify_iter_select_report_types()
373 max_prio_group = mark->group; in fsnotify_iter_select_report_types()
380 iter_info->report_mask = 0; in fsnotify_iter_select_report_types()
382 mark = iter_info->marks[type]; in fsnotify_iter_select_report_types()
384 fsnotify_compare_groups(max_prio_group, mark->group) == 0) in fsnotify_iter_select_report_types()
388 return iter_info->report_mask; in fsnotify_iter_select_report_types()
401 iter_info->marks[type] = in fsnotify_iter_next()
402 fsnotify_next_mark(iter_info->marks[type]); in fsnotify_iter_next()
407 * fsnotify - This is the main call to fsnotify.
417 * @dir: optional directory associated with event -
421 * @inode: optional inode associated with event -
422 * either @dir or @inode must be non-NULL.
423 * if both are non-NULL event may be reported to both.
433 struct inode *child = NULL; in fsnotify() local
438 mnt = real_mount(path->mnt); in fsnotify()
441 /* Dirent event - report on TYPE_INODE to dir */ in fsnotify()
445 * Event on child - report on TYPE_INODE to dir if it is in fsnotify()
446 * watching children and on TYPE_CHILD to child. in fsnotify()
448 child = inode; in fsnotify()
451 sb = inode->i_sb; in fsnotify()
460 if (!sb->s_fsnotify_marks && in fsnotify()
461 (!mnt || !mnt->mnt_fsnotify_marks) && in fsnotify()
462 (!inode || !inode->i_fsnotify_marks) && in fsnotify()
463 (!child || !child->i_fsnotify_marks)) in fsnotify()
466 marks_mask = sb->s_fsnotify_mask; in fsnotify()
468 marks_mask |= mnt->mnt_fsnotify_mask; in fsnotify()
470 marks_mask |= inode->i_fsnotify_mask; in fsnotify()
471 if (child) in fsnotify()
472 marks_mask |= child->i_fsnotify_mask; in fsnotify()
486 fsnotify_first_mark(&sb->s_fsnotify_marks); in fsnotify()
489 fsnotify_first_mark(&mnt->mnt_fsnotify_marks); in fsnotify()
493 fsnotify_first_mark(&inode->i_fsnotify_marks); in fsnotify()
495 if (child) { in fsnotify()
497 fsnotify_first_mark(&child->i_fsnotify_marks); in fsnotify()