mirror of
https://gitee.com/bianbu-linux/linux-6.6
synced 2025-04-24 14:07:52 -04:00
btrfs: move lockdep class helpers to locking.c
These definitions exist in disk-io.c, which is not related to the locking. Move this over to locking.h/c where it makes more sense. Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com> Signed-off-by: Josef Bacik <josef@toxicpanda.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
85f02d6c85
commit
0a27a0474d
4 changed files with 89 additions and 92 deletions
|
@ -86,88 +86,6 @@ struct async_submit_bio {
|
||||||
blk_status_t status;
|
blk_status_t status;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
|
||||||
* Lockdep class keys for extent_buffer->lock's in this root. For a given
|
|
||||||
* eb, the lockdep key is determined by the btrfs_root it belongs to and
|
|
||||||
* the level the eb occupies in the tree.
|
|
||||||
*
|
|
||||||
* Different roots are used for different purposes and may nest inside each
|
|
||||||
* other and they require separate keysets. As lockdep keys should be
|
|
||||||
* static, assign keysets according to the purpose of the root as indicated
|
|
||||||
* by btrfs_root->root_key.objectid. This ensures that all special purpose
|
|
||||||
* roots have separate keysets.
|
|
||||||
*
|
|
||||||
* Lock-nesting across peer nodes is always done with the immediate parent
|
|
||||||
* node locked thus preventing deadlock. As lockdep doesn't know this, use
|
|
||||||
* subclass to avoid triggering lockdep warning in such cases.
|
|
||||||
*
|
|
||||||
* The key is set by the readpage_end_io_hook after the buffer has passed
|
|
||||||
* csum validation but before the pages are unlocked. It is also set by
|
|
||||||
* btrfs_init_new_buffer on freshly allocated blocks.
|
|
||||||
*
|
|
||||||
* We also add a check to make sure the highest level of the tree is the
|
|
||||||
* same as our lockdep setup here. If BTRFS_MAX_LEVEL changes, this code
|
|
||||||
* needs update as well.
|
|
||||||
*/
|
|
||||||
#ifdef CONFIG_DEBUG_LOCK_ALLOC
|
|
||||||
# if BTRFS_MAX_LEVEL != 8
|
|
||||||
# error
|
|
||||||
# endif
|
|
||||||
|
|
||||||
#define DEFINE_LEVEL(stem, level) \
|
|
||||||
.names[level] = "btrfs-" stem "-0" #level,
|
|
||||||
|
|
||||||
#define DEFINE_NAME(stem) \
|
|
||||||
DEFINE_LEVEL(stem, 0) \
|
|
||||||
DEFINE_LEVEL(stem, 1) \
|
|
||||||
DEFINE_LEVEL(stem, 2) \
|
|
||||||
DEFINE_LEVEL(stem, 3) \
|
|
||||||
DEFINE_LEVEL(stem, 4) \
|
|
||||||
DEFINE_LEVEL(stem, 5) \
|
|
||||||
DEFINE_LEVEL(stem, 6) \
|
|
||||||
DEFINE_LEVEL(stem, 7)
|
|
||||||
|
|
||||||
static struct btrfs_lockdep_keyset {
|
|
||||||
u64 id; /* root objectid */
|
|
||||||
/* Longest entry: btrfs-free-space-00 */
|
|
||||||
char names[BTRFS_MAX_LEVEL][20];
|
|
||||||
struct lock_class_key keys[BTRFS_MAX_LEVEL];
|
|
||||||
} btrfs_lockdep_keysets[] = {
|
|
||||||
{ .id = BTRFS_ROOT_TREE_OBJECTID, DEFINE_NAME("root") },
|
|
||||||
{ .id = BTRFS_EXTENT_TREE_OBJECTID, DEFINE_NAME("extent") },
|
|
||||||
{ .id = BTRFS_CHUNK_TREE_OBJECTID, DEFINE_NAME("chunk") },
|
|
||||||
{ .id = BTRFS_DEV_TREE_OBJECTID, DEFINE_NAME("dev") },
|
|
||||||
{ .id = BTRFS_CSUM_TREE_OBJECTID, DEFINE_NAME("csum") },
|
|
||||||
{ .id = BTRFS_QUOTA_TREE_OBJECTID, DEFINE_NAME("quota") },
|
|
||||||
{ .id = BTRFS_TREE_LOG_OBJECTID, DEFINE_NAME("log") },
|
|
||||||
{ .id = BTRFS_TREE_RELOC_OBJECTID, DEFINE_NAME("treloc") },
|
|
||||||
{ .id = BTRFS_DATA_RELOC_TREE_OBJECTID, DEFINE_NAME("dreloc") },
|
|
||||||
{ .id = BTRFS_UUID_TREE_OBJECTID, DEFINE_NAME("uuid") },
|
|
||||||
{ .id = BTRFS_FREE_SPACE_TREE_OBJECTID, DEFINE_NAME("free-space") },
|
|
||||||
{ .id = 0, DEFINE_NAME("tree") },
|
|
||||||
};
|
|
||||||
|
|
||||||
#undef DEFINE_LEVEL
|
|
||||||
#undef DEFINE_NAME
|
|
||||||
|
|
||||||
void btrfs_set_buffer_lockdep_class(u64 objectid, struct extent_buffer *eb,
|
|
||||||
int level)
|
|
||||||
{
|
|
||||||
struct btrfs_lockdep_keyset *ks;
|
|
||||||
|
|
||||||
BUG_ON(level >= ARRAY_SIZE(ks->keys));
|
|
||||||
|
|
||||||
/* find the matching keyset, id 0 is the default entry */
|
|
||||||
for (ks = btrfs_lockdep_keysets; ks->id; ks++)
|
|
||||||
if (ks->id == objectid)
|
|
||||||
break;
|
|
||||||
|
|
||||||
lockdep_set_class_and_name(&eb->lock,
|
|
||||||
&ks->keys[level], ks->names[level]);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Compute the csum of a btree block and store the result to provided buffer.
|
* Compute the csum of a btree block and store the result to provided buffer.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -137,14 +137,4 @@ int btrfs_get_num_tolerated_disk_barrier_failures(u64 flags);
|
||||||
int btrfs_get_free_objectid(struct btrfs_root *root, u64 *objectid);
|
int btrfs_get_free_objectid(struct btrfs_root *root, u64 *objectid);
|
||||||
int btrfs_init_root_free_objectid(struct btrfs_root *root);
|
int btrfs_init_root_free_objectid(struct btrfs_root *root);
|
||||||
|
|
||||||
#ifdef CONFIG_DEBUG_LOCK_ALLOC
|
|
||||||
void btrfs_set_buffer_lockdep_class(u64 objectid,
|
|
||||||
struct extent_buffer *eb, int level);
|
|
||||||
#else
|
|
||||||
static inline void btrfs_set_buffer_lockdep_class(u64 objectid,
|
|
||||||
struct extent_buffer *eb, int level)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -13,6 +13,86 @@
|
||||||
#include "extent_io.h"
|
#include "extent_io.h"
|
||||||
#include "locking.h"
|
#include "locking.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Lockdep class keys for extent_buffer->lock's in this root. For a given
|
||||||
|
* eb, the lockdep key is determined by the btrfs_root it belongs to and
|
||||||
|
* the level the eb occupies in the tree.
|
||||||
|
*
|
||||||
|
* Different roots are used for different purposes and may nest inside each
|
||||||
|
* other and they require separate keysets. As lockdep keys should be
|
||||||
|
* static, assign keysets according to the purpose of the root as indicated
|
||||||
|
* by btrfs_root->root_key.objectid. This ensures that all special purpose
|
||||||
|
* roots have separate keysets.
|
||||||
|
*
|
||||||
|
* Lock-nesting across peer nodes is always done with the immediate parent
|
||||||
|
* node locked thus preventing deadlock. As lockdep doesn't know this, use
|
||||||
|
* subclass to avoid triggering lockdep warning in such cases.
|
||||||
|
*
|
||||||
|
* The key is set by the readpage_end_io_hook after the buffer has passed
|
||||||
|
* csum validation but before the pages are unlocked. It is also set by
|
||||||
|
* btrfs_init_new_buffer on freshly allocated blocks.
|
||||||
|
*
|
||||||
|
* We also add a check to make sure the highest level of the tree is the
|
||||||
|
* same as our lockdep setup here. If BTRFS_MAX_LEVEL changes, this code
|
||||||
|
* needs update as well.
|
||||||
|
*/
|
||||||
|
#ifdef CONFIG_DEBUG_LOCK_ALLOC
|
||||||
|
#if BTRFS_MAX_LEVEL != 8
|
||||||
|
#error
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define DEFINE_LEVEL(stem, level) \
|
||||||
|
.names[level] = "btrfs-" stem "-0" #level,
|
||||||
|
|
||||||
|
#define DEFINE_NAME(stem) \
|
||||||
|
DEFINE_LEVEL(stem, 0) \
|
||||||
|
DEFINE_LEVEL(stem, 1) \
|
||||||
|
DEFINE_LEVEL(stem, 2) \
|
||||||
|
DEFINE_LEVEL(stem, 3) \
|
||||||
|
DEFINE_LEVEL(stem, 4) \
|
||||||
|
DEFINE_LEVEL(stem, 5) \
|
||||||
|
DEFINE_LEVEL(stem, 6) \
|
||||||
|
DEFINE_LEVEL(stem, 7)
|
||||||
|
|
||||||
|
static struct btrfs_lockdep_keyset {
|
||||||
|
u64 id; /* root objectid */
|
||||||
|
/* Longest entry: btrfs-free-space-00 */
|
||||||
|
char names[BTRFS_MAX_LEVEL][20];
|
||||||
|
struct lock_class_key keys[BTRFS_MAX_LEVEL];
|
||||||
|
} btrfs_lockdep_keysets[] = {
|
||||||
|
{ .id = BTRFS_ROOT_TREE_OBJECTID, DEFINE_NAME("root") },
|
||||||
|
{ .id = BTRFS_EXTENT_TREE_OBJECTID, DEFINE_NAME("extent") },
|
||||||
|
{ .id = BTRFS_CHUNK_TREE_OBJECTID, DEFINE_NAME("chunk") },
|
||||||
|
{ .id = BTRFS_DEV_TREE_OBJECTID, DEFINE_NAME("dev") },
|
||||||
|
{ .id = BTRFS_CSUM_TREE_OBJECTID, DEFINE_NAME("csum") },
|
||||||
|
{ .id = BTRFS_QUOTA_TREE_OBJECTID, DEFINE_NAME("quota") },
|
||||||
|
{ .id = BTRFS_TREE_LOG_OBJECTID, DEFINE_NAME("log") },
|
||||||
|
{ .id = BTRFS_TREE_RELOC_OBJECTID, DEFINE_NAME("treloc") },
|
||||||
|
{ .id = BTRFS_DATA_RELOC_TREE_OBJECTID, DEFINE_NAME("dreloc") },
|
||||||
|
{ .id = BTRFS_UUID_TREE_OBJECTID, DEFINE_NAME("uuid") },
|
||||||
|
{ .id = BTRFS_FREE_SPACE_TREE_OBJECTID, DEFINE_NAME("free-space") },
|
||||||
|
{ .id = 0, DEFINE_NAME("tree") },
|
||||||
|
};
|
||||||
|
|
||||||
|
#undef DEFINE_LEVEL
|
||||||
|
#undef DEFINE_NAME
|
||||||
|
|
||||||
|
void btrfs_set_buffer_lockdep_class(u64 objectid, struct extent_buffer *eb, int level)
|
||||||
|
{
|
||||||
|
struct btrfs_lockdep_keyset *ks;
|
||||||
|
|
||||||
|
BUG_ON(level >= ARRAY_SIZE(ks->keys));
|
||||||
|
|
||||||
|
/* Find the matching keyset, id 0 is the default entry */
|
||||||
|
for (ks = btrfs_lockdep_keysets; ks->id; ks++)
|
||||||
|
if (ks->id == objectid)
|
||||||
|
break;
|
||||||
|
|
||||||
|
lockdep_set_class_and_name(&eb->lock, &ks->keys[level], ks->names[level]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Extent buffer locking
|
* Extent buffer locking
|
||||||
* =====================
|
* =====================
|
||||||
|
|
|
@ -131,4 +131,13 @@ void btrfs_drew_write_unlock(struct btrfs_drew_lock *lock);
|
||||||
void btrfs_drew_read_lock(struct btrfs_drew_lock *lock);
|
void btrfs_drew_read_lock(struct btrfs_drew_lock *lock);
|
||||||
void btrfs_drew_read_unlock(struct btrfs_drew_lock *lock);
|
void btrfs_drew_read_unlock(struct btrfs_drew_lock *lock);
|
||||||
|
|
||||||
|
#ifdef CONFIG_DEBUG_LOCK_ALLOC
|
||||||
|
void btrfs_set_buffer_lockdep_class(u64 objectid, struct extent_buffer *eb, int level);
|
||||||
|
#else
|
||||||
|
static inline void btrfs_set_buffer_lockdep_class(u64 objectid,
|
||||||
|
struct extent_buffer *eb, int level)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue