Branch data Line data Source code
1 : : // SPDX-License-Identifier: GPL-2.0-or-later 2 : : /* 3 : : * Copyright (C) 2008 Red Hat, Inc., Eric Paris <eparis@redhat.com> 4 : : */ 5 : : 6 : : #include <linux/dcache.h> 7 : : #include <linux/fs.h> 8 : : #include <linux/gfp.h> 9 : : #include <linux/init.h> 10 : : #include <linux/module.h> 11 : : #include <linux/mount.h> 12 : : #include <linux/srcu.h> 13 : : 14 : : #include <linux/fsnotify_backend.h> 15 : : #include "fsnotify.h" 16 : : 17 : : /* 18 : : * Clear all of the marks on an inode when it is being evicted from core 19 : : */ 20 : 3 : void __fsnotify_inode_delete(struct inode *inode) 21 : : { 22 : : fsnotify_clear_marks_by_inode(inode); 23 : 3 : } 24 : : EXPORT_SYMBOL_GPL(__fsnotify_inode_delete); 25 : : 26 : 3 : void __fsnotify_vfsmount_delete(struct vfsmount *mnt) 27 : : { 28 : : fsnotify_clear_marks_by_mount(mnt); 29 : 3 : } 30 : : 31 : : /** 32 : : * fsnotify_unmount_inodes - an sb is unmounting. handle any watched inodes. 33 : : * @sb: superblock being unmounted. 34 : : * 35 : : * Called during unmount with no locks held, so needs to be safe against 36 : : * concurrent modifiers. We temporarily drop sb->s_inode_list_lock and CAN block. 37 : : */ 38 : 2 : static void fsnotify_unmount_inodes(struct super_block *sb) 39 : : { 40 : : struct inode *inode, *iput_inode = NULL; 41 : : 42 : : spin_lock(&sb->s_inode_list_lock); 43 : 2 : list_for_each_entry(inode, &sb->s_inodes, i_sb_list) { 44 : : /* 45 : : * We cannot __iget() an inode in state I_FREEING, 46 : : * I_WILL_FREE, or I_NEW which is fine because by that point 47 : : * the inode cannot have any associated watches. 48 : : */ 49 : : spin_lock(&inode->i_lock); 50 : 0 : if (inode->i_state & (I_FREEING|I_WILL_FREE|I_NEW)) { 51 : : spin_unlock(&inode->i_lock); 52 : 0 : continue; 53 : : } 54 : : 55 : : /* 56 : : * If i_count is zero, the inode cannot have any watches and 57 : : * doing an __iget/iput with SB_ACTIVE clear would actually 58 : : * evict all inodes with zero i_count from icache which is 59 : : * unnecessarily violent and may in fact be illegal to do. 60 : : * However, we should have been called /after/ evict_inodes 61 : : * removed all zero refcount inodes, in any case. Test to 62 : : * be sure. 63 : : */ 64 : 0 : if (!atomic_read(&inode->i_count)) { 65 : : spin_unlock(&inode->i_lock); 66 : 0 : continue; 67 : : } 68 : : 69 : 0 : __iget(inode); 70 : : spin_unlock(&inode->i_lock); 71 : : spin_unlock(&sb->s_inode_list_lock); 72 : : 73 : 0 : if (iput_inode) 74 : 0 : iput(iput_inode); 75 : : 76 : : /* for each watch, send FS_UNMOUNT and then remove it */ 77 : 0 : fsnotify(inode, FS_UNMOUNT, inode, FSNOTIFY_EVENT_INODE, NULL, 0); 78 : : 79 : : fsnotify_inode_delete(inode); 80 : : 81 : : iput_inode = inode; 82 : : 83 : 0 : cond_resched(); 84 : : spin_lock(&sb->s_inode_list_lock); 85 : : } 86 : : spin_unlock(&sb->s_inode_list_lock); 87 : : 88 : 2 : if (iput_inode) 89 : 0 : iput(iput_inode); 90 : : /* Wait for outstanding inode references from connectors */ 91 : 2 : wait_var_event(&sb->s_fsnotify_inode_refs, 92 : : !atomic_long_read(&sb->s_fsnotify_inode_refs)); 93 : 2 : } 94 : : 95 : 2 : void fsnotify_sb_delete(struct super_block *sb) 96 : : { 97 : 2 : fsnotify_unmount_inodes(sb); 98 : : fsnotify_clear_marks_by_sb(sb); 99 : 2 : } 100 : : 101 : : /* 102 : : * Given an inode, first check if we care what happens to our children. Inotify 103 : : * and dnotify both tell their parents about events. If we care about any event 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. 107 : : */ 108 : 3 : void __fsnotify_update_child_dentry_flags(struct inode *inode) 109 : : { 110 : : struct dentry *alias; 111 : : int watched; 112 : : 113 : 3 : if (!S_ISDIR(inode->i_mode)) 114 : 3 : return; 115 : : 116 : : /* determine if the children should tell inode about their events */ 117 : : watched = fsnotify_inode_watches_children(inode); 118 : : 119 : : spin_lock(&inode->i_lock); 120 : : /* run all of the dentries associated with this inode. Since this is a 121 : : * directory, there damn well better only be one item on this list */ 122 : 3 : hlist_for_each_entry(alias, &inode->i_dentry, d_u.d_alias) { 123 : : struct dentry *child; 124 : : 125 : : /* run all of the children of the original inode and fix their 126 : : * d_flags to indicate parental interest (their parent is the 127 : : * original inode) */ 128 : : spin_lock(&alias->d_lock); 129 : 3 : list_for_each_entry(child, &alias->d_subdirs, d_child) { 130 : 3 : if (!child->d_inode) 131 : 3 : continue; 132 : : 133 : 3 : spin_lock_nested(&child->d_lock, DENTRY_D_LOCK_NESTED); 134 : 3 : if (watched) 135 : 3 : child->d_flags |= DCACHE_FSNOTIFY_PARENT_WATCHED; 136 : : else 137 : 3 : child->d_flags &= ~DCACHE_FSNOTIFY_PARENT_WATCHED; 138 : : spin_unlock(&child->d_lock); 139 : : } 140 : : spin_unlock(&alias->d_lock); 141 : : } 142 : : spin_unlock(&inode->i_lock); 143 : : } 144 : : 145 : : /* Notify this dentry's parent about a child's events. */ 146 : 3 : int __fsnotify_parent(const struct path *path, struct dentry *dentry, __u32 mask) 147 : : { 148 : : struct dentry *parent; 149 : : struct inode *p_inode; 150 : : int ret = 0; 151 : : 152 : 3 : if (!dentry) 153 : 0 : dentry = path->dentry; 154 : : 155 : 3 : if (!(dentry->d_flags & DCACHE_FSNOTIFY_PARENT_WATCHED)) 156 : : return 0; 157 : : 158 : 3 : parent = dget_parent(dentry); 159 : 3 : p_inode = parent->d_inode; 160 : : 161 : 3 : if (unlikely(!fsnotify_inode_watches_children(p_inode))) { 162 : 3 : __fsnotify_update_child_dentry_flags(p_inode); 163 : 3 : } else if (p_inode->i_fsnotify_mask & mask & ALL_FSNOTIFY_EVENTS) { 164 : : struct name_snapshot name; 165 : : 166 : : /* we are notifying a parent so come up with the new mask which 167 : : * specifies these are events which came from a child. */ 168 : 3 : mask |= FS_EVENT_ON_CHILD; 169 : : 170 : 3 : take_dentry_name_snapshot(&name, dentry); 171 : 3 : if (path) 172 : 3 : ret = fsnotify(p_inode, mask, path, FSNOTIFY_EVENT_PATH, 173 : : &name.name, 0); 174 : : else 175 : 3 : ret = fsnotify(p_inode, mask, dentry->d_inode, FSNOTIFY_EVENT_INODE, 176 : : &name.name, 0); 177 : 3 : release_dentry_name_snapshot(&name); 178 : : } 179 : : 180 : 3 : dput(parent); 181 : : 182 : 3 : return ret; 183 : : } 184 : : EXPORT_SYMBOL_GPL(__fsnotify_parent); 185 : : 186 : 3 : static int send_to_group(struct inode *to_tell, 187 : : __u32 mask, const void *data, 188 : : int data_is, u32 cookie, 189 : : const struct qstr *file_name, 190 : : struct fsnotify_iter_info *iter_info) 191 : : { 192 : : struct fsnotify_group *group = NULL; 193 : 3 : __u32 test_mask = (mask & ALL_FSNOTIFY_EVENTS); 194 : : __u32 marks_mask = 0; 195 : : __u32 marks_ignored_mask = 0; 196 : : struct fsnotify_mark *mark; 197 : : int type; 198 : : 199 : 3 : if (WARN_ON(!iter_info->report_mask)) 200 : : return 0; 201 : : 202 : : /* clear ignored on inode modification */ 203 : 3 : if (mask & FS_MODIFY) { 204 : 3 : fsnotify_foreach_obj_type(type) { 205 : 3 : if (!fsnotify_iter_should_report_type(iter_info, type)) 206 : 3 : continue; 207 : 3 : mark = iter_info->marks[type]; 208 : 3 : if (mark && 209 : 3 : !(mark->flags & FSNOTIFY_MARK_FLAG_IGNORED_SURV_MODIFY)) 210 : 3 : mark->ignored_mask = 0; 211 : : } 212 : : } 213 : : 214 : 3 : fsnotify_foreach_obj_type(type) { 215 : 3 : if (!fsnotify_iter_should_report_type(iter_info, type)) 216 : 3 : continue; 217 : 3 : mark = iter_info->marks[type]; 218 : : /* does the object mark tell us to do something? */ 219 : 3 : if (mark) { 220 : 3 : group = mark->group; 221 : 3 : marks_mask |= mark->mask; 222 : 3 : marks_ignored_mask |= mark->ignored_mask; 223 : : } 224 : : } 225 : : 226 : : pr_debug("%s: group=%p to_tell=%p mask=%x marks_mask=%x marks_ignored_mask=%x" 227 : : " data=%p data_is=%d cookie=%d\n", 228 : : __func__, group, to_tell, mask, marks_mask, marks_ignored_mask, 229 : : data, data_is, cookie); 230 : : 231 : 3 : if (!(test_mask & marks_mask & ~marks_ignored_mask)) 232 : : return 0; 233 : : 234 : 3 : return group->ops->handle_event(group, to_tell, mask, data, data_is, 235 : : file_name, cookie, iter_info); 236 : : } 237 : : 238 : : static struct fsnotify_mark *fsnotify_first_mark(struct fsnotify_mark_connector **connp) 239 : : { 240 : : struct fsnotify_mark_connector *conn; 241 : : struct hlist_node *node = NULL; 242 : : 243 : 3 : conn = srcu_dereference(*connp, &fsnotify_mark_srcu); 244 : 3 : if (conn) 245 : 3 : node = srcu_dereference(conn->list.first, &fsnotify_mark_srcu); 246 : : 247 : 3 : return hlist_entry_safe(node, struct fsnotify_mark, obj_list); 248 : : } 249 : : 250 : : static struct fsnotify_mark *fsnotify_next_mark(struct fsnotify_mark *mark) 251 : : { 252 : : struct hlist_node *node = NULL; 253 : : 254 : 3 : if (mark) 255 : 3 : node = srcu_dereference(mark->obj_list.next, 256 : : &fsnotify_mark_srcu); 257 : : 258 : 3 : return hlist_entry_safe(node, struct fsnotify_mark, obj_list); 259 : : } 260 : : 261 : : /* 262 : : * iter_info is a multi head priority queue of marks. 263 : : * Pick a subset of marks from queue heads, all with the 264 : : * same group and set the report_mask for selected subset. 265 : : * Returns the report_mask of the selected subset. 266 : : */ 267 : 3 : static unsigned int fsnotify_iter_select_report_types( 268 : : struct fsnotify_iter_info *iter_info) 269 : : { 270 : : struct fsnotify_group *max_prio_group = NULL; 271 : : struct fsnotify_mark *mark; 272 : : int type; 273 : : 274 : : /* Choose max prio group among groups of all queue heads */ 275 : 3 : fsnotify_foreach_obj_type(type) { 276 : 3 : mark = iter_info->marks[type]; 277 : 3 : if (mark && 278 : 3 : fsnotify_compare_groups(max_prio_group, mark->group) > 0) 279 : 3 : max_prio_group = mark->group; 280 : : } 281 : : 282 : 3 : if (!max_prio_group) 283 : : return 0; 284 : : 285 : : /* Set the report mask for marks from same group as max prio group */ 286 : 3 : iter_info->report_mask = 0; 287 : 3 : fsnotify_foreach_obj_type(type) { 288 : 3 : mark = iter_info->marks[type]; 289 : 3 : if (mark && 290 : 3 : fsnotify_compare_groups(max_prio_group, mark->group) == 0) 291 : : fsnotify_iter_set_report_type(iter_info, type); 292 : : } 293 : : 294 : 3 : return iter_info->report_mask; 295 : : } 296 : : 297 : : /* 298 : : * Pop from iter_info multi head queue, the marks that were iterated in the 299 : : * current iteration step. 300 : : */ 301 : 3 : static void fsnotify_iter_next(struct fsnotify_iter_info *iter_info) 302 : : { 303 : : int type; 304 : : 305 : 3 : fsnotify_foreach_obj_type(type) { 306 : 3 : if (fsnotify_iter_should_report_type(iter_info, type)) 307 : 3 : iter_info->marks[type] = 308 : 3 : fsnotify_next_mark(iter_info->marks[type]); 309 : : } 310 : 3 : } 311 : : 312 : : /* 313 : : * This is the main call to fsnotify. The VFS calls into hook specific functions 314 : : * in linux/fsnotify.h. Those functions then in turn call here. Here will call 315 : : * out to all of the registered fsnotify_group. Those groups can then use the 316 : : * notification event in whatever means they feel necessary. 317 : : */ 318 : 3 : int fsnotify(struct inode *to_tell, __u32 mask, const void *data, int data_is, 319 : : const struct qstr *file_name, u32 cookie) 320 : : { 321 : 3 : struct fsnotify_iter_info iter_info = {}; 322 : 3 : struct super_block *sb = to_tell->i_sb; 323 : : struct mount *mnt = NULL; 324 : 3 : __u32 mnt_or_sb_mask = sb->s_fsnotify_mask; 325 : : int ret = 0; 326 : 3 : __u32 test_mask = (mask & ALL_FSNOTIFY_EVENTS); 327 : : 328 : 3 : if (data_is == FSNOTIFY_EVENT_PATH) { 329 : 3 : mnt = real_mount(((const struct path *)data)->mnt); 330 : 3 : mnt_or_sb_mask |= mnt->mnt_fsnotify_mask; 331 : : } 332 : : /* An event "on child" is not intended for a mount/sb mark */ 333 : 3 : if (mask & FS_EVENT_ON_CHILD) 334 : : mnt_or_sb_mask = 0; 335 : : 336 : : /* 337 : : * Optimization: srcu_read_lock() has a memory barrier which can 338 : : * be expensive. It protects walking the *_fsnotify_marks lists. 339 : : * However, if we do not walk the lists, we do not have to do 340 : : * SRCU because we have no references to any objects and do not 341 : : * need SRCU to keep them "alive". 342 : : */ 343 : 3 : if (!to_tell->i_fsnotify_marks && !sb->s_fsnotify_marks && 344 : 3 : (!mnt || !mnt->mnt_fsnotify_marks)) 345 : : return 0; 346 : : /* 347 : : * if this is a modify event we may need to clear the ignored masks 348 : : * otherwise return if neither the inode nor the vfsmount/sb care about 349 : : * this type of event. 350 : : */ 351 : 3 : if (!(mask & FS_MODIFY) && 352 : 3 : !(test_mask & (to_tell->i_fsnotify_mask | mnt_or_sb_mask))) 353 : : return 0; 354 : : 355 : 3 : iter_info.srcu_idx = srcu_read_lock(&fsnotify_mark_srcu); 356 : : 357 : 3 : iter_info.marks[FSNOTIFY_OBJ_TYPE_INODE] = 358 : : fsnotify_first_mark(&to_tell->i_fsnotify_marks); 359 : 3 : iter_info.marks[FSNOTIFY_OBJ_TYPE_SB] = 360 : : fsnotify_first_mark(&sb->s_fsnotify_marks); 361 : 3 : if (mnt) { 362 : 3 : iter_info.marks[FSNOTIFY_OBJ_TYPE_VFSMOUNT] = 363 : : fsnotify_first_mark(&mnt->mnt_fsnotify_marks); 364 : : } 365 : : 366 : : /* 367 : : * We need to merge inode/vfsmount/sb mark lists so that e.g. inode mark 368 : : * ignore masks are properly reflected for mount/sb mark notifications. 369 : : * That's why this traversal is so complicated... 370 : : */ 371 : 3 : while (fsnotify_iter_select_report_types(&iter_info)) { 372 : 3 : ret = send_to_group(to_tell, mask, data, data_is, cookie, 373 : : file_name, &iter_info); 374 : : 375 : 3 : if (ret && (mask & ALL_FSNOTIFY_PERM_EVENTS)) 376 : : goto out; 377 : : 378 : 3 : fsnotify_iter_next(&iter_info); 379 : : } 380 : : ret = 0; 381 : : out: 382 : 3 : srcu_read_unlock(&fsnotify_mark_srcu, iter_info.srcu_idx); 383 : : 384 : 3 : return ret; 385 : : } 386 : : EXPORT_SYMBOL_GPL(fsnotify); 387 : : 388 : : extern struct kmem_cache *fsnotify_mark_connector_cachep; 389 : : 390 : 3 : static __init int fsnotify_init(void) 391 : : { 392 : : int ret; 393 : : 394 : : BUILD_BUG_ON(HWEIGHT32(ALL_FSNOTIFY_BITS) != 25); 395 : : 396 : 3 : ret = init_srcu_struct(&fsnotify_mark_srcu); 397 : 3 : if (ret) 398 : 0 : panic("initializing fsnotify_mark_srcu"); 399 : : 400 : 3 : fsnotify_mark_connector_cachep = KMEM_CACHE(fsnotify_mark_connector, 401 : : SLAB_PANIC); 402 : : 403 : 3 : return 0; 404 : : } 405 : : core_initcall(fsnotify_init);