1 /* SPDX-License-Identifier: GPL-2.0 */ 2 /* 3 * Copyright (C) 2008 Oracle. All rights reserved. 4 */ 5 6 #ifndef BTRFS_LOCKING_H 7 #define BTRFS_LOCKING_H 8 9 #include <linux/atomic.h> 10 #include <linux/wait.h> 11 #include <linux/percpu_counter.h> 12 #include "extent_io.h" 13 14 #define BTRFS_WRITE_LOCK 1 15 #define BTRFS_READ_LOCK 2 16 #define BTRFS_WRITE_LOCK_BLOCKING 3 17 #define BTRFS_READ_LOCK_BLOCKING 4 18 19 struct btrfs_path; 20 21 void btrfs_tree_lock(struct extent_buffer *eb); 22 void btrfs_tree_unlock(struct extent_buffer *eb); 23 24 void btrfs_tree_read_lock(struct extent_buffer *eb); 25 void btrfs_tree_read_unlock(struct extent_buffer *eb); 26 void btrfs_tree_read_unlock_blocking(struct extent_buffer *eb); 27 void btrfs_set_lock_blocking_read(struct extent_buffer *eb); 28 void btrfs_set_lock_blocking_write(struct extent_buffer *eb); 29 int btrfs_try_tree_read_lock(struct extent_buffer *eb); 30 int btrfs_try_tree_write_lock(struct extent_buffer *eb); 31 int btrfs_tree_read_lock_atomic(struct extent_buffer *eb); 32 33 #ifdef CONFIG_BTRFS_DEBUG 34 static inline void btrfs_assert_tree_locked(struct extent_buffer *eb) { 35 BUG_ON(!eb->write_locks); 36 } 37 #else 38 static inline void btrfs_assert_tree_locked(struct extent_buffer *eb) { } 39 #endif 40 41 void btrfs_set_path_blocking(struct btrfs_path *p); 42 void btrfs_unlock_up_safe(struct btrfs_path *path, int level); 43 44 static inline void btrfs_tree_unlock_rw(struct extent_buffer *eb, int rw) 45 { 46 if (rw == BTRFS_WRITE_LOCK || rw == BTRFS_WRITE_LOCK_BLOCKING) 47 btrfs_tree_unlock(eb); 48 else if (rw == BTRFS_READ_LOCK_BLOCKING) 49 btrfs_tree_read_unlock_blocking(eb); 50 else if (rw == BTRFS_READ_LOCK) 51 btrfs_tree_read_unlock(eb); 52 else 53 BUG(); 54 } 55 56 struct btrfs_drew_lock { 57 atomic_t readers; 58 struct percpu_counter writers; 59 wait_queue_head_t pending_writers; 60 wait_queue_head_t pending_readers; 61 }; 62 63 int btrfs_drew_lock_init(struct btrfs_drew_lock *lock); 64 void btrfs_drew_lock_destroy(struct btrfs_drew_lock *lock); 65 void btrfs_drew_write_lock(struct btrfs_drew_lock *lock); 66 bool btrfs_drew_try_write_lock(struct btrfs_drew_lock *lock); 67 void btrfs_drew_write_unlock(struct btrfs_drew_lock *lock); 68 void btrfs_drew_read_lock(struct btrfs_drew_lock *lock); 69 void btrfs_drew_read_unlock(struct btrfs_drew_lock *lock); 70 71 #endif 72