mirror of
https://gitee.com/bianbu-linux/linux-6.6
synced 2025-04-24 14:07:52 -04:00
btrfs: assert that extent buffers are write locked instead of only locked
We currently use lockdep_assert_held() at btrfs_assert_tree_locked(), and that checks that we hold a lock either in read mode or write mode. However in all contexts we use btrfs_assert_tree_locked(), we actually want to check if we are holding a write lock on the extent buffer's rw semaphore - it would be a bug if in any of those contexts we were holding a read lock instead. So change btrfs_assert_tree_locked() to use lockdep_assert_held_write() instead and, to make it more explicit, rename btrfs_assert_tree_locked() to btrfs_assert_tree_write_locked(), so that it's clear we want to check we are holding a write lock. For now there are no contexts where we want to assert that we must have a read lock, but in case that is needed in the future, we can add a new helper function that just calls out lockdep_assert_held_read(). Signed-off-by: Filipe Manana <fdmanana@suse.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
8ef9dc0f14
commit
49d0c6424c
5 changed files with 15 additions and 14 deletions
|
@ -395,7 +395,7 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans,
|
||||||
if (*cow_ret == buf)
|
if (*cow_ret == buf)
|
||||||
unlock_orig = 1;
|
unlock_orig = 1;
|
||||||
|
|
||||||
btrfs_assert_tree_locked(buf);
|
btrfs_assert_tree_write_locked(buf);
|
||||||
|
|
||||||
WARN_ON(test_bit(BTRFS_ROOT_SHAREABLE, &root->state) &&
|
WARN_ON(test_bit(BTRFS_ROOT_SHAREABLE, &root->state) &&
|
||||||
trans->transid != fs_info->running_transaction->transid);
|
trans->transid != fs_info->running_transaction->transid);
|
||||||
|
@ -2487,7 +2487,7 @@ static void insert_ptr(struct btrfs_trans_handle *trans,
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
BUG_ON(!path->nodes[level]);
|
BUG_ON(!path->nodes[level]);
|
||||||
btrfs_assert_tree_locked(path->nodes[level]);
|
btrfs_assert_tree_write_locked(path->nodes[level]);
|
||||||
lower = path->nodes[level];
|
lower = path->nodes[level];
|
||||||
nritems = btrfs_header_nritems(lower);
|
nritems = btrfs_header_nritems(lower);
|
||||||
BUG_ON(slot > nritems);
|
BUG_ON(slot > nritems);
|
||||||
|
@ -2827,7 +2827,7 @@ static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root
|
||||||
if (slot >= btrfs_header_nritems(upper) - 1)
|
if (slot >= btrfs_header_nritems(upper) - 1)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
btrfs_assert_tree_locked(path->nodes[1]);
|
btrfs_assert_tree_write_locked(path->nodes[1]);
|
||||||
|
|
||||||
right = btrfs_read_node_slot(upper, slot + 1);
|
right = btrfs_read_node_slot(upper, slot + 1);
|
||||||
/*
|
/*
|
||||||
|
@ -3065,7 +3065,7 @@ static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root
|
||||||
if (right_nritems == 0)
|
if (right_nritems == 0)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
btrfs_assert_tree_locked(path->nodes[1]);
|
btrfs_assert_tree_write_locked(path->nodes[1]);
|
||||||
|
|
||||||
left = btrfs_read_node_slot(path->nodes[1], slot - 1);
|
left = btrfs_read_node_slot(path->nodes[1], slot - 1);
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -1036,7 +1036,7 @@ static int btree_set_page_dirty(struct page *page)
|
||||||
BUG_ON(!eb);
|
BUG_ON(!eb);
|
||||||
BUG_ON(!test_bit(EXTENT_BUFFER_DIRTY, &eb->bflags));
|
BUG_ON(!test_bit(EXTENT_BUFFER_DIRTY, &eb->bflags));
|
||||||
BUG_ON(!atomic_read(&eb->refs));
|
BUG_ON(!atomic_read(&eb->refs));
|
||||||
btrfs_assert_tree_locked(eb);
|
btrfs_assert_tree_write_locked(eb);
|
||||||
return __set_page_dirty_nobuffers(page);
|
return __set_page_dirty_nobuffers(page);
|
||||||
}
|
}
|
||||||
ASSERT(PagePrivate(page) && page->private);
|
ASSERT(PagePrivate(page) && page->private);
|
||||||
|
@ -1061,7 +1061,7 @@ static int btree_set_page_dirty(struct page *page)
|
||||||
ASSERT(eb);
|
ASSERT(eb);
|
||||||
ASSERT(test_bit(EXTENT_BUFFER_DIRTY, &eb->bflags));
|
ASSERT(test_bit(EXTENT_BUFFER_DIRTY, &eb->bflags));
|
||||||
ASSERT(atomic_read(&eb->refs));
|
ASSERT(atomic_read(&eb->refs));
|
||||||
btrfs_assert_tree_locked(eb);
|
btrfs_assert_tree_write_locked(eb);
|
||||||
free_extent_buffer(eb);
|
free_extent_buffer(eb);
|
||||||
|
|
||||||
cur_bit += (fs_info->nodesize >> fs_info->sectorsize_bits);
|
cur_bit += (fs_info->nodesize >> fs_info->sectorsize_bits);
|
||||||
|
@ -1125,7 +1125,7 @@ void btrfs_clean_tree_block(struct extent_buffer *buf)
|
||||||
struct btrfs_fs_info *fs_info = buf->fs_info;
|
struct btrfs_fs_info *fs_info = buf->fs_info;
|
||||||
if (btrfs_header_generation(buf) ==
|
if (btrfs_header_generation(buf) ==
|
||||||
fs_info->running_transaction->transid) {
|
fs_info->running_transaction->transid) {
|
||||||
btrfs_assert_tree_locked(buf);
|
btrfs_assert_tree_write_locked(buf);
|
||||||
|
|
||||||
if (test_and_clear_bit(EXTENT_BUFFER_DIRTY, &buf->bflags)) {
|
if (test_and_clear_bit(EXTENT_BUFFER_DIRTY, &buf->bflags)) {
|
||||||
percpu_counter_add_batch(&fs_info->dirty_metadata_bytes,
|
percpu_counter_add_batch(&fs_info->dirty_metadata_bytes,
|
||||||
|
@ -4481,7 +4481,7 @@ void btrfs_mark_buffer_dirty(struct extent_buffer *buf)
|
||||||
if (unlikely(test_bit(EXTENT_BUFFER_UNMAPPED, &buf->bflags)))
|
if (unlikely(test_bit(EXTENT_BUFFER_UNMAPPED, &buf->bflags)))
|
||||||
return;
|
return;
|
||||||
#endif
|
#endif
|
||||||
btrfs_assert_tree_locked(buf);
|
btrfs_assert_tree_write_locked(buf);
|
||||||
if (transid != fs_info->generation)
|
if (transid != fs_info->generation)
|
||||||
WARN(1, KERN_CRIT "btrfs transid mismatch buffer %llu, found %llu running %llu\n",
|
WARN(1, KERN_CRIT "btrfs transid mismatch buffer %llu, found %llu running %llu\n",
|
||||||
buf->start, transid, fs_info->generation);
|
buf->start, transid, fs_info->generation);
|
||||||
|
|
|
@ -5836,13 +5836,13 @@ int btrfs_drop_subtree(struct btrfs_trans_handle *trans,
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
btrfs_assert_tree_locked(parent);
|
btrfs_assert_tree_write_locked(parent);
|
||||||
parent_level = btrfs_header_level(parent);
|
parent_level = btrfs_header_level(parent);
|
||||||
atomic_inc(&parent->refs);
|
atomic_inc(&parent->refs);
|
||||||
path->nodes[parent_level] = parent;
|
path->nodes[parent_level] = parent;
|
||||||
path->slots[parent_level] = btrfs_header_nritems(parent);
|
path->slots[parent_level] = btrfs_header_nritems(parent);
|
||||||
|
|
||||||
btrfs_assert_tree_locked(node);
|
btrfs_assert_tree_write_locked(node);
|
||||||
level = btrfs_header_level(node);
|
level = btrfs_header_level(node);
|
||||||
path->nodes[level] = node;
|
path->nodes[level] = node;
|
||||||
path->slots[level] = 0;
|
path->slots[level] = 0;
|
||||||
|
|
|
@ -96,11 +96,12 @@ struct extent_buffer *btrfs_lock_root_node(struct btrfs_root *root);
|
||||||
struct extent_buffer *btrfs_read_lock_root_node(struct btrfs_root *root);
|
struct extent_buffer *btrfs_read_lock_root_node(struct btrfs_root *root);
|
||||||
|
|
||||||
#ifdef CONFIG_BTRFS_DEBUG
|
#ifdef CONFIG_BTRFS_DEBUG
|
||||||
static inline void btrfs_assert_tree_locked(struct extent_buffer *eb) {
|
static inline void btrfs_assert_tree_write_locked(struct extent_buffer *eb)
|
||||||
lockdep_assert_held(&eb->lock);
|
{
|
||||||
|
lockdep_assert_held_write(&eb->lock);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
static inline void btrfs_assert_tree_locked(struct extent_buffer *eb) { }
|
static inline void btrfs_assert_tree_write_locked(struct extent_buffer *eb) { }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void btrfs_unlock_up_safe(struct btrfs_path *path, int level);
|
void btrfs_unlock_up_safe(struct btrfs_path *path, int level);
|
||||||
|
|
|
@ -138,7 +138,7 @@ int btrfs_setxattr(struct btrfs_trans_handle *trans, struct inode *inode,
|
||||||
* matches our target xattr, so lets check.
|
* matches our target xattr, so lets check.
|
||||||
*/
|
*/
|
||||||
ret = 0;
|
ret = 0;
|
||||||
btrfs_assert_tree_locked(path->nodes[0]);
|
btrfs_assert_tree_write_locked(path->nodes[0]);
|
||||||
di = btrfs_match_dir_item_name(fs_info, path, name, name_len);
|
di = btrfs_match_dir_item_name(fs_info, path, name, name_len);
|
||||||
if (!di && !(flags & XATTR_REPLACE)) {
|
if (!di && !(flags & XATTR_REPLACE)) {
|
||||||
ret = -ENOSPC;
|
ret = -ENOSPC;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue