15444e298SEric Paris /* 25444e298SEric Paris * Copyright (C) 2008 Red Hat, Inc., Eric Paris <eparis@redhat.com> 35444e298SEric Paris * 45444e298SEric Paris * This program is free software; you can redistribute it and/or modify 55444e298SEric Paris * it under the terms of the GNU General Public License as published by 65444e298SEric Paris * the Free Software Foundation; either version 2, or (at your option) 75444e298SEric Paris * any later version. 85444e298SEric Paris * 95444e298SEric Paris * This program is distributed in the hope that it will be useful, 105444e298SEric Paris * but WITHOUT ANY WARRANTY; without even the implied warranty of 115444e298SEric Paris * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 125444e298SEric Paris * GNU General Public License for more details. 135444e298SEric Paris * 145444e298SEric Paris * You should have received a copy of the GNU General Public License 155444e298SEric Paris * along with this program; see the file COPYING. If not, write to 165444e298SEric Paris * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 175444e298SEric Paris */ 185444e298SEric Paris 195444e298SEric Paris /* 205444e298SEric Paris * fsnotify inode mark locking/lifetime/and refcnting 215444e298SEric Paris * 225444e298SEric Paris * REFCNT: 239756b918SLino Sanfilippo * The group->recnt and mark->refcnt tell how many "things" in the kernel 249756b918SLino Sanfilippo * currently are referencing the objects. Both kind of objects typically will 259756b918SLino Sanfilippo * live inside the kernel with a refcnt of 2, one for its creation and one for 269756b918SLino Sanfilippo * the reference a group and a mark hold to each other. 279756b918SLino Sanfilippo * If you are holding the appropriate locks, you can take a reference and the 289756b918SLino Sanfilippo * object itself is guaranteed to survive until the reference is dropped. 295444e298SEric Paris * 305444e298SEric Paris * LOCKING: 319756b918SLino Sanfilippo * There are 3 locks involved with fsnotify inode marks and they MUST be taken 329756b918SLino Sanfilippo * in order as follows: 335444e298SEric Paris * 349756b918SLino Sanfilippo * group->mark_mutex 355444e298SEric Paris * mark->lock 3604662cabSJan Kara * mark->connector->lock 375444e298SEric Paris * 389756b918SLino Sanfilippo * group->mark_mutex protects the marks_list anchored inside a given group and 399756b918SLino Sanfilippo * each mark is hooked via the g_list. It also protects the groups private 409756b918SLino Sanfilippo * data (i.e group limits). 419756b918SLino Sanfilippo 429756b918SLino Sanfilippo * mark->lock protects the marks attributes like its masks and flags. 439756b918SLino Sanfilippo * Furthermore it protects the access to a reference of the group that the mark 449756b918SLino Sanfilippo * is assigned to as well as the access to a reference of the inode/vfsmount 459756b918SLino Sanfilippo * that is being watched by the mark. 465444e298SEric Paris * 4704662cabSJan Kara * mark->connector->lock protects the list of marks anchored inside an 4804662cabSJan Kara * inode / vfsmount and each mark is hooked via the i_list. 495444e298SEric Paris * 5004662cabSJan Kara * A list of notification marks relating to inode / mnt is contained in 5104662cabSJan Kara * fsnotify_mark_connector. That structure is alive as long as there are any 526b3f05d2SJan Kara * marks in the list and is also protected by fsnotify_mark_srcu. A mark gets 536b3f05d2SJan Kara * detached from fsnotify_mark_connector when last reference to the mark is 546b3f05d2SJan Kara * dropped. Thus having mark reference is enough to protect mark->connector 556b3f05d2SJan Kara * pointer and to make sure fsnotify_mark_connector cannot disappear. Also 566b3f05d2SJan Kara * because we remove mark from g_list before dropping mark reference associated 576b3f05d2SJan Kara * with that, any mark found through g_list is guaranteed to have 586b3f05d2SJan Kara * mark->connector set until we drop group->mark_mutex. 595444e298SEric Paris * 605444e298SEric Paris * LIFETIME: 615444e298SEric Paris * Inode marks survive between when they are added to an inode and when their 62c1f33073SJan Kara * refcnt==0. Marks are also protected by fsnotify_mark_srcu. 635444e298SEric Paris * 645444e298SEric Paris * The inode mark can be cleared for a number of different reasons including: 655444e298SEric Paris * - The inode is unlinked for the last time. (fsnotify_inode_remove) 665444e298SEric Paris * - The inode is being evicted from cache. (fsnotify_inode_delete) 675444e298SEric Paris * - The fs the inode is on is unmounted. (fsnotify_inode_delete/fsnotify_unmount_inodes) 685444e298SEric Paris * - Something explicitly requests that it be removed. (fsnotify_destroy_mark) 695444e298SEric Paris * - The fsnotify_group associated with the mark is going away and all such marks 705444e298SEric Paris * need to be cleaned up. (fsnotify_clear_marks_by_group) 715444e298SEric Paris * 725444e298SEric Paris * This has the very interesting property of being able to run concurrently with 735444e298SEric Paris * any (or all) other directions. 745444e298SEric Paris */ 755444e298SEric Paris 765444e298SEric Paris #include <linux/fs.h> 775444e298SEric Paris #include <linux/init.h> 785444e298SEric Paris #include <linux/kernel.h> 7975c1be48SEric Paris #include <linux/kthread.h> 805444e298SEric Paris #include <linux/module.h> 815444e298SEric Paris #include <linux/mutex.h> 825444e298SEric Paris #include <linux/slab.h> 835444e298SEric Paris #include <linux/spinlock.h> 8475c1be48SEric Paris #include <linux/srcu.h> 855444e298SEric Paris 8660063497SArun Sharma #include <linux/atomic.h> 875444e298SEric Paris 885444e298SEric Paris #include <linux/fsnotify_backend.h> 895444e298SEric Paris #include "fsnotify.h" 905444e298SEric Paris 910918f1c3SJeff Layton #define FSNOTIFY_REAPER_DELAY (1) /* 1 jiffy */ 920918f1c3SJeff Layton 9375c1be48SEric Paris struct srcu_struct fsnotify_mark_srcu; 949dd813c1SJan Kara struct kmem_cache *fsnotify_mark_connector_cachep; 959dd813c1SJan Kara 9613d34ac6SJeff Layton static DEFINE_SPINLOCK(destroy_lock); 9713d34ac6SJeff Layton static LIST_HEAD(destroy_list); 9808991e83SJan Kara static struct fsnotify_mark_connector *connector_destroy_list; 990918f1c3SJeff Layton 10035e48176SJan Kara static void fsnotify_mark_destroy_workfn(struct work_struct *work); 10135e48176SJan Kara static DECLARE_DELAYED_WORK(reaper_work, fsnotify_mark_destroy_workfn); 10275c1be48SEric Paris 10308991e83SJan Kara static void fsnotify_connector_destroy_workfn(struct work_struct *work); 10408991e83SJan Kara static DECLARE_WORK(connector_reaper_work, fsnotify_connector_destroy_workfn); 10508991e83SJan Kara 1065444e298SEric Paris void fsnotify_get_mark(struct fsnotify_mark *mark) 1075444e298SEric Paris { 10811375145SJan Kara WARN_ON_ONCE(!atomic_read(&mark->refcnt)); 1095444e298SEric Paris atomic_inc(&mark->refcnt); 1105444e298SEric Paris } 1115444e298SEric Paris 112*abc77577SJan Kara /* 113*abc77577SJan Kara * Get mark reference when we found the mark via lockless traversal of object 114*abc77577SJan Kara * list. Mark can be already removed from the list by now and on its way to be 115*abc77577SJan Kara * destroyed once SRCU period ends. 116*abc77577SJan Kara */ 117*abc77577SJan Kara static bool fsnotify_get_mark_safe(struct fsnotify_mark *mark) 118*abc77577SJan Kara { 119*abc77577SJan Kara return atomic_inc_not_zero(&mark->refcnt); 120*abc77577SJan Kara } 121*abc77577SJan Kara 122a242677bSJan Kara static void __fsnotify_recalc_mask(struct fsnotify_mark_connector *conn) 1230809ab69SJan Kara { 1240809ab69SJan Kara u32 new_mask = 0; 1250809ab69SJan Kara struct fsnotify_mark *mark; 1260809ab69SJan Kara 12704662cabSJan Kara assert_spin_locked(&conn->lock); 1286b3f05d2SJan Kara hlist_for_each_entry(mark, &conn->list, obj_list) { 1296b3f05d2SJan Kara if (mark->flags & FSNOTIFY_MARK_FLAG_ATTACHED) 1300809ab69SJan Kara new_mask |= mark->mask; 1316b3f05d2SJan Kara } 132a242677bSJan Kara if (conn->flags & FSNOTIFY_OBJ_TYPE_INODE) 133a242677bSJan Kara conn->inode->i_fsnotify_mask = new_mask; 134a242677bSJan Kara else if (conn->flags & FSNOTIFY_OBJ_TYPE_VFSMOUNT) 135a242677bSJan Kara real_mount(conn->mnt)->mnt_fsnotify_mask = new_mask; 136a242677bSJan Kara } 137a242677bSJan Kara 138a242677bSJan Kara /* 139a242677bSJan Kara * Calculate mask of events for a list of marks. The caller must make sure 1406b3f05d2SJan Kara * connector and connector->inode cannot disappear under us. Callers achieve 1416b3f05d2SJan Kara * this by holding a mark->lock or mark->group->mark_mutex for a mark on this 1426b3f05d2SJan Kara * list. 143a242677bSJan Kara */ 144a242677bSJan Kara void fsnotify_recalc_mask(struct fsnotify_mark_connector *conn) 145a242677bSJan Kara { 146a242677bSJan Kara if (!conn) 147a242677bSJan Kara return; 148a242677bSJan Kara 14904662cabSJan Kara spin_lock(&conn->lock); 150a242677bSJan Kara __fsnotify_recalc_mask(conn); 15104662cabSJan Kara spin_unlock(&conn->lock); 15204662cabSJan Kara if (conn->flags & FSNOTIFY_OBJ_TYPE_INODE) 153a242677bSJan Kara __fsnotify_update_child_dentry_flags(conn->inode); 1540809ab69SJan Kara } 1550809ab69SJan Kara 15608991e83SJan Kara /* Free all connectors queued for freeing once SRCU period ends */ 15708991e83SJan Kara static void fsnotify_connector_destroy_workfn(struct work_struct *work) 15808991e83SJan Kara { 15908991e83SJan Kara struct fsnotify_mark_connector *conn, *free; 16008991e83SJan Kara 16108991e83SJan Kara spin_lock(&destroy_lock); 16208991e83SJan Kara conn = connector_destroy_list; 16308991e83SJan Kara connector_destroy_list = NULL; 16408991e83SJan Kara spin_unlock(&destroy_lock); 16508991e83SJan Kara 16608991e83SJan Kara synchronize_srcu(&fsnotify_mark_srcu); 16708991e83SJan Kara while (conn) { 16808991e83SJan Kara free = conn; 16908991e83SJan Kara conn = conn->destroy_next; 17008991e83SJan Kara kmem_cache_free(fsnotify_mark_connector_cachep, free); 17108991e83SJan Kara } 17208991e83SJan Kara } 17308991e83SJan Kara 17408991e83SJan Kara static struct inode *fsnotify_detach_connector_from_object( 17508991e83SJan Kara struct fsnotify_mark_connector *conn) 17608991e83SJan Kara { 17708991e83SJan Kara struct inode *inode = NULL; 17808991e83SJan Kara 17908991e83SJan Kara if (conn->flags & FSNOTIFY_OBJ_TYPE_INODE) { 18008991e83SJan Kara inode = conn->inode; 18108991e83SJan Kara rcu_assign_pointer(inode->i_fsnotify_marks, NULL); 18208991e83SJan Kara inode->i_fsnotify_mask = 0; 18308991e83SJan Kara conn->inode = NULL; 18408991e83SJan Kara conn->flags &= ~FSNOTIFY_OBJ_TYPE_INODE; 18508991e83SJan Kara } else if (conn->flags & FSNOTIFY_OBJ_TYPE_VFSMOUNT) { 18608991e83SJan Kara rcu_assign_pointer(real_mount(conn->mnt)->mnt_fsnotify_marks, 18708991e83SJan Kara NULL); 18808991e83SJan Kara real_mount(conn->mnt)->mnt_fsnotify_mask = 0; 18908991e83SJan Kara conn->mnt = NULL; 19008991e83SJan Kara conn->flags &= ~FSNOTIFY_OBJ_TYPE_VFSMOUNT; 19108991e83SJan Kara } 19208991e83SJan Kara 19308991e83SJan Kara return inode; 19408991e83SJan Kara } 19508991e83SJan Kara 1966b3f05d2SJan Kara static void fsnotify_final_mark_destroy(struct fsnotify_mark *mark) 1976b3f05d2SJan Kara { 1986b3f05d2SJan Kara if (mark->group) 1996b3f05d2SJan Kara fsnotify_put_group(mark->group); 2006b3f05d2SJan Kara mark->free_mark(mark); 2016b3f05d2SJan Kara } 2026b3f05d2SJan Kara 2036b3f05d2SJan Kara void fsnotify_put_mark(struct fsnotify_mark *mark) 2048212a609SJan Kara { 2058212a609SJan Kara struct fsnotify_mark_connector *conn; 2068212a609SJan Kara struct inode *inode = NULL; 20708991e83SJan Kara bool free_conn = false; 2088212a609SJan Kara 2096b3f05d2SJan Kara /* Catch marks that were actually never attached to object */ 2106b3f05d2SJan Kara if (!mark->connector) { 2116b3f05d2SJan Kara if (atomic_dec_and_test(&mark->refcnt)) 2126b3f05d2SJan Kara fsnotify_final_mark_destroy(mark); 2136b3f05d2SJan Kara return; 2146b3f05d2SJan Kara } 2156b3f05d2SJan Kara 2166b3f05d2SJan Kara /* 2176b3f05d2SJan Kara * We have to be careful so that traversals of obj_list under lock can 2186b3f05d2SJan Kara * safely grab mark reference. 2196b3f05d2SJan Kara */ 2206b3f05d2SJan Kara if (!atomic_dec_and_lock(&mark->refcnt, &mark->connector->lock)) 2216b3f05d2SJan Kara return; 2226b3f05d2SJan Kara 2238212a609SJan Kara conn = mark->connector; 2248212a609SJan Kara hlist_del_init_rcu(&mark->obj_list); 2258212a609SJan Kara if (hlist_empty(&conn->list)) { 22608991e83SJan Kara inode = fsnotify_detach_connector_from_object(conn); 22708991e83SJan Kara free_conn = true; 22808991e83SJan Kara } else { 22973cd3c33SJan Kara __fsnotify_recalc_mask(conn); 23008991e83SJan Kara } 2318212a609SJan Kara mark->connector = NULL; 23204662cabSJan Kara spin_unlock(&conn->lock); 2338212a609SJan Kara 2346b3f05d2SJan Kara iput(inode); 2356b3f05d2SJan Kara 23608991e83SJan Kara if (free_conn) { 23708991e83SJan Kara spin_lock(&destroy_lock); 23808991e83SJan Kara conn->destroy_next = connector_destroy_list; 23908991e83SJan Kara connector_destroy_list = conn; 24008991e83SJan Kara spin_unlock(&destroy_lock); 24108991e83SJan Kara queue_work(system_unbound_wq, &connector_reaper_work); 24208991e83SJan Kara } 2436b3f05d2SJan Kara /* 2446b3f05d2SJan Kara * Note that we didn't update flags telling whether inode cares about 2456b3f05d2SJan Kara * what's happening with children. We update these flags from 2466b3f05d2SJan Kara * __fsnotify_parent() lazily when next event happens on one of our 2476b3f05d2SJan Kara * children. 2486b3f05d2SJan Kara */ 2496b3f05d2SJan Kara spin_lock(&destroy_lock); 2506b3f05d2SJan Kara list_add(&mark->g_list, &destroy_list); 2516b3f05d2SJan Kara spin_unlock(&destroy_lock); 2526b3f05d2SJan Kara queue_delayed_work(system_unbound_wq, &reaper_work, 2536b3f05d2SJan Kara FSNOTIFY_REAPER_DELAY); 2548212a609SJan Kara } 2558212a609SJan Kara 256*abc77577SJan Kara bool fsnotify_prepare_user_wait(struct fsnotify_iter_info *iter_info) 257*abc77577SJan Kara { 258*abc77577SJan Kara struct fsnotify_group *group; 259*abc77577SJan Kara 260*abc77577SJan Kara if (WARN_ON_ONCE(!iter_info->inode_mark && !iter_info->vfsmount_mark)) 261*abc77577SJan Kara return false; 262*abc77577SJan Kara 263*abc77577SJan Kara if (iter_info->inode_mark) 264*abc77577SJan Kara group = iter_info->inode_mark->group; 265*abc77577SJan Kara else 266*abc77577SJan Kara group = iter_info->vfsmount_mark->group; 267*abc77577SJan Kara 268*abc77577SJan Kara /* 269*abc77577SJan Kara * Since acquisition of mark reference is an atomic op as well, we can 270*abc77577SJan Kara * be sure this inc is seen before any effect of refcount increment. 271*abc77577SJan Kara */ 272*abc77577SJan Kara atomic_inc(&group->user_waits); 273*abc77577SJan Kara 274*abc77577SJan Kara if (iter_info->inode_mark) { 275*abc77577SJan Kara /* This can fail if mark is being removed */ 276*abc77577SJan Kara if (!fsnotify_get_mark_safe(iter_info->inode_mark)) 277*abc77577SJan Kara goto out_wait; 278*abc77577SJan Kara } 279*abc77577SJan Kara if (iter_info->vfsmount_mark) { 280*abc77577SJan Kara if (!fsnotify_get_mark_safe(iter_info->vfsmount_mark)) 281*abc77577SJan Kara goto out_inode; 282*abc77577SJan Kara } 283*abc77577SJan Kara 284*abc77577SJan Kara /* 285*abc77577SJan Kara * Now that both marks are pinned by refcount in the inode / vfsmount 286*abc77577SJan Kara * lists, we can drop SRCU lock, and safely resume the list iteration 287*abc77577SJan Kara * once userspace returns. 288*abc77577SJan Kara */ 289*abc77577SJan Kara srcu_read_unlock(&fsnotify_mark_srcu, iter_info->srcu_idx); 290*abc77577SJan Kara 291*abc77577SJan Kara return true; 292*abc77577SJan Kara out_inode: 293*abc77577SJan Kara if (iter_info->inode_mark) 294*abc77577SJan Kara fsnotify_put_mark(iter_info->inode_mark); 295*abc77577SJan Kara out_wait: 296*abc77577SJan Kara if (atomic_dec_and_test(&group->user_waits) && group->shutdown) 297*abc77577SJan Kara wake_up(&group->notification_waitq); 298*abc77577SJan Kara return false; 299*abc77577SJan Kara } 300*abc77577SJan Kara 301*abc77577SJan Kara void fsnotify_finish_user_wait(struct fsnotify_iter_info *iter_info) 302*abc77577SJan Kara { 303*abc77577SJan Kara struct fsnotify_group *group = NULL; 304*abc77577SJan Kara 305*abc77577SJan Kara iter_info->srcu_idx = srcu_read_lock(&fsnotify_mark_srcu); 306*abc77577SJan Kara if (iter_info->inode_mark) { 307*abc77577SJan Kara group = iter_info->inode_mark->group; 308*abc77577SJan Kara fsnotify_put_mark(iter_info->inode_mark); 309*abc77577SJan Kara } 310*abc77577SJan Kara if (iter_info->vfsmount_mark) { 311*abc77577SJan Kara group = iter_info->vfsmount_mark->group; 312*abc77577SJan Kara fsnotify_put_mark(iter_info->vfsmount_mark); 313*abc77577SJan Kara } 314*abc77577SJan Kara /* 315*abc77577SJan Kara * We abuse notification_waitq on group shutdown for waiting for all 316*abc77577SJan Kara * marks pinned when waiting for userspace. 317*abc77577SJan Kara */ 318*abc77577SJan Kara if (atomic_dec_and_test(&group->user_waits) && group->shutdown) 319*abc77577SJan Kara wake_up(&group->notification_waitq); 320*abc77577SJan Kara } 321*abc77577SJan Kara 3225444e298SEric Paris /* 3236b3f05d2SJan Kara * Mark mark as detached, remove it from group list. Mark still stays in object 3246b3f05d2SJan Kara * list until its last reference is dropped. Note that we rely on mark being 3256b3f05d2SJan Kara * removed from group list before corresponding reference to it is dropped. In 3266b3f05d2SJan Kara * particular we rely on mark->connector being valid while we hold 3276b3f05d2SJan Kara * group->mark_mutex if we found the mark through g_list. 3284712e722SJan Kara * 32911375145SJan Kara * Must be called with group->mark_mutex held. The caller must either hold 33011375145SJan Kara * reference to the mark or be protected by fsnotify_mark_srcu. 3315444e298SEric Paris */ 3324712e722SJan Kara void fsnotify_detach_mark(struct fsnotify_mark *mark) 3335444e298SEric Paris { 3344712e722SJan Kara struct fsnotify_group *group = mark->group; 3355444e298SEric Paris 33611375145SJan Kara WARN_ON_ONCE(!mutex_is_locked(&group->mark_mutex)); 33711375145SJan Kara WARN_ON_ONCE(!srcu_read_lock_held(&fsnotify_mark_srcu) && 33811375145SJan Kara atomic_read(&mark->refcnt) < 1 + 33911375145SJan Kara !!(mark->flags & FSNOTIFY_MARK_FLAG_ATTACHED)); 340d5a335b8SLino Sanfilippo 341104d06f0SLino Sanfilippo spin_lock(&mark->lock); 342700307a2SEric Paris /* something else already called this function on this mark */ 3434712e722SJan Kara if (!(mark->flags & FSNOTIFY_MARK_FLAG_ATTACHED)) { 3445444e298SEric Paris spin_unlock(&mark->lock); 345e2a29943SLino Sanfilippo return; 3465444e298SEric Paris } 3474712e722SJan Kara mark->flags &= ~FSNOTIFY_MARK_FLAG_ATTACHED; 3485444e298SEric Paris list_del_init(&mark->g_list); 3495444e298SEric Paris spin_unlock(&mark->lock); 350d5a335b8SLino Sanfilippo 3514712e722SJan Kara atomic_dec(&group->num_marks); 35211375145SJan Kara 35311375145SJan Kara /* Drop mark reference acquired in fsnotify_add_mark_locked() */ 35411375145SJan Kara fsnotify_put_mark(mark); 3554712e722SJan Kara } 3564712e722SJan Kara 3574712e722SJan Kara /* 35811375145SJan Kara * Free fsnotify mark. The mark is actually only marked as being freed. The 35911375145SJan Kara * freeing is actually happening only once last reference to the mark is 36011375145SJan Kara * dropped from a workqueue which first waits for srcu period end. 36135e48176SJan Kara * 36211375145SJan Kara * Caller must have a reference to the mark or be protected by 36311375145SJan Kara * fsnotify_mark_srcu. 3644712e722SJan Kara */ 36511375145SJan Kara void fsnotify_free_mark(struct fsnotify_mark *mark) 3664712e722SJan Kara { 3674712e722SJan Kara struct fsnotify_group *group = mark->group; 3684712e722SJan Kara 3694712e722SJan Kara spin_lock(&mark->lock); 3704712e722SJan Kara /* something else already called this function on this mark */ 3714712e722SJan Kara if (!(mark->flags & FSNOTIFY_MARK_FLAG_ALIVE)) { 3724712e722SJan Kara spin_unlock(&mark->lock); 37311375145SJan Kara return; 3744712e722SJan Kara } 3754712e722SJan Kara mark->flags &= ~FSNOTIFY_MARK_FLAG_ALIVE; 3764712e722SJan Kara spin_unlock(&mark->lock); 3775444e298SEric Paris 378d725e66cSLinus Torvalds /* 379d725e66cSLinus Torvalds * Some groups like to know that marks are being freed. This is a 380d725e66cSLinus Torvalds * callback to the group function to let it know that this mark 381d725e66cSLinus Torvalds * is being freed. 382d725e66cSLinus Torvalds */ 383d725e66cSLinus Torvalds if (group->ops->freeing_mark) 384d725e66cSLinus Torvalds group->ops->freeing_mark(mark, group); 385d5a335b8SLino Sanfilippo } 386d5a335b8SLino Sanfilippo 387d5a335b8SLino Sanfilippo void fsnotify_destroy_mark(struct fsnotify_mark *mark, 388d5a335b8SLino Sanfilippo struct fsnotify_group *group) 389d5a335b8SLino Sanfilippo { 3906960b0d9SLino Sanfilippo mutex_lock_nested(&group->mark_mutex, SINGLE_DEPTH_NESTING); 3914712e722SJan Kara fsnotify_detach_mark(mark); 392d5a335b8SLino Sanfilippo mutex_unlock(&group->mark_mutex); 3934712e722SJan Kara fsnotify_free_mark(mark); 3945444e298SEric Paris } 3955444e298SEric Paris 39690b1e7a5SEric Paris void fsnotify_set_mark_mask_locked(struct fsnotify_mark *mark, __u32 mask) 39790b1e7a5SEric Paris { 39890b1e7a5SEric Paris assert_spin_locked(&mark->lock); 39990b1e7a5SEric Paris 40090b1e7a5SEric Paris mark->mask = mask; 40190b1e7a5SEric Paris } 40290b1e7a5SEric Paris 40333af5e32SEric Paris void fsnotify_set_mark_ignored_mask_locked(struct fsnotify_mark *mark, __u32 mask) 40433af5e32SEric Paris { 40533af5e32SEric Paris assert_spin_locked(&mark->lock); 40633af5e32SEric Paris 40733af5e32SEric Paris mark->ignored_mask = mask; 40833af5e32SEric Paris } 40990b1e7a5SEric Paris 4105444e298SEric Paris /* 4118edc6e16SJan Kara * Sorting function for lists of fsnotify marks. 4128edc6e16SJan Kara * 4138edc6e16SJan Kara * Fanotify supports different notification classes (reflected as priority of 4148edc6e16SJan Kara * notification group). Events shall be passed to notification groups in 4158edc6e16SJan Kara * decreasing priority order. To achieve this marks in notification lists for 4168edc6e16SJan Kara * inodes and vfsmounts are sorted so that priorities of corresponding groups 4178edc6e16SJan Kara * are descending. 4188edc6e16SJan Kara * 4198edc6e16SJan Kara * Furthermore correct handling of the ignore mask requires processing inode 4208edc6e16SJan Kara * and vfsmount marks of each group together. Using the group address as 4218edc6e16SJan Kara * further sort criterion provides a unique sorting order and thus we can 4228edc6e16SJan Kara * merge inode and vfsmount lists of marks in linear time and find groups 4238edc6e16SJan Kara * present in both lists. 4248edc6e16SJan Kara * 4258edc6e16SJan Kara * A return value of 1 signifies that b has priority over a. 4268edc6e16SJan Kara * A return value of 0 signifies that the two marks have to be handled together. 4278edc6e16SJan Kara * A return value of -1 signifies that a has priority over b. 4288edc6e16SJan Kara */ 4298edc6e16SJan Kara int fsnotify_compare_groups(struct fsnotify_group *a, struct fsnotify_group *b) 4308edc6e16SJan Kara { 4318edc6e16SJan Kara if (a == b) 4328edc6e16SJan Kara return 0; 4338edc6e16SJan Kara if (!a) 4348edc6e16SJan Kara return 1; 4358edc6e16SJan Kara if (!b) 4368edc6e16SJan Kara return -1; 4378edc6e16SJan Kara if (a->priority < b->priority) 4388edc6e16SJan Kara return 1; 4398edc6e16SJan Kara if (a->priority > b->priority) 4408edc6e16SJan Kara return -1; 4418edc6e16SJan Kara if (a < b) 4428edc6e16SJan Kara return 1; 4438edc6e16SJan Kara return -1; 4448edc6e16SJan Kara } 4458edc6e16SJan Kara 4469dd813c1SJan Kara static int fsnotify_attach_connector_to_object( 44708991e83SJan Kara struct fsnotify_mark_connector __rcu **connp, 44886ffe245SJan Kara struct inode *inode, 44986ffe245SJan Kara struct vfsmount *mnt) 4509dd813c1SJan Kara { 4519dd813c1SJan Kara struct fsnotify_mark_connector *conn; 4529dd813c1SJan Kara 453755b5bc6SJan Kara conn = kmem_cache_alloc(fsnotify_mark_connector_cachep, GFP_KERNEL); 4549dd813c1SJan Kara if (!conn) 4559dd813c1SJan Kara return -ENOMEM; 45604662cabSJan Kara spin_lock_init(&conn->lock); 4579dd813c1SJan Kara INIT_HLIST_HEAD(&conn->list); 45886ffe245SJan Kara if (inode) { 45986ffe245SJan Kara conn->flags = FSNOTIFY_OBJ_TYPE_INODE; 46008991e83SJan Kara conn->inode = igrab(inode); 46186ffe245SJan Kara } else { 46286ffe245SJan Kara conn->flags = FSNOTIFY_OBJ_TYPE_VFSMOUNT; 46386ffe245SJan Kara conn->mnt = mnt; 46486ffe245SJan Kara } 4659dd813c1SJan Kara /* 46604662cabSJan Kara * cmpxchg() provides the barrier so that readers of *connp can see 46704662cabSJan Kara * only initialized structure 4689dd813c1SJan Kara */ 46904662cabSJan Kara if (cmpxchg(connp, NULL, conn)) { 47004662cabSJan Kara /* Someone else created list structure for us */ 47108991e83SJan Kara if (inode) 47208991e83SJan Kara iput(inode); 473755b5bc6SJan Kara kmem_cache_free(fsnotify_mark_connector_cachep, conn); 47404662cabSJan Kara } 4759dd813c1SJan Kara 4769dd813c1SJan Kara return 0; 4779dd813c1SJan Kara } 4789dd813c1SJan Kara 4799dd813c1SJan Kara /* 48008991e83SJan Kara * Get mark connector, make sure it is alive and return with its lock held. 48108991e83SJan Kara * This is for users that get connector pointer from inode or mount. Users that 48208991e83SJan Kara * hold reference to a mark on the list may directly lock connector->lock as 48308991e83SJan Kara * they are sure list cannot go away under them. 48408991e83SJan Kara */ 48508991e83SJan Kara static struct fsnotify_mark_connector *fsnotify_grab_connector( 48608991e83SJan Kara struct fsnotify_mark_connector __rcu **connp) 48708991e83SJan Kara { 48808991e83SJan Kara struct fsnotify_mark_connector *conn; 48908991e83SJan Kara int idx; 49008991e83SJan Kara 49108991e83SJan Kara idx = srcu_read_lock(&fsnotify_mark_srcu); 49208991e83SJan Kara conn = srcu_dereference(*connp, &fsnotify_mark_srcu); 49308991e83SJan Kara if (!conn) 49408991e83SJan Kara goto out; 49508991e83SJan Kara spin_lock(&conn->lock); 49608991e83SJan Kara if (!(conn->flags & (FSNOTIFY_OBJ_TYPE_INODE | 49708991e83SJan Kara FSNOTIFY_OBJ_TYPE_VFSMOUNT))) { 49808991e83SJan Kara spin_unlock(&conn->lock); 49908991e83SJan Kara srcu_read_unlock(&fsnotify_mark_srcu, idx); 50008991e83SJan Kara return NULL; 50108991e83SJan Kara } 50208991e83SJan Kara out: 50308991e83SJan Kara srcu_read_unlock(&fsnotify_mark_srcu, idx); 50408991e83SJan Kara return conn; 50508991e83SJan Kara } 50608991e83SJan Kara 50708991e83SJan Kara /* 5089dd813c1SJan Kara * Add mark into proper place in given list of marks. These marks may be used 5099dd813c1SJan Kara * for the fsnotify backend to determine which event types should be delivered 5109dd813c1SJan Kara * to which group and for which inodes. These marks are ordered according to 5119dd813c1SJan Kara * priority, highest number first, and then by the group's location in memory. 5129dd813c1SJan Kara */ 513755b5bc6SJan Kara static int fsnotify_add_mark_list(struct fsnotify_mark *mark, 514755b5bc6SJan Kara struct inode *inode, struct vfsmount *mnt, 515755b5bc6SJan Kara int allow_dups) 5160809ab69SJan Kara { 5170809ab69SJan Kara struct fsnotify_mark *lmark, *last = NULL; 5189dd813c1SJan Kara struct fsnotify_mark_connector *conn; 51908991e83SJan Kara struct fsnotify_mark_connector __rcu **connp; 5200809ab69SJan Kara int cmp; 521755b5bc6SJan Kara int err = 0; 522755b5bc6SJan Kara 523755b5bc6SJan Kara if (WARN_ON(!inode && !mnt)) 524755b5bc6SJan Kara return -EINVAL; 52504662cabSJan Kara if (inode) 526755b5bc6SJan Kara connp = &inode->i_fsnotify_marks; 52704662cabSJan Kara else 528755b5bc6SJan Kara connp = &real_mount(mnt)->mnt_fsnotify_marks; 52908991e83SJan Kara restart: 53008991e83SJan Kara spin_lock(&mark->lock); 53108991e83SJan Kara conn = fsnotify_grab_connector(connp); 53208991e83SJan Kara if (!conn) { 53308991e83SJan Kara spin_unlock(&mark->lock); 53404662cabSJan Kara err = fsnotify_attach_connector_to_object(connp, inode, mnt); 5359dd813c1SJan Kara if (err) 5369dd813c1SJan Kara return err; 53708991e83SJan Kara goto restart; 5389dd813c1SJan Kara } 5390809ab69SJan Kara 5400809ab69SJan Kara /* is mark the first mark? */ 5419dd813c1SJan Kara if (hlist_empty(&conn->list)) { 5429dd813c1SJan Kara hlist_add_head_rcu(&mark->obj_list, &conn->list); 54386ffe245SJan Kara goto added; 5440809ab69SJan Kara } 5450809ab69SJan Kara 5460809ab69SJan Kara /* should mark be in the middle of the current list? */ 5479dd813c1SJan Kara hlist_for_each_entry(lmark, &conn->list, obj_list) { 5480809ab69SJan Kara last = lmark; 5490809ab69SJan Kara 5506b3f05d2SJan Kara if ((lmark->group == mark->group) && 5516b3f05d2SJan Kara (lmark->flags & FSNOTIFY_MARK_FLAG_ATTACHED) && 5526b3f05d2SJan Kara !allow_dups) { 553755b5bc6SJan Kara err = -EEXIST; 554755b5bc6SJan Kara goto out_err; 555755b5bc6SJan Kara } 5560809ab69SJan Kara 5570809ab69SJan Kara cmp = fsnotify_compare_groups(lmark->group, mark->group); 5580809ab69SJan Kara if (cmp >= 0) { 5590809ab69SJan Kara hlist_add_before_rcu(&mark->obj_list, &lmark->obj_list); 56086ffe245SJan Kara goto added; 5610809ab69SJan Kara } 5620809ab69SJan Kara } 5630809ab69SJan Kara 5640809ab69SJan Kara BUG_ON(last == NULL); 5650809ab69SJan Kara /* mark should be the last entry. last is the current last entry */ 5660809ab69SJan Kara hlist_add_behind_rcu(&mark->obj_list, &last->obj_list); 56786ffe245SJan Kara added: 56886ffe245SJan Kara mark->connector = conn; 569755b5bc6SJan Kara out_err: 57004662cabSJan Kara spin_unlock(&conn->lock); 571755b5bc6SJan Kara spin_unlock(&mark->lock); 572755b5bc6SJan Kara return err; 5730809ab69SJan Kara } 5740809ab69SJan Kara 5758edc6e16SJan Kara /* 5765444e298SEric Paris * Attach an initialized mark to a given group and fs object. 5775444e298SEric Paris * These marks may be used for the fsnotify backend to determine which 5785444e298SEric Paris * event types should be delivered to which group. 5795444e298SEric Paris */ 580d5a335b8SLino Sanfilippo int fsnotify_add_mark_locked(struct fsnotify_mark *mark, 5815444e298SEric Paris struct fsnotify_group *group, struct inode *inode, 5825444e298SEric Paris struct vfsmount *mnt, int allow_dups) 5835444e298SEric Paris { 5845444e298SEric Paris int ret = 0; 5855444e298SEric Paris 5865444e298SEric Paris BUG_ON(inode && mnt); 5875444e298SEric Paris BUG_ON(!inode && !mnt); 588d5a335b8SLino Sanfilippo BUG_ON(!mutex_is_locked(&group->mark_mutex)); 5895444e298SEric Paris 5905444e298SEric Paris /* 5915444e298SEric Paris * LOCKING ORDER!!!! 592986ab098SLino Sanfilippo * group->mark_mutex 593104d06f0SLino Sanfilippo * mark->lock 59404662cabSJan Kara * mark->connector->lock 5955444e298SEric Paris */ 596104d06f0SLino Sanfilippo spin_lock(&mark->lock); 5974712e722SJan Kara mark->flags |= FSNOTIFY_MARK_FLAG_ALIVE | FSNOTIFY_MARK_FLAG_ATTACHED; 598700307a2SEric Paris 59923e964c2SLino Sanfilippo fsnotify_get_group(group); 6005444e298SEric Paris mark->group = group; 6015444e298SEric Paris list_add(&mark->g_list, &group->marks_list); 6025444e298SEric Paris atomic_inc(&group->num_marks); 6036b3f05d2SJan Kara fsnotify_get_mark(mark); /* for g_list */ 6045444e298SEric Paris spin_unlock(&mark->lock); 6055444e298SEric Paris 606755b5bc6SJan Kara ret = fsnotify_add_mark_list(mark, inode, mnt, allow_dups); 607755b5bc6SJan Kara if (ret) 608755b5bc6SJan Kara goto err; 609755b5bc6SJan Kara 610a242677bSJan Kara if (mark->mask) 611a242677bSJan Kara fsnotify_recalc_mask(mark->connector); 6125444e298SEric Paris 6135444e298SEric Paris return ret; 6145444e298SEric Paris err: 61511375145SJan Kara mark->flags &= ~(FSNOTIFY_MARK_FLAG_ALIVE | 61611375145SJan Kara FSNOTIFY_MARK_FLAG_ATTACHED); 6175444e298SEric Paris list_del_init(&mark->g_list); 6185444e298SEric Paris atomic_dec(&group->num_marks); 6195444e298SEric Paris spin_unlock(&mark->lock); 6205444e298SEric Paris 62111375145SJan Kara fsnotify_put_mark(mark); 6225444e298SEric Paris return ret; 6235444e298SEric Paris } 6245444e298SEric Paris 625d5a335b8SLino Sanfilippo int fsnotify_add_mark(struct fsnotify_mark *mark, struct fsnotify_group *group, 626d5a335b8SLino Sanfilippo struct inode *inode, struct vfsmount *mnt, int allow_dups) 627d5a335b8SLino Sanfilippo { 628d5a335b8SLino Sanfilippo int ret; 629d5a335b8SLino Sanfilippo mutex_lock(&group->mark_mutex); 630d5a335b8SLino Sanfilippo ret = fsnotify_add_mark_locked(mark, group, inode, mnt, allow_dups); 631d5a335b8SLino Sanfilippo mutex_unlock(&group->mark_mutex); 632d5a335b8SLino Sanfilippo return ret; 633d5a335b8SLino Sanfilippo } 634d5a335b8SLino Sanfilippo 6355444e298SEric Paris /* 6360809ab69SJan Kara * Given a list of marks, find the mark associated with given group. If found 6370809ab69SJan Kara * take a reference to that mark and return it, else return NULL. 6380809ab69SJan Kara */ 63908991e83SJan Kara struct fsnotify_mark *fsnotify_find_mark( 64008991e83SJan Kara struct fsnotify_mark_connector __rcu **connp, 6410809ab69SJan Kara struct fsnotify_group *group) 6420809ab69SJan Kara { 64308991e83SJan Kara struct fsnotify_mark_connector *conn; 6440809ab69SJan Kara struct fsnotify_mark *mark; 6450809ab69SJan Kara 64608991e83SJan Kara conn = fsnotify_grab_connector(connp); 6479dd813c1SJan Kara if (!conn) 6489dd813c1SJan Kara return NULL; 6499dd813c1SJan Kara 6509dd813c1SJan Kara hlist_for_each_entry(mark, &conn->list, obj_list) { 6516b3f05d2SJan Kara if (mark->group == group && 6526b3f05d2SJan Kara (mark->flags & FSNOTIFY_MARK_FLAG_ATTACHED)) { 6530809ab69SJan Kara fsnotify_get_mark(mark); 65404662cabSJan Kara spin_unlock(&conn->lock); 6550809ab69SJan Kara return mark; 6560809ab69SJan Kara } 6570809ab69SJan Kara } 65804662cabSJan Kara spin_unlock(&conn->lock); 6590809ab69SJan Kara return NULL; 6600809ab69SJan Kara } 6610809ab69SJan Kara 6620809ab69SJan Kara /* 663d725e66cSLinus Torvalds * clear any marks in a group in which mark->flags & flags is true 6645444e298SEric Paris */ 6654d92604cSEric Paris void fsnotify_clear_marks_by_group_flags(struct fsnotify_group *group, 6664d92604cSEric Paris unsigned int flags) 6675444e298SEric Paris { 6685444e298SEric Paris struct fsnotify_mark *lmark, *mark; 6698f2f3eb5SJan Kara LIST_HEAD(to_free); 6705444e298SEric Paris 6718f2f3eb5SJan Kara /* 6728f2f3eb5SJan Kara * We have to be really careful here. Anytime we drop mark_mutex, e.g. 6738f2f3eb5SJan Kara * fsnotify_clear_marks_by_inode() can come and free marks. Even in our 6748f2f3eb5SJan Kara * to_free list so we have to use mark_mutex even when accessing that 6758f2f3eb5SJan Kara * list. And freeing mark requires us to drop mark_mutex. So we can 6768f2f3eb5SJan Kara * reliably free only the first mark in the list. That's why we first 6778f2f3eb5SJan Kara * move marks to free to to_free list in one go and then free marks in 6788f2f3eb5SJan Kara * to_free list one by one. 6798f2f3eb5SJan Kara */ 6806960b0d9SLino Sanfilippo mutex_lock_nested(&group->mark_mutex, SINGLE_DEPTH_NESTING); 6815444e298SEric Paris list_for_each_entry_safe(mark, lmark, &group->marks_list, g_list) { 68286ffe245SJan Kara if (mark->connector->flags & flags) 6838f2f3eb5SJan Kara list_move(&mark->g_list, &to_free); 6844d92604cSEric Paris } 685986ab098SLino Sanfilippo mutex_unlock(&group->mark_mutex); 6868f2f3eb5SJan Kara 6878f2f3eb5SJan Kara while (1) { 6888f2f3eb5SJan Kara mutex_lock_nested(&group->mark_mutex, SINGLE_DEPTH_NESTING); 6898f2f3eb5SJan Kara if (list_empty(&to_free)) { 6908f2f3eb5SJan Kara mutex_unlock(&group->mark_mutex); 6918f2f3eb5SJan Kara break; 6928f2f3eb5SJan Kara } 6938f2f3eb5SJan Kara mark = list_first_entry(&to_free, struct fsnotify_mark, g_list); 6948f2f3eb5SJan Kara fsnotify_get_mark(mark); 6954712e722SJan Kara fsnotify_detach_mark(mark); 6968f2f3eb5SJan Kara mutex_unlock(&group->mark_mutex); 6974712e722SJan Kara fsnotify_free_mark(mark); 6988f2f3eb5SJan Kara fsnotify_put_mark(mark); 6998f2f3eb5SJan Kara } 7005444e298SEric Paris } 7015444e298SEric Paris 7024d92604cSEric Paris /* 70335e48176SJan Kara * Given a group, prepare for freeing all the marks associated with that group. 70435e48176SJan Kara * The marks are attached to the list of marks prepared for destruction, the 70535e48176SJan Kara * caller is responsible for freeing marks in that list after SRCU period has 70635e48176SJan Kara * ended. 7074d92604cSEric Paris */ 70835e48176SJan Kara void fsnotify_detach_group_marks(struct fsnotify_group *group) 7094d92604cSEric Paris { 71035e48176SJan Kara struct fsnotify_mark *mark; 71135e48176SJan Kara 71235e48176SJan Kara while (1) { 71335e48176SJan Kara mutex_lock_nested(&group->mark_mutex, SINGLE_DEPTH_NESTING); 71435e48176SJan Kara if (list_empty(&group->marks_list)) { 71535e48176SJan Kara mutex_unlock(&group->mark_mutex); 71635e48176SJan Kara break; 71735e48176SJan Kara } 71835e48176SJan Kara mark = list_first_entry(&group->marks_list, 71935e48176SJan Kara struct fsnotify_mark, g_list); 72035e48176SJan Kara fsnotify_get_mark(mark); 72135e48176SJan Kara fsnotify_detach_mark(mark); 72235e48176SJan Kara mutex_unlock(&group->mark_mutex); 72311375145SJan Kara fsnotify_free_mark(mark); 72435e48176SJan Kara fsnotify_put_mark(mark); 72535e48176SJan Kara } 726*abc77577SJan Kara /* 727*abc77577SJan Kara * Some marks can still be pinned when waiting for response from 728*abc77577SJan Kara * userspace. Wait for those now. fsnotify_prepare_user_wait() will 729*abc77577SJan Kara * not succeed now so this wait is race-free. 730*abc77577SJan Kara */ 731*abc77577SJan Kara wait_event(group->notification_waitq, !atomic_read(&group->user_waits)); 7324d92604cSEric Paris } 7334d92604cSEric Paris 73408991e83SJan Kara /* Destroy all marks attached to inode / vfsmount */ 73508991e83SJan Kara void fsnotify_destroy_marks(struct fsnotify_mark_connector __rcu **connp) 7360810b4f9SJan Kara { 73708991e83SJan Kara struct fsnotify_mark_connector *conn; 7386b3f05d2SJan Kara struct fsnotify_mark *mark, *old_mark = NULL; 7396b3f05d2SJan Kara struct inode *inode; 7400810b4f9SJan Kara 7416b3f05d2SJan Kara conn = fsnotify_grab_connector(connp); 7426b3f05d2SJan Kara if (!conn) 7436b3f05d2SJan Kara return; 7440810b4f9SJan Kara /* 7450810b4f9SJan Kara * We have to be careful since we can race with e.g. 7466b3f05d2SJan Kara * fsnotify_clear_marks_by_group() and once we drop the conn->lock, the 7476b3f05d2SJan Kara * list can get modified. However we are holding mark reference and 7486b3f05d2SJan Kara * thus our mark cannot be removed from obj_list so we can continue 7496b3f05d2SJan Kara * iteration after regaining conn->lock. 7500810b4f9SJan Kara */ 7516b3f05d2SJan Kara hlist_for_each_entry(mark, &conn->list, obj_list) { 7520810b4f9SJan Kara fsnotify_get_mark(mark); 75304662cabSJan Kara spin_unlock(&conn->lock); 7546b3f05d2SJan Kara if (old_mark) 7556b3f05d2SJan Kara fsnotify_put_mark(old_mark); 7566b3f05d2SJan Kara old_mark = mark; 7570810b4f9SJan Kara fsnotify_destroy_mark(mark, mark->group); 7586b3f05d2SJan Kara spin_lock(&conn->lock); 7590810b4f9SJan Kara } 7606b3f05d2SJan Kara /* 7616b3f05d2SJan Kara * Detach list from object now so that we don't pin inode until all 7626b3f05d2SJan Kara * mark references get dropped. It would lead to strange results such 7636b3f05d2SJan Kara * as delaying inode deletion or blocking unmount. 7646b3f05d2SJan Kara */ 7656b3f05d2SJan Kara inode = fsnotify_detach_connector_from_object(conn); 7666b3f05d2SJan Kara spin_unlock(&conn->lock); 7676b3f05d2SJan Kara if (old_mark) 7686b3f05d2SJan Kara fsnotify_put_mark(old_mark); 7696b3f05d2SJan Kara iput(inode); 7700810b4f9SJan Kara } 7710810b4f9SJan Kara 7725444e298SEric Paris /* 7735444e298SEric Paris * Nothing fancy, just initialize lists and locks and counters. 7745444e298SEric Paris */ 7755444e298SEric Paris void fsnotify_init_mark(struct fsnotify_mark *mark, 7765444e298SEric Paris void (*free_mark)(struct fsnotify_mark *mark)) 7775444e298SEric Paris { 778ba643f04SEric Paris memset(mark, 0, sizeof(*mark)); 7795444e298SEric Paris spin_lock_init(&mark->lock); 7805444e298SEric Paris atomic_set(&mark->refcnt, 1); 7815444e298SEric Paris mark->free_mark = free_mark; 7825444e298SEric Paris } 78313d34ac6SJeff Layton 78435e48176SJan Kara /* 78535e48176SJan Kara * Destroy all marks in destroy_list, waits for SRCU period to finish before 78635e48176SJan Kara * actually freeing marks. 78735e48176SJan Kara */ 788f09b04a0SJan Kara static void fsnotify_mark_destroy_workfn(struct work_struct *work) 78913d34ac6SJeff Layton { 79013d34ac6SJeff Layton struct fsnotify_mark *mark, *next; 79113d34ac6SJeff Layton struct list_head private_destroy_list; 79213d34ac6SJeff Layton 79313d34ac6SJeff Layton spin_lock(&destroy_lock); 79413d34ac6SJeff Layton /* exchange the list head */ 79513d34ac6SJeff Layton list_replace_init(&destroy_list, &private_destroy_list); 79613d34ac6SJeff Layton spin_unlock(&destroy_lock); 79713d34ac6SJeff Layton 79813d34ac6SJeff Layton synchronize_srcu(&fsnotify_mark_srcu); 79913d34ac6SJeff Layton 80013d34ac6SJeff Layton list_for_each_entry_safe(mark, next, &private_destroy_list, g_list) { 80113d34ac6SJeff Layton list_del_init(&mark->g_list); 8026b3f05d2SJan Kara fsnotify_final_mark_destroy(mark); 80313d34ac6SJeff Layton } 80413d34ac6SJeff Layton } 80535e48176SJan Kara 806f09b04a0SJan Kara /* Wait for all marks queued for destruction to be actually destroyed */ 807f09b04a0SJan Kara void fsnotify_wait_marks_destroyed(void) 80835e48176SJan Kara { 809f09b04a0SJan Kara flush_delayed_work(&reaper_work); 81035e48176SJan Kara } 811