xref: /linux/fs/notify/mark.c (revision 1c9007d62bea6fd164285314f7553f73e5308863)
1c82ee6d3SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
25444e298SEric Paris /*
35444e298SEric Paris  *  Copyright (C) 2008 Red Hat, Inc., Eric Paris <eparis@redhat.com>
45444e298SEric Paris  */
55444e298SEric Paris 
65444e298SEric Paris /*
75444e298SEric Paris  * fsnotify inode mark locking/lifetime/and refcnting
85444e298SEric Paris  *
95444e298SEric Paris  * REFCNT:
109756b918SLino Sanfilippo  * The group->recnt and mark->refcnt tell how many "things" in the kernel
119756b918SLino Sanfilippo  * currently are referencing the objects. Both kind of objects typically will
129756b918SLino Sanfilippo  * live inside the kernel with a refcnt of 2, one for its creation and one for
139756b918SLino Sanfilippo  * the reference a group and a mark hold to each other.
149756b918SLino Sanfilippo  * If you are holding the appropriate locks, you can take a reference and the
159756b918SLino Sanfilippo  * object itself is guaranteed to survive until the reference is dropped.
165444e298SEric Paris  *
175444e298SEric Paris  * LOCKING:
189756b918SLino Sanfilippo  * There are 3 locks involved with fsnotify inode marks and they MUST be taken
199756b918SLino Sanfilippo  * in order as follows:
205444e298SEric Paris  *
219756b918SLino Sanfilippo  * group->mark_mutex
225444e298SEric Paris  * mark->lock
2304662cabSJan Kara  * mark->connector->lock
245444e298SEric Paris  *
259756b918SLino Sanfilippo  * group->mark_mutex protects the marks_list anchored inside a given group and
269756b918SLino Sanfilippo  * each mark is hooked via the g_list.  It also protects the groups private
279756b918SLino Sanfilippo  * data (i.e group limits).
289756b918SLino Sanfilippo 
299756b918SLino Sanfilippo  * mark->lock protects the marks attributes like its masks and flags.
309756b918SLino Sanfilippo  * Furthermore it protects the access to a reference of the group that the mark
319756b918SLino Sanfilippo  * is assigned to as well as the access to a reference of the inode/vfsmount
329756b918SLino Sanfilippo  * that is being watched by the mark.
335444e298SEric Paris  *
3404662cabSJan Kara  * mark->connector->lock protects the list of marks anchored inside an
3504662cabSJan Kara  * inode / vfsmount and each mark is hooked via the i_list.
365444e298SEric Paris  *
3704662cabSJan Kara  * A list of notification marks relating to inode / mnt is contained in
3804662cabSJan Kara  * fsnotify_mark_connector. That structure is alive as long as there are any
396b3f05d2SJan Kara  * marks in the list and is also protected by fsnotify_mark_srcu. A mark gets
406b3f05d2SJan Kara  * detached from fsnotify_mark_connector when last reference to the mark is
416b3f05d2SJan Kara  * dropped.  Thus having mark reference is enough to protect mark->connector
426b3f05d2SJan Kara  * pointer and to make sure fsnotify_mark_connector cannot disappear. Also
436b3f05d2SJan Kara  * because we remove mark from g_list before dropping mark reference associated
446b3f05d2SJan Kara  * with that, any mark found through g_list is guaranteed to have
456b3f05d2SJan Kara  * mark->connector set until we drop group->mark_mutex.
465444e298SEric Paris  *
475444e298SEric Paris  * LIFETIME:
485444e298SEric Paris  * Inode marks survive between when they are added to an inode and when their
49c1f33073SJan Kara  * refcnt==0. Marks are also protected by fsnotify_mark_srcu.
505444e298SEric Paris  *
515444e298SEric Paris  * The inode mark can be cleared for a number of different reasons including:
525444e298SEric Paris  * - The inode is unlinked for the last time.  (fsnotify_inode_remove)
535444e298SEric Paris  * - The inode is being evicted from cache. (fsnotify_inode_delete)
545444e298SEric Paris  * - The fs the inode is on is unmounted.  (fsnotify_inode_delete/fsnotify_unmount_inodes)
555444e298SEric Paris  * - Something explicitly requests that it be removed.  (fsnotify_destroy_mark)
565444e298SEric Paris  * - The fsnotify_group associated with the mark is going away and all such marks
572e37c6caSJan Kara  *   need to be cleaned up. (fsnotify_clear_marks_by_group)
585444e298SEric Paris  *
595444e298SEric Paris  * This has the very interesting property of being able to run concurrently with
605444e298SEric Paris  * any (or all) other directions.
615444e298SEric Paris  */
625444e298SEric Paris 
635444e298SEric Paris #include <linux/fs.h>
645444e298SEric Paris #include <linux/init.h>
655444e298SEric Paris #include <linux/kernel.h>
6675c1be48SEric Paris #include <linux/kthread.h>
675444e298SEric Paris #include <linux/module.h>
685444e298SEric Paris #include <linux/mutex.h>
695444e298SEric Paris #include <linux/slab.h>
705444e298SEric Paris #include <linux/spinlock.h>
7175c1be48SEric Paris #include <linux/srcu.h>
7277115225SAmir Goldstein #include <linux/ratelimit.h>
735444e298SEric Paris 
7460063497SArun Sharma #include <linux/atomic.h>
755444e298SEric Paris 
765444e298SEric Paris #include <linux/fsnotify_backend.h>
775444e298SEric Paris #include "fsnotify.h"
785444e298SEric Paris 
790918f1c3SJeff Layton #define FSNOTIFY_REAPER_DELAY	(1)	/* 1 jiffy */
800918f1c3SJeff Layton 
8175c1be48SEric Paris struct srcu_struct fsnotify_mark_srcu;
829dd813c1SJan Kara struct kmem_cache *fsnotify_mark_connector_cachep;
839dd813c1SJan Kara 
8413d34ac6SJeff Layton static DEFINE_SPINLOCK(destroy_lock);
8513d34ac6SJeff Layton static LIST_HEAD(destroy_list);
8608991e83SJan Kara static struct fsnotify_mark_connector *connector_destroy_list;
870918f1c3SJeff Layton 
8835e48176SJan Kara static void fsnotify_mark_destroy_workfn(struct work_struct *work);
8935e48176SJan Kara static DECLARE_DELAYED_WORK(reaper_work, fsnotify_mark_destroy_workfn);
9075c1be48SEric Paris 
9108991e83SJan Kara static void fsnotify_connector_destroy_workfn(struct work_struct *work);
9208991e83SJan Kara static DECLARE_WORK(connector_reaper_work, fsnotify_connector_destroy_workfn);
9308991e83SJan Kara 
945444e298SEric Paris void fsnotify_get_mark(struct fsnotify_mark *mark)
955444e298SEric Paris {
96ab97f873SElena Reshetova 	WARN_ON_ONCE(!refcount_read(&mark->refcnt));
97ab97f873SElena Reshetova 	refcount_inc(&mark->refcnt);
985444e298SEric Paris }
995444e298SEric Paris 
1003ac70bfcSAmir Goldstein static __u32 *fsnotify_conn_mask_p(struct fsnotify_mark_connector *conn)
1013ac70bfcSAmir Goldstein {
1023ac70bfcSAmir Goldstein 	if (conn->type == FSNOTIFY_OBJ_TYPE_INODE)
1033ac70bfcSAmir Goldstein 		return &fsnotify_conn_inode(conn)->i_fsnotify_mask;
1043ac70bfcSAmir Goldstein 	else if (conn->type == FSNOTIFY_OBJ_TYPE_VFSMOUNT)
1053ac70bfcSAmir Goldstein 		return &fsnotify_conn_mount(conn)->mnt_fsnotify_mask;
1061e6cb723SAmir Goldstein 	else if (conn->type == FSNOTIFY_OBJ_TYPE_SB)
1071e6cb723SAmir Goldstein 		return &fsnotify_conn_sb(conn)->s_fsnotify_mask;
1083ac70bfcSAmir Goldstein 	return NULL;
1093ac70bfcSAmir Goldstein }
1103ac70bfcSAmir Goldstein 
1113ac70bfcSAmir Goldstein __u32 fsnotify_conn_mask(struct fsnotify_mark_connector *conn)
1123ac70bfcSAmir Goldstein {
1133ac70bfcSAmir Goldstein 	if (WARN_ON(!fsnotify_valid_obj_type(conn->type)))
1143ac70bfcSAmir Goldstein 		return 0;
1153ac70bfcSAmir Goldstein 
1163ac70bfcSAmir Goldstein 	return *fsnotify_conn_mask_p(conn);
1173ac70bfcSAmir Goldstein }
1183ac70bfcSAmir Goldstein 
119a242677bSJan Kara static void __fsnotify_recalc_mask(struct fsnotify_mark_connector *conn)
1200809ab69SJan Kara {
1210809ab69SJan Kara 	u32 new_mask = 0;
1220809ab69SJan Kara 	struct fsnotify_mark *mark;
1230809ab69SJan Kara 
12404662cabSJan Kara 	assert_spin_locked(&conn->lock);
125d3bc0fa8SJan Kara 	/* We can get detached connector here when inode is getting unlinked. */
126d3bc0fa8SJan Kara 	if (!fsnotify_valid_obj_type(conn->type))
127d3bc0fa8SJan Kara 		return;
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 	}
1323ac70bfcSAmir Goldstein 	*fsnotify_conn_mask_p(conn) = new_mask;
133a242677bSJan Kara }
134a242677bSJan Kara 
135a242677bSJan Kara /*
136a242677bSJan Kara  * Calculate mask of events for a list of marks. The caller must make sure
13736f10f55SAmir Goldstein  * connector and connector->obj cannot disappear under us.  Callers achieve
1386b3f05d2SJan Kara  * this by holding a mark->lock or mark->group->mark_mutex for a mark on this
1396b3f05d2SJan Kara  * list.
140a242677bSJan Kara  */
141a242677bSJan Kara void fsnotify_recalc_mask(struct fsnotify_mark_connector *conn)
142a242677bSJan Kara {
143a242677bSJan Kara 	if (!conn)
144a242677bSJan Kara 		return;
145a242677bSJan Kara 
14604662cabSJan Kara 	spin_lock(&conn->lock);
147a242677bSJan Kara 	__fsnotify_recalc_mask(conn);
14804662cabSJan Kara 	spin_unlock(&conn->lock);
149d6f7b98bSAmir Goldstein 	if (conn->type == FSNOTIFY_OBJ_TYPE_INODE)
15036f10f55SAmir Goldstein 		__fsnotify_update_child_dentry_flags(
15136f10f55SAmir Goldstein 					fsnotify_conn_inode(conn));
1520809ab69SJan Kara }
1530809ab69SJan Kara 
15408991e83SJan Kara /* Free all connectors queued for freeing once SRCU period ends */
15508991e83SJan Kara static void fsnotify_connector_destroy_workfn(struct work_struct *work)
15608991e83SJan Kara {
15708991e83SJan Kara 	struct fsnotify_mark_connector *conn, *free;
15808991e83SJan Kara 
15908991e83SJan Kara 	spin_lock(&destroy_lock);
16008991e83SJan Kara 	conn = connector_destroy_list;
16108991e83SJan Kara 	connector_destroy_list = NULL;
16208991e83SJan Kara 	spin_unlock(&destroy_lock);
16308991e83SJan Kara 
16408991e83SJan Kara 	synchronize_srcu(&fsnotify_mark_srcu);
16508991e83SJan Kara 	while (conn) {
16608991e83SJan Kara 		free = conn;
16708991e83SJan Kara 		conn = conn->destroy_next;
16808991e83SJan Kara 		kmem_cache_free(fsnotify_mark_connector_cachep, free);
16908991e83SJan Kara 	}
17008991e83SJan Kara }
17108991e83SJan Kara 
17211fa333bSAmir Goldstein static void fsnotify_get_inode_ref(struct inode *inode)
17311fa333bSAmir Goldstein {
17411fa333bSAmir Goldstein 	ihold(inode);
175ec44610fSAmir Goldstein 	atomic_long_inc(&inode->i_sb->s_fsnotify_connectors);
17611fa333bSAmir Goldstein }
17711fa333bSAmir Goldstein 
17811fa333bSAmir Goldstein static void fsnotify_put_inode_ref(struct inode *inode)
17911fa333bSAmir Goldstein {
18011fa333bSAmir Goldstein 	struct super_block *sb = inode->i_sb;
18111fa333bSAmir Goldstein 
18211fa333bSAmir Goldstein 	iput(inode);
183ec44610fSAmir Goldstein 	if (atomic_long_dec_and_test(&sb->s_fsnotify_connectors))
184ec44610fSAmir Goldstein 		wake_up_var(&sb->s_fsnotify_connectors);
185ec44610fSAmir Goldstein }
186ec44610fSAmir Goldstein 
187ec44610fSAmir Goldstein static void fsnotify_get_sb_connectors(struct fsnotify_mark_connector *conn)
188ec44610fSAmir Goldstein {
189ec44610fSAmir Goldstein 	struct super_block *sb = fsnotify_connector_sb(conn);
190ec44610fSAmir Goldstein 
191ec44610fSAmir Goldstein 	if (sb)
192ec44610fSAmir Goldstein 		atomic_long_inc(&sb->s_fsnotify_connectors);
193ec44610fSAmir Goldstein }
194ec44610fSAmir Goldstein 
195ec44610fSAmir Goldstein static void fsnotify_put_sb_connectors(struct fsnotify_mark_connector *conn)
196ec44610fSAmir Goldstein {
197ec44610fSAmir Goldstein 	struct super_block *sb = fsnotify_connector_sb(conn);
198ec44610fSAmir Goldstein 
199ec44610fSAmir Goldstein 	if (sb && atomic_long_dec_and_test(&sb->s_fsnotify_connectors))
200ec44610fSAmir Goldstein 		wake_up_var(&sb->s_fsnotify_connectors);
20111fa333bSAmir Goldstein }
20211fa333bSAmir Goldstein 
203721fb6fbSJan Kara static void *fsnotify_detach_connector_from_object(
204721fb6fbSJan Kara 					struct fsnotify_mark_connector *conn,
205721fb6fbSJan Kara 					unsigned int *type)
20608991e83SJan Kara {
20708991e83SJan Kara 	struct inode *inode = NULL;
20808991e83SJan Kara 
209721fb6fbSJan Kara 	*type = conn->type;
21036f10f55SAmir Goldstein 	if (conn->type == FSNOTIFY_OBJ_TYPE_DETACHED)
21136f10f55SAmir Goldstein 		return NULL;
21236f10f55SAmir Goldstein 
213d6f7b98bSAmir Goldstein 	if (conn->type == FSNOTIFY_OBJ_TYPE_INODE) {
21436f10f55SAmir Goldstein 		inode = fsnotify_conn_inode(conn);
21508991e83SJan Kara 		inode->i_fsnotify_mask = 0;
216d6f7b98bSAmir Goldstein 	} else if (conn->type == FSNOTIFY_OBJ_TYPE_VFSMOUNT) {
21736f10f55SAmir Goldstein 		fsnotify_conn_mount(conn)->mnt_fsnotify_mask = 0;
2181e6cb723SAmir Goldstein 	} else if (conn->type == FSNOTIFY_OBJ_TYPE_SB) {
2191e6cb723SAmir Goldstein 		fsnotify_conn_sb(conn)->s_fsnotify_mask = 0;
22008991e83SJan Kara 	}
22108991e83SJan Kara 
222ec44610fSAmir Goldstein 	fsnotify_put_sb_connectors(conn);
22336f10f55SAmir Goldstein 	rcu_assign_pointer(*(conn->obj), NULL);
22436f10f55SAmir Goldstein 	conn->obj = NULL;
22536f10f55SAmir Goldstein 	conn->type = FSNOTIFY_OBJ_TYPE_DETACHED;
22636f10f55SAmir Goldstein 
22708991e83SJan Kara 	return inode;
22808991e83SJan Kara }
22908991e83SJan Kara 
2306b3f05d2SJan Kara static void fsnotify_final_mark_destroy(struct fsnotify_mark *mark)
2316b3f05d2SJan Kara {
232054c636eSJan Kara 	struct fsnotify_group *group = mark->group;
233054c636eSJan Kara 
234054c636eSJan Kara 	if (WARN_ON_ONCE(!group))
235054c636eSJan Kara 		return;
236054c636eSJan Kara 	group->ops->free_mark(mark);
237054c636eSJan Kara 	fsnotify_put_group(group);
2386b3f05d2SJan Kara }
2396b3f05d2SJan Kara 
240721fb6fbSJan Kara /* Drop object reference originally held by a connector */
241721fb6fbSJan Kara static void fsnotify_drop_object(unsigned int type, void *objp)
242721fb6fbSJan Kara {
243721fb6fbSJan Kara 	if (!objp)
244721fb6fbSJan Kara 		return;
245721fb6fbSJan Kara 	/* Currently only inode references are passed to be dropped */
246721fb6fbSJan Kara 	if (WARN_ON_ONCE(type != FSNOTIFY_OBJ_TYPE_INODE))
247721fb6fbSJan Kara 		return;
24811fa333bSAmir Goldstein 	fsnotify_put_inode_ref(objp);
249721fb6fbSJan Kara }
250721fb6fbSJan Kara 
2516b3f05d2SJan Kara void fsnotify_put_mark(struct fsnotify_mark *mark)
2528212a609SJan Kara {
253b1da6a51SJan Kara 	struct fsnotify_mark_connector *conn = READ_ONCE(mark->connector);
254721fb6fbSJan Kara 	void *objp = NULL;
255721fb6fbSJan Kara 	unsigned int type = FSNOTIFY_OBJ_TYPE_DETACHED;
25608991e83SJan Kara 	bool free_conn = false;
2578212a609SJan Kara 
2586b3f05d2SJan Kara 	/* Catch marks that were actually never attached to object */
259b1da6a51SJan Kara 	if (!conn) {
260ab97f873SElena Reshetova 		if (refcount_dec_and_test(&mark->refcnt))
2616b3f05d2SJan Kara 			fsnotify_final_mark_destroy(mark);
2626b3f05d2SJan Kara 		return;
2636b3f05d2SJan Kara 	}
2646b3f05d2SJan Kara 
2656b3f05d2SJan Kara 	/*
2666b3f05d2SJan Kara 	 * We have to be careful so that traversals of obj_list under lock can
2676b3f05d2SJan Kara 	 * safely grab mark reference.
2686b3f05d2SJan Kara 	 */
269b1da6a51SJan Kara 	if (!refcount_dec_and_lock(&mark->refcnt, &conn->lock))
2706b3f05d2SJan Kara 		return;
2716b3f05d2SJan Kara 
2728212a609SJan Kara 	hlist_del_init_rcu(&mark->obj_list);
2738212a609SJan Kara 	if (hlist_empty(&conn->list)) {
274721fb6fbSJan Kara 		objp = fsnotify_detach_connector_from_object(conn, &type);
27508991e83SJan Kara 		free_conn = true;
27608991e83SJan Kara 	} else {
27773cd3c33SJan Kara 		__fsnotify_recalc_mask(conn);
27808991e83SJan Kara 	}
279b1da6a51SJan Kara 	WRITE_ONCE(mark->connector, NULL);
28004662cabSJan Kara 	spin_unlock(&conn->lock);
2818212a609SJan Kara 
282721fb6fbSJan Kara 	fsnotify_drop_object(type, objp);
2836b3f05d2SJan Kara 
28408991e83SJan Kara 	if (free_conn) {
28508991e83SJan Kara 		spin_lock(&destroy_lock);
28608991e83SJan Kara 		conn->destroy_next = connector_destroy_list;
28708991e83SJan Kara 		connector_destroy_list = conn;
28808991e83SJan Kara 		spin_unlock(&destroy_lock);
28908991e83SJan Kara 		queue_work(system_unbound_wq, &connector_reaper_work);
29008991e83SJan Kara 	}
2916b3f05d2SJan Kara 	/*
2926b3f05d2SJan Kara 	 * Note that we didn't update flags telling whether inode cares about
2936b3f05d2SJan Kara 	 * what's happening with children. We update these flags from
2946b3f05d2SJan Kara 	 * __fsnotify_parent() lazily when next event happens on one of our
2956b3f05d2SJan Kara 	 * children.
2966b3f05d2SJan Kara 	 */
2976b3f05d2SJan Kara 	spin_lock(&destroy_lock);
2986b3f05d2SJan Kara 	list_add(&mark->g_list, &destroy_list);
2996b3f05d2SJan Kara 	spin_unlock(&destroy_lock);
3006b3f05d2SJan Kara 	queue_delayed_work(system_unbound_wq, &reaper_work,
3016b3f05d2SJan Kara 			   FSNOTIFY_REAPER_DELAY);
3028212a609SJan Kara }
303b72679eeSTrond Myklebust EXPORT_SYMBOL_GPL(fsnotify_put_mark);
3048212a609SJan Kara 
30524c20305SMiklos Szeredi /*
30624c20305SMiklos Szeredi  * Get mark reference when we found the mark via lockless traversal of object
30724c20305SMiklos Szeredi  * list. Mark can be already removed from the list by now and on its way to be
30824c20305SMiklos Szeredi  * destroyed once SRCU period ends.
30924c20305SMiklos Szeredi  *
31024c20305SMiklos Szeredi  * Also pin the group so it doesn't disappear under us.
31124c20305SMiklos Szeredi  */
31224c20305SMiklos Szeredi static bool fsnotify_get_mark_safe(struct fsnotify_mark *mark)
313abc77577SJan Kara {
31424c20305SMiklos Szeredi 	if (!mark)
31524c20305SMiklos Szeredi 		return true;
316abc77577SJan Kara 
317ab97f873SElena Reshetova 	if (refcount_inc_not_zero(&mark->refcnt)) {
3189a31d7adSMiklos Szeredi 		spin_lock(&mark->lock);
3199a31d7adSMiklos Szeredi 		if (mark->flags & FSNOTIFY_MARK_FLAG_ATTACHED) {
3209a31d7adSMiklos Szeredi 			/* mark is attached, group is still alive then */
3219a31d7adSMiklos Szeredi 			atomic_inc(&mark->group->user_waits);
3229a31d7adSMiklos Szeredi 			spin_unlock(&mark->lock);
32324c20305SMiklos Szeredi 			return true;
3249a31d7adSMiklos Szeredi 		}
3259a31d7adSMiklos Szeredi 		spin_unlock(&mark->lock);
3269a31d7adSMiklos Szeredi 		fsnotify_put_mark(mark);
3279a31d7adSMiklos Szeredi 	}
32824c20305SMiklos Szeredi 	return false;
32924c20305SMiklos Szeredi }
33024c20305SMiklos Szeredi 
33124c20305SMiklos Szeredi /*
33224c20305SMiklos Szeredi  * Puts marks and wakes up group destruction if necessary.
33324c20305SMiklos Szeredi  *
33424c20305SMiklos Szeredi  * Pairs with fsnotify_get_mark_safe()
33524c20305SMiklos Szeredi  */
33624c20305SMiklos Szeredi static void fsnotify_put_mark_wake(struct fsnotify_mark *mark)
33724c20305SMiklos Szeredi {
33824c20305SMiklos Szeredi 	if (mark) {
33924c20305SMiklos Szeredi 		struct fsnotify_group *group = mark->group;
34024c20305SMiklos Szeredi 
34124c20305SMiklos Szeredi 		fsnotify_put_mark(mark);
34224c20305SMiklos Szeredi 		/*
34324c20305SMiklos Szeredi 		 * We abuse notification_waitq on group shutdown for waiting for
34424c20305SMiklos Szeredi 		 * all marks pinned when waiting for userspace.
34524c20305SMiklos Szeredi 		 */
34624c20305SMiklos Szeredi 		if (atomic_dec_and_test(&group->user_waits) && group->shutdown)
34724c20305SMiklos Szeredi 			wake_up(&group->notification_waitq);
34824c20305SMiklos Szeredi 	}
34924c20305SMiklos Szeredi }
35024c20305SMiklos Szeredi 
35124c20305SMiklos Szeredi bool fsnotify_prepare_user_wait(struct fsnotify_iter_info *iter_info)
35200e0afb6SJules Irenge 	__releases(&fsnotify_mark_srcu)
35324c20305SMiklos Szeredi {
35447d9c7ccSAmir Goldstein 	int type;
35547d9c7ccSAmir Goldstein 
356*1c9007d6SAmir Goldstein 	fsnotify_foreach_iter_type(type) {
357abc77577SJan Kara 		/* This can fail if mark is being removed */
35800e0afb6SJules Irenge 		if (!fsnotify_get_mark_safe(iter_info->marks[type])) {
35900e0afb6SJules Irenge 			__release(&fsnotify_mark_srcu);
36047d9c7ccSAmir Goldstein 			goto fail;
361abc77577SJan Kara 		}
36200e0afb6SJules Irenge 	}
363abc77577SJan Kara 
364abc77577SJan Kara 	/*
365abc77577SJan Kara 	 * Now that both marks are pinned by refcount in the inode / vfsmount
366abc77577SJan Kara 	 * lists, we can drop SRCU lock, and safely resume the list iteration
367abc77577SJan Kara 	 * once userspace returns.
368abc77577SJan Kara 	 */
369abc77577SJan Kara 	srcu_read_unlock(&fsnotify_mark_srcu, iter_info->srcu_idx);
370abc77577SJan Kara 
371abc77577SJan Kara 	return true;
37247d9c7ccSAmir Goldstein 
37347d9c7ccSAmir Goldstein fail:
37447d9c7ccSAmir Goldstein 	for (type--; type >= 0; type--)
37547d9c7ccSAmir Goldstein 		fsnotify_put_mark_wake(iter_info->marks[type]);
37647d9c7ccSAmir Goldstein 	return false;
377abc77577SJan Kara }
378abc77577SJan Kara 
379abc77577SJan Kara void fsnotify_finish_user_wait(struct fsnotify_iter_info *iter_info)
38000e0afb6SJules Irenge 	__acquires(&fsnotify_mark_srcu)
381abc77577SJan Kara {
38247d9c7ccSAmir Goldstein 	int type;
38347d9c7ccSAmir Goldstein 
384abc77577SJan Kara 	iter_info->srcu_idx = srcu_read_lock(&fsnotify_mark_srcu);
385*1c9007d6SAmir Goldstein 	fsnotify_foreach_iter_type(type)
38647d9c7ccSAmir Goldstein 		fsnotify_put_mark_wake(iter_info->marks[type]);
387abc77577SJan Kara }
388abc77577SJan Kara 
3895444e298SEric Paris /*
3906b3f05d2SJan Kara  * Mark mark as detached, remove it from group list. Mark still stays in object
3916b3f05d2SJan Kara  * list until its last reference is dropped. Note that we rely on mark being
3926b3f05d2SJan Kara  * removed from group list before corresponding reference to it is dropped. In
3936b3f05d2SJan Kara  * particular we rely on mark->connector being valid while we hold
3946b3f05d2SJan Kara  * group->mark_mutex if we found the mark through g_list.
3954712e722SJan Kara  *
39611375145SJan Kara  * Must be called with group->mark_mutex held. The caller must either hold
39711375145SJan Kara  * reference to the mark or be protected by fsnotify_mark_srcu.
3985444e298SEric Paris  */
3994712e722SJan Kara void fsnotify_detach_mark(struct fsnotify_mark *mark)
4005444e298SEric Paris {
4014712e722SJan Kara 	struct fsnotify_group *group = mark->group;
4025444e298SEric Paris 
40311375145SJan Kara 	WARN_ON_ONCE(!mutex_is_locked(&group->mark_mutex));
40411375145SJan Kara 	WARN_ON_ONCE(!srcu_read_lock_held(&fsnotify_mark_srcu) &&
405ab97f873SElena Reshetova 		     refcount_read(&mark->refcnt) < 1 +
40611375145SJan Kara 			!!(mark->flags & FSNOTIFY_MARK_FLAG_ATTACHED));
407d5a335b8SLino Sanfilippo 
408104d06f0SLino Sanfilippo 	spin_lock(&mark->lock);
409700307a2SEric Paris 	/* something else already called this function on this mark */
4104712e722SJan Kara 	if (!(mark->flags & FSNOTIFY_MARK_FLAG_ATTACHED)) {
4115444e298SEric Paris 		spin_unlock(&mark->lock);
412e2a29943SLino Sanfilippo 		return;
4135444e298SEric Paris 	}
4144712e722SJan Kara 	mark->flags &= ~FSNOTIFY_MARK_FLAG_ATTACHED;
4155444e298SEric Paris 	list_del_init(&mark->g_list);
4165444e298SEric Paris 	spin_unlock(&mark->lock);
417d5a335b8SLino Sanfilippo 
41811375145SJan Kara 	/* Drop mark reference acquired in fsnotify_add_mark_locked() */
41911375145SJan Kara 	fsnotify_put_mark(mark);
4204712e722SJan Kara }
4214712e722SJan Kara 
4224712e722SJan Kara /*
42311375145SJan Kara  * Free fsnotify mark. The mark is actually only marked as being freed.  The
42411375145SJan Kara  * freeing is actually happening only once last reference to the mark is
42511375145SJan Kara  * dropped from a workqueue which first waits for srcu period end.
42635e48176SJan Kara  *
42711375145SJan Kara  * Caller must have a reference to the mark or be protected by
42811375145SJan Kara  * fsnotify_mark_srcu.
4294712e722SJan Kara  */
43011375145SJan Kara void fsnotify_free_mark(struct fsnotify_mark *mark)
4314712e722SJan Kara {
4324712e722SJan Kara 	struct fsnotify_group *group = mark->group;
4334712e722SJan Kara 
4344712e722SJan Kara 	spin_lock(&mark->lock);
4354712e722SJan Kara 	/* something else already called this function on this mark */
4364712e722SJan Kara 	if (!(mark->flags & FSNOTIFY_MARK_FLAG_ALIVE)) {
4374712e722SJan Kara 		spin_unlock(&mark->lock);
43811375145SJan Kara 		return;
4394712e722SJan Kara 	}
4404712e722SJan Kara 	mark->flags &= ~FSNOTIFY_MARK_FLAG_ALIVE;
4414712e722SJan Kara 	spin_unlock(&mark->lock);
4425444e298SEric Paris 
443d725e66cSLinus Torvalds 	/*
444d725e66cSLinus Torvalds 	 * Some groups like to know that marks are being freed.  This is a
445d725e66cSLinus Torvalds 	 * callback to the group function to let it know that this mark
446d725e66cSLinus Torvalds 	 * is being freed.
447d725e66cSLinus Torvalds 	 */
448d725e66cSLinus Torvalds 	if (group->ops->freeing_mark)
449d725e66cSLinus Torvalds 		group->ops->freeing_mark(mark, group);
450d5a335b8SLino Sanfilippo }
451d5a335b8SLino Sanfilippo 
452d5a335b8SLino Sanfilippo void fsnotify_destroy_mark(struct fsnotify_mark *mark,
453d5a335b8SLino Sanfilippo 			   struct fsnotify_group *group)
454d5a335b8SLino Sanfilippo {
4556960b0d9SLino Sanfilippo 	mutex_lock_nested(&group->mark_mutex, SINGLE_DEPTH_NESTING);
4564712e722SJan Kara 	fsnotify_detach_mark(mark);
457d5a335b8SLino Sanfilippo 	mutex_unlock(&group->mark_mutex);
4584712e722SJan Kara 	fsnotify_free_mark(mark);
4595444e298SEric Paris }
460b72679eeSTrond Myklebust EXPORT_SYMBOL_GPL(fsnotify_destroy_mark);
4615444e298SEric Paris 
4625444e298SEric Paris /*
4638edc6e16SJan Kara  * Sorting function for lists of fsnotify marks.
4648edc6e16SJan Kara  *
4658edc6e16SJan Kara  * Fanotify supports different notification classes (reflected as priority of
4668edc6e16SJan Kara  * notification group). Events shall be passed to notification groups in
4678edc6e16SJan Kara  * decreasing priority order. To achieve this marks in notification lists for
4688edc6e16SJan Kara  * inodes and vfsmounts are sorted so that priorities of corresponding groups
4698edc6e16SJan Kara  * are descending.
4708edc6e16SJan Kara  *
4718edc6e16SJan Kara  * Furthermore correct handling of the ignore mask requires processing inode
4728edc6e16SJan Kara  * and vfsmount marks of each group together. Using the group address as
4738edc6e16SJan Kara  * further sort criterion provides a unique sorting order and thus we can
4748edc6e16SJan Kara  * merge inode and vfsmount lists of marks in linear time and find groups
4758edc6e16SJan Kara  * present in both lists.
4768edc6e16SJan Kara  *
4778edc6e16SJan Kara  * A return value of 1 signifies that b has priority over a.
4788edc6e16SJan Kara  * A return value of 0 signifies that the two marks have to be handled together.
4798edc6e16SJan Kara  * A return value of -1 signifies that a has priority over b.
4808edc6e16SJan Kara  */
4818edc6e16SJan Kara int fsnotify_compare_groups(struct fsnotify_group *a, struct fsnotify_group *b)
4828edc6e16SJan Kara {
4838edc6e16SJan Kara 	if (a == b)
4848edc6e16SJan Kara 		return 0;
4858edc6e16SJan Kara 	if (!a)
4868edc6e16SJan Kara 		return 1;
4878edc6e16SJan Kara 	if (!b)
4888edc6e16SJan Kara 		return -1;
4898edc6e16SJan Kara 	if (a->priority < b->priority)
4908edc6e16SJan Kara 		return 1;
4918edc6e16SJan Kara 	if (a->priority > b->priority)
4928edc6e16SJan Kara 		return -1;
4938edc6e16SJan Kara 	if (a < b)
4948edc6e16SJan Kara 		return 1;
4958edc6e16SJan Kara 	return -1;
4968edc6e16SJan Kara }
4978edc6e16SJan Kara 
4989b6e5434SAmir Goldstein static int fsnotify_attach_connector_to_object(fsnotify_connp_t *connp,
499ad69cd99SAmir Goldstein 					       unsigned int obj_type,
50077115225SAmir Goldstein 					       __kernel_fsid_t *fsid)
5019dd813c1SJan Kara {
502b812a9f5SAmir Goldstein 	struct inode *inode = NULL;
5039dd813c1SJan Kara 	struct fsnotify_mark_connector *conn;
5049dd813c1SJan Kara 
505755b5bc6SJan Kara 	conn = kmem_cache_alloc(fsnotify_mark_connector_cachep, GFP_KERNEL);
5069dd813c1SJan Kara 	if (!conn)
5079dd813c1SJan Kara 		return -ENOMEM;
50804662cabSJan Kara 	spin_lock_init(&conn->lock);
5099dd813c1SJan Kara 	INIT_HLIST_HEAD(&conn->list);
510ad69cd99SAmir Goldstein 	conn->type = obj_type;
51136f10f55SAmir Goldstein 	conn->obj = connp;
51277115225SAmir Goldstein 	/* Cache fsid of filesystem containing the object */
513c285a2f0SAmir Goldstein 	if (fsid) {
51477115225SAmir Goldstein 		conn->fsid = *fsid;
515c285a2f0SAmir Goldstein 		conn->flags = FSNOTIFY_CONN_FLAG_HAS_FSID;
516c285a2f0SAmir Goldstein 	} else {
51777115225SAmir Goldstein 		conn->fsid.val[0] = conn->fsid.val[1] = 0;
518c285a2f0SAmir Goldstein 		conn->flags = 0;
519c285a2f0SAmir Goldstein 	}
52009ddbe69SAmir Goldstein 	if (conn->type == FSNOTIFY_OBJ_TYPE_INODE) {
52109ddbe69SAmir Goldstein 		inode = fsnotify_conn_inode(conn);
52211fa333bSAmir Goldstein 		fsnotify_get_inode_ref(inode);
52309ddbe69SAmir Goldstein 	}
524ec44610fSAmir Goldstein 	fsnotify_get_sb_connectors(conn);
52509ddbe69SAmir Goldstein 
5269dd813c1SJan Kara 	/*
52704662cabSJan Kara 	 * cmpxchg() provides the barrier so that readers of *connp can see
52804662cabSJan Kara 	 * only initialized structure
5299dd813c1SJan Kara 	 */
53004662cabSJan Kara 	if (cmpxchg(connp, NULL, conn)) {
53104662cabSJan Kara 		/* Someone else created list structure for us */
53208991e83SJan Kara 		if (inode)
53311fa333bSAmir Goldstein 			fsnotify_put_inode_ref(inode);
5344396a731SAmir Goldstein 		fsnotify_put_sb_connectors(conn);
535755b5bc6SJan Kara 		kmem_cache_free(fsnotify_mark_connector_cachep, conn);
53604662cabSJan Kara 	}
5379dd813c1SJan Kara 
5389dd813c1SJan Kara 	return 0;
5399dd813c1SJan Kara }
5409dd813c1SJan Kara 
5419dd813c1SJan Kara /*
54208991e83SJan Kara  * Get mark connector, make sure it is alive and return with its lock held.
54308991e83SJan Kara  * This is for users that get connector pointer from inode or mount. Users that
54408991e83SJan Kara  * hold reference to a mark on the list may directly lock connector->lock as
54508991e83SJan Kara  * they are sure list cannot go away under them.
54608991e83SJan Kara  */
54708991e83SJan Kara static struct fsnotify_mark_connector *fsnotify_grab_connector(
5489b6e5434SAmir Goldstein 						fsnotify_connp_t *connp)
54908991e83SJan Kara {
55008991e83SJan Kara 	struct fsnotify_mark_connector *conn;
55108991e83SJan Kara 	int idx;
55208991e83SJan Kara 
55308991e83SJan Kara 	idx = srcu_read_lock(&fsnotify_mark_srcu);
55408991e83SJan Kara 	conn = srcu_dereference(*connp, &fsnotify_mark_srcu);
55508991e83SJan Kara 	if (!conn)
55608991e83SJan Kara 		goto out;
55708991e83SJan Kara 	spin_lock(&conn->lock);
558d6f7b98bSAmir Goldstein 	if (conn->type == FSNOTIFY_OBJ_TYPE_DETACHED) {
55908991e83SJan Kara 		spin_unlock(&conn->lock);
56008991e83SJan Kara 		srcu_read_unlock(&fsnotify_mark_srcu, idx);
56108991e83SJan Kara 		return NULL;
56208991e83SJan Kara 	}
56308991e83SJan Kara out:
56408991e83SJan Kara 	srcu_read_unlock(&fsnotify_mark_srcu, idx);
56508991e83SJan Kara 	return conn;
56608991e83SJan Kara }
56708991e83SJan Kara 
56808991e83SJan Kara /*
5699dd813c1SJan Kara  * Add mark into proper place in given list of marks. These marks may be used
5709dd813c1SJan Kara  * for the fsnotify backend to determine which event types should be delivered
5719dd813c1SJan Kara  * to which group and for which inodes. These marks are ordered according to
5729dd813c1SJan Kara  * priority, highest number first, and then by the group's location in memory.
5739dd813c1SJan Kara  */
574755b5bc6SJan Kara static int fsnotify_add_mark_list(struct fsnotify_mark *mark,
575ad69cd99SAmir Goldstein 				  fsnotify_connp_t *connp,
576ad69cd99SAmir Goldstein 				  unsigned int obj_type,
57777115225SAmir Goldstein 				  int allow_dups, __kernel_fsid_t *fsid)
5780809ab69SJan Kara {
5790809ab69SJan Kara 	struct fsnotify_mark *lmark, *last = NULL;
5809dd813c1SJan Kara 	struct fsnotify_mark_connector *conn;
5810809ab69SJan Kara 	int cmp;
582755b5bc6SJan Kara 	int err = 0;
583755b5bc6SJan Kara 
584ad69cd99SAmir Goldstein 	if (WARN_ON(!fsnotify_valid_obj_type(obj_type)))
585755b5bc6SJan Kara 		return -EINVAL;
58677115225SAmir Goldstein 
58777115225SAmir Goldstein 	/* Backend is expected to check for zero fsid (e.g. tmpfs) */
58877115225SAmir Goldstein 	if (fsid && WARN_ON_ONCE(!fsid->val[0] && !fsid->val[1]))
58977115225SAmir Goldstein 		return -ENODEV;
59077115225SAmir Goldstein 
59108991e83SJan Kara restart:
59208991e83SJan Kara 	spin_lock(&mark->lock);
59308991e83SJan Kara 	conn = fsnotify_grab_connector(connp);
59408991e83SJan Kara 	if (!conn) {
59508991e83SJan Kara 		spin_unlock(&mark->lock);
596ad69cd99SAmir Goldstein 		err = fsnotify_attach_connector_to_object(connp, obj_type,
597ad69cd99SAmir Goldstein 							  fsid);
5989dd813c1SJan Kara 		if (err)
5999dd813c1SJan Kara 			return err;
60008991e83SJan Kara 		goto restart;
601c285a2f0SAmir Goldstein 	} else if (fsid && !(conn->flags & FSNOTIFY_CONN_FLAG_HAS_FSID)) {
602c285a2f0SAmir Goldstein 		conn->fsid = *fsid;
603c285a2f0SAmir Goldstein 		/* Pairs with smp_rmb() in fanotify_get_fsid() */
604c285a2f0SAmir Goldstein 		smp_wmb();
605c285a2f0SAmir Goldstein 		conn->flags |= FSNOTIFY_CONN_FLAG_HAS_FSID;
606c285a2f0SAmir Goldstein 	} else if (fsid && (conn->flags & FSNOTIFY_CONN_FLAG_HAS_FSID) &&
60777115225SAmir Goldstein 		   (fsid->val[0] != conn->fsid.val[0] ||
60877115225SAmir Goldstein 		    fsid->val[1] != conn->fsid.val[1])) {
60977115225SAmir Goldstein 		/*
61077115225SAmir Goldstein 		 * Backend is expected to check for non uniform fsid
61177115225SAmir Goldstein 		 * (e.g. btrfs), but maybe we missed something?
61277115225SAmir Goldstein 		 * Only allow setting conn->fsid once to non zero fsid.
61377115225SAmir Goldstein 		 * inotify and non-fid fanotify groups do not set nor test
61477115225SAmir Goldstein 		 * conn->fsid.
61577115225SAmir Goldstein 		 */
61677115225SAmir Goldstein 		pr_warn_ratelimited("%s: fsid mismatch on object of type %u: "
61777115225SAmir Goldstein 				    "%x.%x != %x.%x\n", __func__, conn->type,
61877115225SAmir Goldstein 				    fsid->val[0], fsid->val[1],
61977115225SAmir Goldstein 				    conn->fsid.val[0], conn->fsid.val[1]);
62077115225SAmir Goldstein 		err = -EXDEV;
62177115225SAmir Goldstein 		goto out_err;
6229dd813c1SJan Kara 	}
6230809ab69SJan Kara 
6240809ab69SJan Kara 	/* is mark the first mark? */
6259dd813c1SJan Kara 	if (hlist_empty(&conn->list)) {
6269dd813c1SJan Kara 		hlist_add_head_rcu(&mark->obj_list, &conn->list);
62786ffe245SJan Kara 		goto added;
6280809ab69SJan Kara 	}
6290809ab69SJan Kara 
6300809ab69SJan Kara 	/* should mark be in the middle of the current list? */
6319dd813c1SJan Kara 	hlist_for_each_entry(lmark, &conn->list, obj_list) {
6320809ab69SJan Kara 		last = lmark;
6330809ab69SJan Kara 
6346b3f05d2SJan Kara 		if ((lmark->group == mark->group) &&
6356b3f05d2SJan Kara 		    (lmark->flags & FSNOTIFY_MARK_FLAG_ATTACHED) &&
6366b3f05d2SJan Kara 		    !allow_dups) {
637755b5bc6SJan Kara 			err = -EEXIST;
638755b5bc6SJan Kara 			goto out_err;
639755b5bc6SJan Kara 		}
6400809ab69SJan Kara 
6410809ab69SJan Kara 		cmp = fsnotify_compare_groups(lmark->group, mark->group);
6420809ab69SJan Kara 		if (cmp >= 0) {
6430809ab69SJan Kara 			hlist_add_before_rcu(&mark->obj_list, &lmark->obj_list);
64486ffe245SJan Kara 			goto added;
6450809ab69SJan Kara 		}
6460809ab69SJan Kara 	}
6470809ab69SJan Kara 
6480809ab69SJan Kara 	BUG_ON(last == NULL);
6490809ab69SJan Kara 	/* mark should be the last entry.  last is the current last entry */
6500809ab69SJan Kara 	hlist_add_behind_rcu(&mark->obj_list, &last->obj_list);
65186ffe245SJan Kara added:
65211a6f8e2SJan Kara 	/*
65311a6f8e2SJan Kara 	 * Since connector is attached to object using cmpxchg() we are
65411a6f8e2SJan Kara 	 * guaranteed that connector initialization is fully visible by anyone
65511a6f8e2SJan Kara 	 * seeing mark->connector set.
65611a6f8e2SJan Kara 	 */
657b1da6a51SJan Kara 	WRITE_ONCE(mark->connector, conn);
658755b5bc6SJan Kara out_err:
65904662cabSJan Kara 	spin_unlock(&conn->lock);
660755b5bc6SJan Kara 	spin_unlock(&mark->lock);
661755b5bc6SJan Kara 	return err;
6620809ab69SJan Kara }
6630809ab69SJan Kara 
6648edc6e16SJan Kara /*
6655444e298SEric Paris  * Attach an initialized mark to a given group and fs object.
6665444e298SEric Paris  * These marks may be used for the fsnotify backend to determine which
6675444e298SEric Paris  * event types should be delivered to which group.
6685444e298SEric Paris  */
669b812a9f5SAmir Goldstein int fsnotify_add_mark_locked(struct fsnotify_mark *mark,
670ad69cd99SAmir Goldstein 			     fsnotify_connp_t *connp, unsigned int obj_type,
67177115225SAmir Goldstein 			     int allow_dups, __kernel_fsid_t *fsid)
6725444e298SEric Paris {
6737b129323SJan Kara 	struct fsnotify_group *group = mark->group;
6745444e298SEric Paris 	int ret = 0;
6755444e298SEric Paris 
676d5a335b8SLino Sanfilippo 	BUG_ON(!mutex_is_locked(&group->mark_mutex));
6775444e298SEric Paris 
6785444e298SEric Paris 	/*
6795444e298SEric Paris 	 * LOCKING ORDER!!!!
680986ab098SLino Sanfilippo 	 * group->mark_mutex
681104d06f0SLino Sanfilippo 	 * mark->lock
68204662cabSJan Kara 	 * mark->connector->lock
6835444e298SEric Paris 	 */
684104d06f0SLino Sanfilippo 	spin_lock(&mark->lock);
6854712e722SJan Kara 	mark->flags |= FSNOTIFY_MARK_FLAG_ALIVE | FSNOTIFY_MARK_FLAG_ATTACHED;
686700307a2SEric Paris 
6875444e298SEric Paris 	list_add(&mark->g_list, &group->marks_list);
6886b3f05d2SJan Kara 	fsnotify_get_mark(mark); /* for g_list */
6895444e298SEric Paris 	spin_unlock(&mark->lock);
6905444e298SEric Paris 
691ad69cd99SAmir Goldstein 	ret = fsnotify_add_mark_list(mark, connp, obj_type, allow_dups, fsid);
692755b5bc6SJan Kara 	if (ret)
693755b5bc6SJan Kara 		goto err;
694755b5bc6SJan Kara 
695a242677bSJan Kara 	if (mark->mask)
696a242677bSJan Kara 		fsnotify_recalc_mask(mark->connector);
6975444e298SEric Paris 
6985444e298SEric Paris 	return ret;
6995444e298SEric Paris err:
7009cf90cefSJan Kara 	spin_lock(&mark->lock);
70111375145SJan Kara 	mark->flags &= ~(FSNOTIFY_MARK_FLAG_ALIVE |
70211375145SJan Kara 			 FSNOTIFY_MARK_FLAG_ATTACHED);
7035444e298SEric Paris 	list_del_init(&mark->g_list);
7049cf90cefSJan Kara 	spin_unlock(&mark->lock);
7055444e298SEric Paris 
70611375145SJan Kara 	fsnotify_put_mark(mark);
7075444e298SEric Paris 	return ret;
7085444e298SEric Paris }
7095444e298SEric Paris 
710b812a9f5SAmir Goldstein int fsnotify_add_mark(struct fsnotify_mark *mark, fsnotify_connp_t *connp,
711ad69cd99SAmir Goldstein 		      unsigned int obj_type, int allow_dups,
712ad69cd99SAmir Goldstein 		      __kernel_fsid_t *fsid)
713d5a335b8SLino Sanfilippo {
714d5a335b8SLino Sanfilippo 	int ret;
7157b129323SJan Kara 	struct fsnotify_group *group = mark->group;
7167b129323SJan Kara 
717d5a335b8SLino Sanfilippo 	mutex_lock(&group->mark_mutex);
718ad69cd99SAmir Goldstein 	ret = fsnotify_add_mark_locked(mark, connp, obj_type, allow_dups, fsid);
719d5a335b8SLino Sanfilippo 	mutex_unlock(&group->mark_mutex);
720d5a335b8SLino Sanfilippo 	return ret;
721d5a335b8SLino Sanfilippo }
722b72679eeSTrond Myklebust EXPORT_SYMBOL_GPL(fsnotify_add_mark);
723d5a335b8SLino Sanfilippo 
7245444e298SEric Paris /*
7250809ab69SJan Kara  * Given a list of marks, find the mark associated with given group. If found
7260809ab69SJan Kara  * take a reference to that mark and return it, else return NULL.
7270809ab69SJan Kara  */
7289b6e5434SAmir Goldstein struct fsnotify_mark *fsnotify_find_mark(fsnotify_connp_t *connp,
7290809ab69SJan Kara 					 struct fsnotify_group *group)
7300809ab69SJan Kara {
73108991e83SJan Kara 	struct fsnotify_mark_connector *conn;
7320809ab69SJan Kara 	struct fsnotify_mark *mark;
7330809ab69SJan Kara 
73408991e83SJan Kara 	conn = fsnotify_grab_connector(connp);
7359dd813c1SJan Kara 	if (!conn)
7369dd813c1SJan Kara 		return NULL;
7379dd813c1SJan Kara 
7389dd813c1SJan Kara 	hlist_for_each_entry(mark, &conn->list, obj_list) {
7396b3f05d2SJan Kara 		if (mark->group == group &&
7406b3f05d2SJan Kara 		    (mark->flags & FSNOTIFY_MARK_FLAG_ATTACHED)) {
7410809ab69SJan Kara 			fsnotify_get_mark(mark);
74204662cabSJan Kara 			spin_unlock(&conn->lock);
7430809ab69SJan Kara 			return mark;
7440809ab69SJan Kara 		}
7450809ab69SJan Kara 	}
74604662cabSJan Kara 	spin_unlock(&conn->lock);
7470809ab69SJan Kara 	return NULL;
7480809ab69SJan Kara }
749b72679eeSTrond Myklebust EXPORT_SYMBOL_GPL(fsnotify_find_mark);
7500809ab69SJan Kara 
751d6f7b98bSAmir Goldstein /* Clear any marks in a group with given type mask */
75218f2e0d3SJan Kara void fsnotify_clear_marks_by_group(struct fsnotify_group *group,
753ad69cd99SAmir Goldstein 				   unsigned int obj_type)
7545444e298SEric Paris {
7555444e298SEric Paris 	struct fsnotify_mark *lmark, *mark;
7568f2f3eb5SJan Kara 	LIST_HEAD(to_free);
7572e37c6caSJan Kara 	struct list_head *head = &to_free;
7585444e298SEric Paris 
7592e37c6caSJan Kara 	/* Skip selection step if we want to clear all marks. */
760ad69cd99SAmir Goldstein 	if (obj_type == FSNOTIFY_OBJ_TYPE_ANY) {
7612e37c6caSJan Kara 		head = &group->marks_list;
7622e37c6caSJan Kara 		goto clear;
7632e37c6caSJan Kara 	}
7648f2f3eb5SJan Kara 	/*
7658f2f3eb5SJan Kara 	 * We have to be really careful here. Anytime we drop mark_mutex, e.g.
7668f2f3eb5SJan Kara 	 * fsnotify_clear_marks_by_inode() can come and free marks. Even in our
7678f2f3eb5SJan Kara 	 * to_free list so we have to use mark_mutex even when accessing that
7688f2f3eb5SJan Kara 	 * list. And freeing mark requires us to drop mark_mutex. So we can
7698f2f3eb5SJan Kara 	 * reliably free only the first mark in the list. That's why we first
7708f2f3eb5SJan Kara 	 * move marks to free to to_free list in one go and then free marks in
7718f2f3eb5SJan Kara 	 * to_free list one by one.
7728f2f3eb5SJan Kara 	 */
7736960b0d9SLino Sanfilippo 	mutex_lock_nested(&group->mark_mutex, SINGLE_DEPTH_NESTING);
7745444e298SEric Paris 	list_for_each_entry_safe(mark, lmark, &group->marks_list, g_list) {
775ad69cd99SAmir Goldstein 		if (mark->connector->type == obj_type)
7768f2f3eb5SJan Kara 			list_move(&mark->g_list, &to_free);
7774d92604cSEric Paris 	}
778986ab098SLino Sanfilippo 	mutex_unlock(&group->mark_mutex);
7798f2f3eb5SJan Kara 
7802e37c6caSJan Kara clear:
7818f2f3eb5SJan Kara 	while (1) {
7828f2f3eb5SJan Kara 		mutex_lock_nested(&group->mark_mutex, SINGLE_DEPTH_NESTING);
7832e37c6caSJan Kara 		if (list_empty(head)) {
7848f2f3eb5SJan Kara 			mutex_unlock(&group->mark_mutex);
7858f2f3eb5SJan Kara 			break;
7868f2f3eb5SJan Kara 		}
7872e37c6caSJan Kara 		mark = list_first_entry(head, struct fsnotify_mark, g_list);
7888f2f3eb5SJan Kara 		fsnotify_get_mark(mark);
7894712e722SJan Kara 		fsnotify_detach_mark(mark);
7908f2f3eb5SJan Kara 		mutex_unlock(&group->mark_mutex);
7914712e722SJan Kara 		fsnotify_free_mark(mark);
7928f2f3eb5SJan Kara 		fsnotify_put_mark(mark);
7938f2f3eb5SJan Kara 	}
7945444e298SEric Paris }
7955444e298SEric Paris 
7969b6e5434SAmir Goldstein /* Destroy all marks attached to an object via connector */
7979b6e5434SAmir Goldstein void fsnotify_destroy_marks(fsnotify_connp_t *connp)
7980810b4f9SJan Kara {
79908991e83SJan Kara 	struct fsnotify_mark_connector *conn;
8006b3f05d2SJan Kara 	struct fsnotify_mark *mark, *old_mark = NULL;
801721fb6fbSJan Kara 	void *objp;
802721fb6fbSJan Kara 	unsigned int type;
8030810b4f9SJan Kara 
8046b3f05d2SJan Kara 	conn = fsnotify_grab_connector(connp);
8056b3f05d2SJan Kara 	if (!conn)
8066b3f05d2SJan Kara 		return;
8070810b4f9SJan Kara 	/*
8080810b4f9SJan Kara 	 * We have to be careful since we can race with e.g.
8096b3f05d2SJan Kara 	 * fsnotify_clear_marks_by_group() and once we drop the conn->lock, the
8106b3f05d2SJan Kara 	 * list can get modified. However we are holding mark reference and
8116b3f05d2SJan Kara 	 * thus our mark cannot be removed from obj_list so we can continue
8126b3f05d2SJan Kara 	 * iteration after regaining conn->lock.
8130810b4f9SJan Kara 	 */
8146b3f05d2SJan Kara 	hlist_for_each_entry(mark, &conn->list, obj_list) {
8150810b4f9SJan Kara 		fsnotify_get_mark(mark);
81604662cabSJan Kara 		spin_unlock(&conn->lock);
8176b3f05d2SJan Kara 		if (old_mark)
8186b3f05d2SJan Kara 			fsnotify_put_mark(old_mark);
8196b3f05d2SJan Kara 		old_mark = mark;
8200810b4f9SJan Kara 		fsnotify_destroy_mark(mark, mark->group);
8216b3f05d2SJan Kara 		spin_lock(&conn->lock);
8220810b4f9SJan Kara 	}
8236b3f05d2SJan Kara 	/*
8246b3f05d2SJan Kara 	 * Detach list from object now so that we don't pin inode until all
8256b3f05d2SJan Kara 	 * mark references get dropped. It would lead to strange results such
8266b3f05d2SJan Kara 	 * as delaying inode deletion or blocking unmount.
8276b3f05d2SJan Kara 	 */
828721fb6fbSJan Kara 	objp = fsnotify_detach_connector_from_object(conn, &type);
8296b3f05d2SJan Kara 	spin_unlock(&conn->lock);
8306b3f05d2SJan Kara 	if (old_mark)
8316b3f05d2SJan Kara 		fsnotify_put_mark(old_mark);
832721fb6fbSJan Kara 	fsnotify_drop_object(type, objp);
8330810b4f9SJan Kara }
8340810b4f9SJan Kara 
8355444e298SEric Paris /*
8365444e298SEric Paris  * Nothing fancy, just initialize lists and locks and counters.
8375444e298SEric Paris  */
8385444e298SEric Paris void fsnotify_init_mark(struct fsnotify_mark *mark,
839054c636eSJan Kara 			struct fsnotify_group *group)
8405444e298SEric Paris {
841ba643f04SEric Paris 	memset(mark, 0, sizeof(*mark));
8425444e298SEric Paris 	spin_lock_init(&mark->lock);
843ab97f873SElena Reshetova 	refcount_set(&mark->refcnt, 1);
8447b129323SJan Kara 	fsnotify_get_group(group);
8457b129323SJan Kara 	mark->group = group;
846b1da6a51SJan Kara 	WRITE_ONCE(mark->connector, NULL);
8475444e298SEric Paris }
848b72679eeSTrond Myklebust EXPORT_SYMBOL_GPL(fsnotify_init_mark);
84913d34ac6SJeff Layton 
85035e48176SJan Kara /*
85135e48176SJan Kara  * Destroy all marks in destroy_list, waits for SRCU period to finish before
85235e48176SJan Kara  * actually freeing marks.
85335e48176SJan Kara  */
854f09b04a0SJan Kara static void fsnotify_mark_destroy_workfn(struct work_struct *work)
85513d34ac6SJeff Layton {
85613d34ac6SJeff Layton 	struct fsnotify_mark *mark, *next;
85713d34ac6SJeff Layton 	struct list_head private_destroy_list;
85813d34ac6SJeff Layton 
85913d34ac6SJeff Layton 	spin_lock(&destroy_lock);
86013d34ac6SJeff Layton 	/* exchange the list head */
86113d34ac6SJeff Layton 	list_replace_init(&destroy_list, &private_destroy_list);
86213d34ac6SJeff Layton 	spin_unlock(&destroy_lock);
86313d34ac6SJeff Layton 
86413d34ac6SJeff Layton 	synchronize_srcu(&fsnotify_mark_srcu);
86513d34ac6SJeff Layton 
86613d34ac6SJeff Layton 	list_for_each_entry_safe(mark, next, &private_destroy_list, g_list) {
86713d34ac6SJeff Layton 		list_del_init(&mark->g_list);
8686b3f05d2SJan Kara 		fsnotify_final_mark_destroy(mark);
86913d34ac6SJeff Layton 	}
87013d34ac6SJeff Layton }
87135e48176SJan Kara 
872f09b04a0SJan Kara /* Wait for all marks queued for destruction to be actually destroyed */
873f09b04a0SJan Kara void fsnotify_wait_marks_destroyed(void)
87435e48176SJan Kara {
875f09b04a0SJan Kara 	flush_delayed_work(&reaper_work);
87635e48176SJan Kara }
877b72679eeSTrond Myklebust EXPORT_SYMBOL_GPL(fsnotify_wait_marks_destroyed);
878