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