Skip to content

Commit 42c54d5

Browse files
committed
Merge tag 'for-6.0-rc1-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux
Pull btrfs fixes from David Sterba: "A few short fixes and a lockdep warning fix (needs moving some code): - tree-log replay fixes: - fix error handling when looking up extent refs - fix warning when setting inode number of links - relocation fixes: - reset block group read-only status when relocation fails - unset control structure if transaction fails when starting to process a block group - add lockdep annotations to fix a warning during relocation where blocks temporarily belong to another tree and can lead to reversed dependencies - tree-checker verifies that extent items don't overlap" * tag 'for-6.0-rc1-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux: btrfs: tree-checker: check for overlapping extent items btrfs: fix warning during log replay when bumping inode link count btrfs: fix lost error handling when looking up extended ref on log replay btrfs: fix lockdep splat with reloc root extent buffers btrfs: move lockdep class helpers to locking.c btrfs: unset reloc control if transaction commit fails in prepare_to_relocate() btrfs: reset RO counter on block group if we fail to relocate
2 parents a3a78b6 + 899b7f6 commit 42c54d5

File tree

12 files changed

+176
-101
lines changed

12 files changed

+176
-101
lines changed

fs/btrfs/block-group.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1640,9 +1640,11 @@ void btrfs_reclaim_bgs_work(struct work_struct *work)
16401640
div64_u64(zone_unusable * 100, bg->length));
16411641
trace_btrfs_reclaim_block_group(bg);
16421642
ret = btrfs_relocate_chunk(fs_info, bg->start);
1643-
if (ret)
1643+
if (ret) {
1644+
btrfs_dec_block_group_ro(bg);
16441645
btrfs_err(fs_info, "error relocating chunk %llu",
16451646
bg->start);
1647+
}
16461648

16471649
next:
16481650
btrfs_put_block_group(bg);

fs/btrfs/ctree.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2075,6 +2075,9 @@ int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root *root,
20752075

20762076
if (!p->skip_locking) {
20772077
level = btrfs_header_level(b);
2078+
2079+
btrfs_maybe_reset_lockdep_class(root, b);
2080+
20782081
if (level <= write_lock_level) {
20792082
btrfs_tree_lock(b);
20802083
p->locks[level] = BTRFS_WRITE_LOCK;

fs/btrfs/ctree.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1173,6 +1173,8 @@ enum {
11731173
BTRFS_ROOT_ORPHAN_CLEANUP,
11741174
/* This root has a drop operation that was started previously. */
11751175
BTRFS_ROOT_UNFINISHED_DROP,
1176+
/* This reloc root needs to have its buffers lockdep class reset. */
1177+
BTRFS_ROOT_RESET_LOCKDEP_CLASS,
11761178
};
11771179

11781180
static inline void btrfs_wake_unfinished_drop(struct btrfs_fs_info *fs_info)

fs/btrfs/disk-io.c

Lines changed: 0 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -86,88 +86,6 @@ struct async_submit_bio {
8686
blk_status_t status;
8787
};
8888

89-
/*
90-
* Lockdep class keys for extent_buffer->lock's in this root. For a given
91-
* eb, the lockdep key is determined by the btrfs_root it belongs to and
92-
* the level the eb occupies in the tree.
93-
*
94-
* Different roots are used for different purposes and may nest inside each
95-
* other and they require separate keysets. As lockdep keys should be
96-
* static, assign keysets according to the purpose of the root as indicated
97-
* by btrfs_root->root_key.objectid. This ensures that all special purpose
98-
* roots have separate keysets.
99-
*
100-
* Lock-nesting across peer nodes is always done with the immediate parent
101-
* node locked thus preventing deadlock. As lockdep doesn't know this, use
102-
* subclass to avoid triggering lockdep warning in such cases.
103-
*
104-
* The key is set by the readpage_end_io_hook after the buffer has passed
105-
* csum validation but before the pages are unlocked. It is also set by
106-
* btrfs_init_new_buffer on freshly allocated blocks.
107-
*
108-
* We also add a check to make sure the highest level of the tree is the
109-
* same as our lockdep setup here. If BTRFS_MAX_LEVEL changes, this code
110-
* needs update as well.
111-
*/
112-
#ifdef CONFIG_DEBUG_LOCK_ALLOC
113-
# if BTRFS_MAX_LEVEL != 8
114-
# error
115-
# endif
116-
117-
#define DEFINE_LEVEL(stem, level) \
118-
.names[level] = "btrfs-" stem "-0" #level,
119-
120-
#define DEFINE_NAME(stem) \
121-
DEFINE_LEVEL(stem, 0) \
122-
DEFINE_LEVEL(stem, 1) \
123-
DEFINE_LEVEL(stem, 2) \
124-
DEFINE_LEVEL(stem, 3) \
125-
DEFINE_LEVEL(stem, 4) \
126-
DEFINE_LEVEL(stem, 5) \
127-
DEFINE_LEVEL(stem, 6) \
128-
DEFINE_LEVEL(stem, 7)
129-
130-
static struct btrfs_lockdep_keyset {
131-
u64 id; /* root objectid */
132-
/* Longest entry: btrfs-free-space-00 */
133-
char names[BTRFS_MAX_LEVEL][20];
134-
struct lock_class_key keys[BTRFS_MAX_LEVEL];
135-
} btrfs_lockdep_keysets[] = {
136-
{ .id = BTRFS_ROOT_TREE_OBJECTID, DEFINE_NAME("root") },
137-
{ .id = BTRFS_EXTENT_TREE_OBJECTID, DEFINE_NAME("extent") },
138-
{ .id = BTRFS_CHUNK_TREE_OBJECTID, DEFINE_NAME("chunk") },
139-
{ .id = BTRFS_DEV_TREE_OBJECTID, DEFINE_NAME("dev") },
140-
{ .id = BTRFS_CSUM_TREE_OBJECTID, DEFINE_NAME("csum") },
141-
{ .id = BTRFS_QUOTA_TREE_OBJECTID, DEFINE_NAME("quota") },
142-
{ .id = BTRFS_TREE_LOG_OBJECTID, DEFINE_NAME("log") },
143-
{ .id = BTRFS_TREE_RELOC_OBJECTID, DEFINE_NAME("treloc") },
144-
{ .id = BTRFS_DATA_RELOC_TREE_OBJECTID, DEFINE_NAME("dreloc") },
145-
{ .id = BTRFS_UUID_TREE_OBJECTID, DEFINE_NAME("uuid") },
146-
{ .id = BTRFS_FREE_SPACE_TREE_OBJECTID, DEFINE_NAME("free-space") },
147-
{ .id = 0, DEFINE_NAME("tree") },
148-
};
149-
150-
#undef DEFINE_LEVEL
151-
#undef DEFINE_NAME
152-
153-
void btrfs_set_buffer_lockdep_class(u64 objectid, struct extent_buffer *eb,
154-
int level)
155-
{
156-
struct btrfs_lockdep_keyset *ks;
157-
158-
BUG_ON(level >= ARRAY_SIZE(ks->keys));
159-
160-
/* find the matching keyset, id 0 is the default entry */
161-
for (ks = btrfs_lockdep_keysets; ks->id; ks++)
162-
if (ks->id == objectid)
163-
break;
164-
165-
lockdep_set_class_and_name(&eb->lock,
166-
&ks->keys[level], ks->names[level]);
167-
}
168-
169-
#endif
170-
17189
/*
17290
* Compute the csum of a btree block and store the result to provided buffer.
17391
*/

fs/btrfs/disk-io.h

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -137,14 +137,4 @@ int btrfs_get_num_tolerated_disk_barrier_failures(u64 flags);
137137
int btrfs_get_free_objectid(struct btrfs_root *root, u64 *objectid);
138138
int btrfs_init_root_free_objectid(struct btrfs_root *root);
139139

140-
#ifdef CONFIG_DEBUG_LOCK_ALLOC
141-
void btrfs_set_buffer_lockdep_class(u64 objectid,
142-
struct extent_buffer *eb, int level);
143-
#else
144-
static inline void btrfs_set_buffer_lockdep_class(u64 objectid,
145-
struct extent_buffer *eb, int level)
146-
{
147-
}
148-
#endif
149-
150140
#endif

fs/btrfs/extent-tree.c

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4867,6 +4867,7 @@ btrfs_init_new_buffer(struct btrfs_trans_handle *trans, struct btrfs_root *root,
48674867
{
48684868
struct btrfs_fs_info *fs_info = root->fs_info;
48694869
struct extent_buffer *buf;
4870+
u64 lockdep_owner = owner;
48704871

48714872
buf = btrfs_find_create_tree_block(fs_info, bytenr, owner, level);
48724873
if (IS_ERR(buf))
@@ -4885,12 +4886,27 @@ btrfs_init_new_buffer(struct btrfs_trans_handle *trans, struct btrfs_root *root,
48854886
return ERR_PTR(-EUCLEAN);
48864887
}
48874888

4889+
/*
4890+
* The reloc trees are just snapshots, so we need them to appear to be
4891+
* just like any other fs tree WRT lockdep.
4892+
*
4893+
* The exception however is in replace_path() in relocation, where we
4894+
* hold the lock on the original fs root and then search for the reloc
4895+
* root. At that point we need to make sure any reloc root buffers are
4896+
* set to the BTRFS_TREE_RELOC_OBJECTID lockdep class in order to make
4897+
* lockdep happy.
4898+
*/
4899+
if (lockdep_owner == BTRFS_TREE_RELOC_OBJECTID &&
4900+
!test_bit(BTRFS_ROOT_RESET_LOCKDEP_CLASS, &root->state))
4901+
lockdep_owner = BTRFS_FS_TREE_OBJECTID;
4902+
48884903
/*
48894904
* This needs to stay, because we could allocate a freed block from an
48904905
* old tree into a new tree, so we need to make sure this new block is
48914906
* set to the appropriate level and owner.
48924907
*/
4893-
btrfs_set_buffer_lockdep_class(owner, buf, level);
4908+
btrfs_set_buffer_lockdep_class(lockdep_owner, buf, level);
4909+
48944910
__btrfs_tree_lock(buf, nest);
48954911
btrfs_clean_tree_block(buf);
48964912
clear_bit(EXTENT_BUFFER_STALE, &buf->bflags);

fs/btrfs/extent_io.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6140,6 +6140,7 @@ struct extent_buffer *alloc_extent_buffer(struct btrfs_fs_info *fs_info,
61406140
struct extent_buffer *exists = NULL;
61416141
struct page *p;
61426142
struct address_space *mapping = fs_info->btree_inode->i_mapping;
6143+
u64 lockdep_owner = owner_root;
61436144
int uptodate = 1;
61446145
int ret;
61456146

@@ -6164,7 +6165,15 @@ struct extent_buffer *alloc_extent_buffer(struct btrfs_fs_info *fs_info,
61646165
eb = __alloc_extent_buffer(fs_info, start, len);
61656166
if (!eb)
61666167
return ERR_PTR(-ENOMEM);
6167-
btrfs_set_buffer_lockdep_class(owner_root, eb, level);
6168+
6169+
/*
6170+
* The reloc trees are just snapshots, so we need them to appear to be
6171+
* just like any other fs tree WRT lockdep.
6172+
*/
6173+
if (lockdep_owner == BTRFS_TREE_RELOC_OBJECTID)
6174+
lockdep_owner = BTRFS_FS_TREE_OBJECTID;
6175+
6176+
btrfs_set_buffer_lockdep_class(lockdep_owner, eb, level);
61686177

61696178
num_pages = num_extent_pages(eb);
61706179
for (i = 0; i < num_pages; i++, index++) {

fs/btrfs/locking.c

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,93 @@
1313
#include "extent_io.h"
1414
#include "locking.h"
1515

16+
/*
17+
* Lockdep class keys for extent_buffer->lock's in this root. For a given
18+
* eb, the lockdep key is determined by the btrfs_root it belongs to and
19+
* the level the eb occupies in the tree.
20+
*
21+
* Different roots are used for different purposes and may nest inside each
22+
* other and they require separate keysets. As lockdep keys should be
23+
* static, assign keysets according to the purpose of the root as indicated
24+
* by btrfs_root->root_key.objectid. This ensures that all special purpose
25+
* roots have separate keysets.
26+
*
27+
* Lock-nesting across peer nodes is always done with the immediate parent
28+
* node locked thus preventing deadlock. As lockdep doesn't know this, use
29+
* subclass to avoid triggering lockdep warning in such cases.
30+
*
31+
* The key is set by the readpage_end_io_hook after the buffer has passed
32+
* csum validation but before the pages are unlocked. It is also set by
33+
* btrfs_init_new_buffer on freshly allocated blocks.
34+
*
35+
* We also add a check to make sure the highest level of the tree is the
36+
* same as our lockdep setup here. If BTRFS_MAX_LEVEL changes, this code
37+
* needs update as well.
38+
*/
39+
#ifdef CONFIG_DEBUG_LOCK_ALLOC
40+
#if BTRFS_MAX_LEVEL != 8
41+
#error
42+
#endif
43+
44+
#define DEFINE_LEVEL(stem, level) \
45+
.names[level] = "btrfs-" stem "-0" #level,
46+
47+
#define DEFINE_NAME(stem) \
48+
DEFINE_LEVEL(stem, 0) \
49+
DEFINE_LEVEL(stem, 1) \
50+
DEFINE_LEVEL(stem, 2) \
51+
DEFINE_LEVEL(stem, 3) \
52+
DEFINE_LEVEL(stem, 4) \
53+
DEFINE_LEVEL(stem, 5) \
54+
DEFINE_LEVEL(stem, 6) \
55+
DEFINE_LEVEL(stem, 7)
56+
57+
static struct btrfs_lockdep_keyset {
58+
u64 id; /* root objectid */
59+
/* Longest entry: btrfs-free-space-00 */
60+
char names[BTRFS_MAX_LEVEL][20];
61+
struct lock_class_key keys[BTRFS_MAX_LEVEL];
62+
} btrfs_lockdep_keysets[] = {
63+
{ .id = BTRFS_ROOT_TREE_OBJECTID, DEFINE_NAME("root") },
64+
{ .id = BTRFS_EXTENT_TREE_OBJECTID, DEFINE_NAME("extent") },
65+
{ .id = BTRFS_CHUNK_TREE_OBJECTID, DEFINE_NAME("chunk") },
66+
{ .id = BTRFS_DEV_TREE_OBJECTID, DEFINE_NAME("dev") },
67+
{ .id = BTRFS_CSUM_TREE_OBJECTID, DEFINE_NAME("csum") },
68+
{ .id = BTRFS_QUOTA_TREE_OBJECTID, DEFINE_NAME("quota") },
69+
{ .id = BTRFS_TREE_LOG_OBJECTID, DEFINE_NAME("log") },
70+
{ .id = BTRFS_TREE_RELOC_OBJECTID, DEFINE_NAME("treloc") },
71+
{ .id = BTRFS_DATA_RELOC_TREE_OBJECTID, DEFINE_NAME("dreloc") },
72+
{ .id = BTRFS_UUID_TREE_OBJECTID, DEFINE_NAME("uuid") },
73+
{ .id = BTRFS_FREE_SPACE_TREE_OBJECTID, DEFINE_NAME("free-space") },
74+
{ .id = 0, DEFINE_NAME("tree") },
75+
};
76+
77+
#undef DEFINE_LEVEL
78+
#undef DEFINE_NAME
79+
80+
void btrfs_set_buffer_lockdep_class(u64 objectid, struct extent_buffer *eb, int level)
81+
{
82+
struct btrfs_lockdep_keyset *ks;
83+
84+
BUG_ON(level >= ARRAY_SIZE(ks->keys));
85+
86+
/* Find the matching keyset, id 0 is the default entry */
87+
for (ks = btrfs_lockdep_keysets; ks->id; ks++)
88+
if (ks->id == objectid)
89+
break;
90+
91+
lockdep_set_class_and_name(&eb->lock, &ks->keys[level], ks->names[level]);
92+
}
93+
94+
void btrfs_maybe_reset_lockdep_class(struct btrfs_root *root, struct extent_buffer *eb)
95+
{
96+
if (test_bit(BTRFS_ROOT_RESET_LOCKDEP_CLASS, &root->state))
97+
btrfs_set_buffer_lockdep_class(root->root_key.objectid,
98+
eb, btrfs_header_level(eb));
99+
}
100+
101+
#endif
102+
16103
/*
17104
* Extent buffer locking
18105
* =====================
@@ -164,6 +251,8 @@ struct extent_buffer *btrfs_lock_root_node(struct btrfs_root *root)
164251

165252
while (1) {
166253
eb = btrfs_root_node(root);
254+
255+
btrfs_maybe_reset_lockdep_class(root, eb);
167256
btrfs_tree_lock(eb);
168257
if (eb == root->node)
169258
break;
@@ -185,6 +274,8 @@ struct extent_buffer *btrfs_read_lock_root_node(struct btrfs_root *root)
185274

186275
while (1) {
187276
eb = btrfs_root_node(root);
277+
278+
btrfs_maybe_reset_lockdep_class(root, eb);
188279
btrfs_tree_read_lock(eb);
189280
if (eb == root->node)
190281
break;

fs/btrfs/locking.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,4 +131,18 @@ void btrfs_drew_write_unlock(struct btrfs_drew_lock *lock);
131131
void btrfs_drew_read_lock(struct btrfs_drew_lock *lock);
132132
void btrfs_drew_read_unlock(struct btrfs_drew_lock *lock);
133133

134+
#ifdef CONFIG_DEBUG_LOCK_ALLOC
135+
void btrfs_set_buffer_lockdep_class(u64 objectid, struct extent_buffer *eb, int level);
136+
void btrfs_maybe_reset_lockdep_class(struct btrfs_root *root, struct extent_buffer *eb);
137+
#else
138+
static inline void btrfs_set_buffer_lockdep_class(u64 objectid,
139+
struct extent_buffer *eb, int level)
140+
{
141+
}
142+
static inline void btrfs_maybe_reset_lockdep_class(struct btrfs_root *root,
143+
struct extent_buffer *eb)
144+
{
145+
}
146+
#endif
147+
134148
#endif

fs/btrfs/relocation.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1326,7 +1326,9 @@ int replace_path(struct btrfs_trans_handle *trans, struct reloc_control *rc,
13261326
btrfs_release_path(path);
13271327

13281328
path->lowest_level = level;
1329+
set_bit(BTRFS_ROOT_RESET_LOCKDEP_CLASS, &src->state);
13291330
ret = btrfs_search_slot(trans, src, &key, path, 0, 1);
1331+
clear_bit(BTRFS_ROOT_RESET_LOCKDEP_CLASS, &src->state);
13301332
path->lowest_level = 0;
13311333
if (ret) {
13321334
if (ret > 0)
@@ -3573,7 +3575,12 @@ int prepare_to_relocate(struct reloc_control *rc)
35733575
*/
35743576
return PTR_ERR(trans);
35753577
}
3576-
return btrfs_commit_transaction(trans);
3578+
3579+
ret = btrfs_commit_transaction(trans);
3580+
if (ret)
3581+
unset_reloc_control(rc);
3582+
3583+
return ret;
35773584
}
35783585

35793586
static noinline_for_stack int relocate_block_group(struct reloc_control *rc)

0 commit comments

Comments
 (0)