162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Copyright (C) 2008 Oracle.  All rights reserved.
462306a36Sopenharmony_ci */
562306a36Sopenharmony_ci
662306a36Sopenharmony_ci#ifndef BTRFS_LOCKING_H
762306a36Sopenharmony_ci#define BTRFS_LOCKING_H
862306a36Sopenharmony_ci
962306a36Sopenharmony_ci#include <linux/atomic.h>
1062306a36Sopenharmony_ci#include <linux/wait.h>
1162306a36Sopenharmony_ci#include <linux/percpu_counter.h>
1262306a36Sopenharmony_ci#include "extent_io.h"
1362306a36Sopenharmony_ci
1462306a36Sopenharmony_ci#define BTRFS_WRITE_LOCK 1
1562306a36Sopenharmony_ci#define BTRFS_READ_LOCK 2
1662306a36Sopenharmony_ci
1762306a36Sopenharmony_ci/*
1862306a36Sopenharmony_ci * We are limited in number of subclasses by MAX_LOCKDEP_SUBCLASSES, which at
1962306a36Sopenharmony_ci * the time of this patch is 8, which is how many we use.  Keep this in mind if
2062306a36Sopenharmony_ci * you decide you want to add another subclass.
2162306a36Sopenharmony_ci */
2262306a36Sopenharmony_cienum btrfs_lock_nesting {
2362306a36Sopenharmony_ci	BTRFS_NESTING_NORMAL,
2462306a36Sopenharmony_ci
2562306a36Sopenharmony_ci	/*
2662306a36Sopenharmony_ci	 * When we COW a block we are holding the lock on the original block,
2762306a36Sopenharmony_ci	 * and since our lockdep maps are rootid+level, this confuses lockdep
2862306a36Sopenharmony_ci	 * when we lock the newly allocated COW'd block.  Handle this by having
2962306a36Sopenharmony_ci	 * a subclass for COW'ed blocks so that lockdep doesn't complain.
3062306a36Sopenharmony_ci	 */
3162306a36Sopenharmony_ci	BTRFS_NESTING_COW,
3262306a36Sopenharmony_ci
3362306a36Sopenharmony_ci	/*
3462306a36Sopenharmony_ci	 * Oftentimes we need to lock adjacent nodes on the same level while
3562306a36Sopenharmony_ci	 * still holding the lock on the original node we searched to, such as
3662306a36Sopenharmony_ci	 * for searching forward or for split/balance.
3762306a36Sopenharmony_ci	 *
3862306a36Sopenharmony_ci	 * Because of this we need to indicate to lockdep that this is
3962306a36Sopenharmony_ci	 * acceptable by having a different subclass for each of these
4062306a36Sopenharmony_ci	 * operations.
4162306a36Sopenharmony_ci	 */
4262306a36Sopenharmony_ci	BTRFS_NESTING_LEFT,
4362306a36Sopenharmony_ci	BTRFS_NESTING_RIGHT,
4462306a36Sopenharmony_ci
4562306a36Sopenharmony_ci	/*
4662306a36Sopenharmony_ci	 * When splitting we will be holding a lock on the left/right node when
4762306a36Sopenharmony_ci	 * we need to cow that node, thus we need a new set of subclasses for
4862306a36Sopenharmony_ci	 * these two operations.
4962306a36Sopenharmony_ci	 */
5062306a36Sopenharmony_ci	BTRFS_NESTING_LEFT_COW,
5162306a36Sopenharmony_ci	BTRFS_NESTING_RIGHT_COW,
5262306a36Sopenharmony_ci
5362306a36Sopenharmony_ci	/*
5462306a36Sopenharmony_ci	 * When splitting we may push nodes to the left or right, but still use
5562306a36Sopenharmony_ci	 * the subsequent nodes in our path, keeping our locks on those adjacent
5662306a36Sopenharmony_ci	 * blocks.  Thus when we go to allocate a new split block we've already
5762306a36Sopenharmony_ci	 * used up all of our available subclasses, so this subclass exists to
5862306a36Sopenharmony_ci	 * handle this case where we need to allocate a new split block.
5962306a36Sopenharmony_ci	 */
6062306a36Sopenharmony_ci	BTRFS_NESTING_SPLIT,
6162306a36Sopenharmony_ci
6262306a36Sopenharmony_ci	/*
6362306a36Sopenharmony_ci	 * When promoting a new block to a root we need to have a special
6462306a36Sopenharmony_ci	 * subclass so we don't confuse lockdep, as it will appear that we are
6562306a36Sopenharmony_ci	 * locking a higher level node before a lower level one.  Copying also
6662306a36Sopenharmony_ci	 * has this problem as it appears we're locking the same block again
6762306a36Sopenharmony_ci	 * when we make a snapshot of an existing root.
6862306a36Sopenharmony_ci	 */
6962306a36Sopenharmony_ci	BTRFS_NESTING_NEW_ROOT,
7062306a36Sopenharmony_ci
7162306a36Sopenharmony_ci	/*
7262306a36Sopenharmony_ci	 * We are limited to MAX_LOCKDEP_SUBLCLASSES number of subclasses, so
7362306a36Sopenharmony_ci	 * add this in here and add a static_assert to keep us from going over
7462306a36Sopenharmony_ci	 * the limit.  As of this writing we're limited to 8, and we're
7562306a36Sopenharmony_ci	 * definitely using 8, hence this check to keep us from messing up in
7662306a36Sopenharmony_ci	 * the future.
7762306a36Sopenharmony_ci	 */
7862306a36Sopenharmony_ci	BTRFS_NESTING_MAX,
7962306a36Sopenharmony_ci};
8062306a36Sopenharmony_ci
8162306a36Sopenharmony_cienum btrfs_lockdep_trans_states {
8262306a36Sopenharmony_ci	BTRFS_LOCKDEP_TRANS_COMMIT_PREP,
8362306a36Sopenharmony_ci	BTRFS_LOCKDEP_TRANS_UNBLOCKED,
8462306a36Sopenharmony_ci	BTRFS_LOCKDEP_TRANS_SUPER_COMMITTED,
8562306a36Sopenharmony_ci	BTRFS_LOCKDEP_TRANS_COMPLETED,
8662306a36Sopenharmony_ci};
8762306a36Sopenharmony_ci
8862306a36Sopenharmony_ci/*
8962306a36Sopenharmony_ci * Lockdep annotation for wait events.
9062306a36Sopenharmony_ci *
9162306a36Sopenharmony_ci * @owner:  The struct where the lockdep map is defined
9262306a36Sopenharmony_ci * @lock:   The lockdep map corresponding to a wait event
9362306a36Sopenharmony_ci *
9462306a36Sopenharmony_ci * This macro is used to annotate a wait event. In this case a thread acquires
9562306a36Sopenharmony_ci * the lockdep map as writer (exclusive lock) because it has to block until all
9662306a36Sopenharmony_ci * the threads that hold the lock as readers signal the condition for the wait
9762306a36Sopenharmony_ci * event and release their locks.
9862306a36Sopenharmony_ci */
9962306a36Sopenharmony_ci#define btrfs_might_wait_for_event(owner, lock)					\
10062306a36Sopenharmony_ci	do {									\
10162306a36Sopenharmony_ci		rwsem_acquire(&owner->lock##_map, 0, 0, _THIS_IP_);		\
10262306a36Sopenharmony_ci		rwsem_release(&owner->lock##_map, _THIS_IP_);			\
10362306a36Sopenharmony_ci	} while (0)
10462306a36Sopenharmony_ci
10562306a36Sopenharmony_ci/*
10662306a36Sopenharmony_ci * Protection for the resource/condition of a wait event.
10762306a36Sopenharmony_ci *
10862306a36Sopenharmony_ci * @owner:  The struct where the lockdep map is defined
10962306a36Sopenharmony_ci * @lock:   The lockdep map corresponding to a wait event
11062306a36Sopenharmony_ci *
11162306a36Sopenharmony_ci * Many threads can modify the condition for the wait event at the same time
11262306a36Sopenharmony_ci * and signal the threads that block on the wait event. The threads that modify
11362306a36Sopenharmony_ci * the condition and do the signaling acquire the lock as readers (shared
11462306a36Sopenharmony_ci * lock).
11562306a36Sopenharmony_ci */
11662306a36Sopenharmony_ci#define btrfs_lockdep_acquire(owner, lock)					\
11762306a36Sopenharmony_ci	rwsem_acquire_read(&owner->lock##_map, 0, 0, _THIS_IP_)
11862306a36Sopenharmony_ci
11962306a36Sopenharmony_ci/*
12062306a36Sopenharmony_ci * Used after signaling the condition for a wait event to release the lockdep
12162306a36Sopenharmony_ci * map held by a reader thread.
12262306a36Sopenharmony_ci */
12362306a36Sopenharmony_ci#define btrfs_lockdep_release(owner, lock)					\
12462306a36Sopenharmony_ci	rwsem_release(&owner->lock##_map, _THIS_IP_)
12562306a36Sopenharmony_ci
12662306a36Sopenharmony_ci/*
12762306a36Sopenharmony_ci * Macros for the transaction states wait events, similar to the generic wait
12862306a36Sopenharmony_ci * event macros.
12962306a36Sopenharmony_ci */
13062306a36Sopenharmony_ci#define btrfs_might_wait_for_state(owner, i)					\
13162306a36Sopenharmony_ci	do {									\
13262306a36Sopenharmony_ci		rwsem_acquire(&owner->btrfs_state_change_map[i], 0, 0, _THIS_IP_); \
13362306a36Sopenharmony_ci		rwsem_release(&owner->btrfs_state_change_map[i], _THIS_IP_);	\
13462306a36Sopenharmony_ci	} while (0)
13562306a36Sopenharmony_ci
13662306a36Sopenharmony_ci#define btrfs_trans_state_lockdep_acquire(owner, i)				\
13762306a36Sopenharmony_ci	rwsem_acquire_read(&owner->btrfs_state_change_map[i], 0, 0, _THIS_IP_)
13862306a36Sopenharmony_ci
13962306a36Sopenharmony_ci#define btrfs_trans_state_lockdep_release(owner, i)				\
14062306a36Sopenharmony_ci	rwsem_release(&owner->btrfs_state_change_map[i], _THIS_IP_)
14162306a36Sopenharmony_ci
14262306a36Sopenharmony_ci/* Initialization of the lockdep map */
14362306a36Sopenharmony_ci#define btrfs_lockdep_init_map(owner, lock)					\
14462306a36Sopenharmony_ci	do {									\
14562306a36Sopenharmony_ci		static struct lock_class_key lock##_key;			\
14662306a36Sopenharmony_ci		lockdep_init_map(&owner->lock##_map, #lock, &lock##_key, 0);	\
14762306a36Sopenharmony_ci	} while (0)
14862306a36Sopenharmony_ci
14962306a36Sopenharmony_ci/* Initialization of the transaction states lockdep maps. */
15062306a36Sopenharmony_ci#define btrfs_state_lockdep_init_map(owner, lock, state)			\
15162306a36Sopenharmony_ci	do {									\
15262306a36Sopenharmony_ci		static struct lock_class_key lock##_key;			\
15362306a36Sopenharmony_ci		lockdep_init_map(&owner->btrfs_state_change_map[state], #lock,	\
15462306a36Sopenharmony_ci				 &lock##_key, 0);				\
15562306a36Sopenharmony_ci	} while (0)
15662306a36Sopenharmony_ci
15762306a36Sopenharmony_cistatic_assert(BTRFS_NESTING_MAX <= MAX_LOCKDEP_SUBCLASSES,
15862306a36Sopenharmony_ci	      "too many lock subclasses defined");
15962306a36Sopenharmony_ci
16062306a36Sopenharmony_cistruct btrfs_path;
16162306a36Sopenharmony_ci
16262306a36Sopenharmony_civoid __btrfs_tree_lock(struct extent_buffer *eb, enum btrfs_lock_nesting nest);
16362306a36Sopenharmony_civoid btrfs_tree_lock(struct extent_buffer *eb);
16462306a36Sopenharmony_civoid btrfs_tree_unlock(struct extent_buffer *eb);
16562306a36Sopenharmony_ci
16662306a36Sopenharmony_civoid __btrfs_tree_read_lock(struct extent_buffer *eb, enum btrfs_lock_nesting nest);
16762306a36Sopenharmony_civoid btrfs_tree_read_lock(struct extent_buffer *eb);
16862306a36Sopenharmony_civoid btrfs_tree_read_unlock(struct extent_buffer *eb);
16962306a36Sopenharmony_ciint btrfs_try_tree_read_lock(struct extent_buffer *eb);
17062306a36Sopenharmony_ciint btrfs_try_tree_write_lock(struct extent_buffer *eb);
17162306a36Sopenharmony_cistruct extent_buffer *btrfs_lock_root_node(struct btrfs_root *root);
17262306a36Sopenharmony_cistruct extent_buffer *btrfs_read_lock_root_node(struct btrfs_root *root);
17362306a36Sopenharmony_cistruct extent_buffer *btrfs_try_read_lock_root_node(struct btrfs_root *root);
17462306a36Sopenharmony_ci
17562306a36Sopenharmony_ci#ifdef CONFIG_BTRFS_DEBUG
17662306a36Sopenharmony_cistatic inline void btrfs_assert_tree_write_locked(struct extent_buffer *eb)
17762306a36Sopenharmony_ci{
17862306a36Sopenharmony_ci	lockdep_assert_held_write(&eb->lock);
17962306a36Sopenharmony_ci}
18062306a36Sopenharmony_ci#else
18162306a36Sopenharmony_cistatic inline void btrfs_assert_tree_write_locked(struct extent_buffer *eb) { }
18262306a36Sopenharmony_ci#endif
18362306a36Sopenharmony_ci
18462306a36Sopenharmony_civoid btrfs_unlock_up_safe(struct btrfs_path *path, int level);
18562306a36Sopenharmony_ci
18662306a36Sopenharmony_cistatic inline void btrfs_tree_unlock_rw(struct extent_buffer *eb, int rw)
18762306a36Sopenharmony_ci{
18862306a36Sopenharmony_ci	if (rw == BTRFS_WRITE_LOCK)
18962306a36Sopenharmony_ci		btrfs_tree_unlock(eb);
19062306a36Sopenharmony_ci	else if (rw == BTRFS_READ_LOCK)
19162306a36Sopenharmony_ci		btrfs_tree_read_unlock(eb);
19262306a36Sopenharmony_ci	else
19362306a36Sopenharmony_ci		BUG();
19462306a36Sopenharmony_ci}
19562306a36Sopenharmony_ci
19662306a36Sopenharmony_cistruct btrfs_drew_lock {
19762306a36Sopenharmony_ci	atomic_t readers;
19862306a36Sopenharmony_ci	atomic_t writers;
19962306a36Sopenharmony_ci	wait_queue_head_t pending_writers;
20062306a36Sopenharmony_ci	wait_queue_head_t pending_readers;
20162306a36Sopenharmony_ci};
20262306a36Sopenharmony_ci
20362306a36Sopenharmony_civoid btrfs_drew_lock_init(struct btrfs_drew_lock *lock);
20462306a36Sopenharmony_civoid btrfs_drew_write_lock(struct btrfs_drew_lock *lock);
20562306a36Sopenharmony_cibool btrfs_drew_try_write_lock(struct btrfs_drew_lock *lock);
20662306a36Sopenharmony_civoid btrfs_drew_write_unlock(struct btrfs_drew_lock *lock);
20762306a36Sopenharmony_civoid btrfs_drew_read_lock(struct btrfs_drew_lock *lock);
20862306a36Sopenharmony_civoid btrfs_drew_read_unlock(struct btrfs_drew_lock *lock);
20962306a36Sopenharmony_ci
21062306a36Sopenharmony_ci#ifdef CONFIG_DEBUG_LOCK_ALLOC
21162306a36Sopenharmony_civoid btrfs_set_buffer_lockdep_class(u64 objectid, struct extent_buffer *eb, int level);
21262306a36Sopenharmony_civoid btrfs_maybe_reset_lockdep_class(struct btrfs_root *root, struct extent_buffer *eb);
21362306a36Sopenharmony_ci#else
21462306a36Sopenharmony_cistatic inline void btrfs_set_buffer_lockdep_class(u64 objectid,
21562306a36Sopenharmony_ci					struct extent_buffer *eb, int level)
21662306a36Sopenharmony_ci{
21762306a36Sopenharmony_ci}
21862306a36Sopenharmony_cistatic inline void btrfs_maybe_reset_lockdep_class(struct btrfs_root *root,
21962306a36Sopenharmony_ci						   struct extent_buffer *eb)
22062306a36Sopenharmony_ci{
22162306a36Sopenharmony_ci}
22262306a36Sopenharmony_ci#endif
22362306a36Sopenharmony_ci
22462306a36Sopenharmony_ci#endif
225