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 19struct btrfs_path; 20 21void btrfs_tree_lock(struct extent_buffer *eb); 22void btrfs_tree_unlock(struct extent_buffer *eb); 23 24void btrfs_tree_read_lock(struct extent_buffer *eb); 25void btrfs_tree_read_unlock(struct extent_buffer *eb); 26void btrfs_tree_read_unlock_blocking(struct extent_buffer *eb); 27void btrfs_set_lock_blocking_read(struct extent_buffer *eb); 28void btrfs_set_lock_blocking_write(struct extent_buffer *eb); 29int btrfs_try_tree_read_lock(struct extent_buffer *eb); 30int btrfs_try_tree_write_lock(struct extent_buffer *eb); 31int btrfs_tree_read_lock_atomic(struct extent_buffer *eb); 32 33#ifdef CONFIG_BTRFS_DEBUG 34static inline void btrfs_assert_tree_locked(struct extent_buffer *eb) { 35 BUG_ON(!eb->write_locks); 36} 37#else 38static inline void btrfs_assert_tree_locked(struct extent_buffer *eb) { } 39#endif 40 41void btrfs_set_path_blocking(struct btrfs_path *p); 42void btrfs_unlock_up_safe(struct btrfs_path *path, int level); 43 44static 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 56struct 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 63int btrfs_drew_lock_init(struct btrfs_drew_lock *lock); 64void btrfs_drew_lock_destroy(struct btrfs_drew_lock *lock); 65void btrfs_drew_write_lock(struct btrfs_drew_lock *lock); 66bool btrfs_drew_try_write_lock(struct btrfs_drew_lock *lock); 67void btrfs_drew_write_unlock(struct btrfs_drew_lock *lock); 68void btrfs_drew_read_lock(struct btrfs_drew_lock *lock); 69void btrfs_drew_read_unlock(struct btrfs_drew_lock *lock); 70 71#endif 72