Skip to content

Commit 9d65b5a

Browse files
committed
Merge branch 'misc-next' into for-next-next-v6.12-20241009
2 parents f0e3a4b + 7131d1b commit 9d65b5a

File tree

11 files changed

+337
-489
lines changed

11 files changed

+337
-489
lines changed

fs/btrfs/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
# SPDX-License-Identifier: GPL-2.0
2+
# misc-next marker
23

34
config BTRFS_FS
45
tristate "Btrfs filesystem support"

fs/btrfs/backref.c

Lines changed: 36 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -3021,9 +3021,6 @@ void btrfs_backref_init_cache(struct btrfs_fs_info *fs_info,
30213021
cache->rb_root = RB_ROOT;
30223022
for (i = 0; i < BTRFS_MAX_LEVEL; i++)
30233023
INIT_LIST_HEAD(&cache->pending[i]);
3024-
INIT_LIST_HEAD(&cache->changed);
3025-
INIT_LIST_HEAD(&cache->detached);
3026-
INIT_LIST_HEAD(&cache->leaves);
30273024
INIT_LIST_HEAD(&cache->pending_edge);
30283025
INIT_LIST_HEAD(&cache->useless_node);
30293026
cache->fs_info = fs_info;
@@ -3131,29 +3128,17 @@ void btrfs_backref_drop_node(struct btrfs_backref_cache *tree,
31313128
void btrfs_backref_cleanup_node(struct btrfs_backref_cache *cache,
31323129
struct btrfs_backref_node *node)
31333130
{
3134-
struct btrfs_backref_node *upper;
31353131
struct btrfs_backref_edge *edge;
31363132

31373133
if (!node)
31383134
return;
31393135

3140-
BUG_ON(!node->lowest && !node->detached);
31413136
while (!list_empty(&node->upper)) {
31423137
edge = list_entry(node->upper.next, struct btrfs_backref_edge,
31433138
list[LOWER]);
3144-
upper = edge->node[UPPER];
31453139
list_del(&edge->list[LOWER]);
31463140
list_del(&edge->list[UPPER]);
31473141
btrfs_backref_free_edge(cache, edge);
3148-
3149-
/*
3150-
* Add the node to leaf node list if no other child block
3151-
* cached.
3152-
*/
3153-
if (list_empty(&upper->lower)) {
3154-
list_add_tail(&upper->lower, &cache->leaves);
3155-
upper->lowest = 1;
3156-
}
31573142
}
31583143

31593144
btrfs_backref_drop_node(cache, node);
@@ -3165,33 +3150,13 @@ void btrfs_backref_cleanup_node(struct btrfs_backref_cache *cache,
31653150
void btrfs_backref_release_cache(struct btrfs_backref_cache *cache)
31663151
{
31673152
struct btrfs_backref_node *node;
3168-
int i;
3169-
3170-
while (!list_empty(&cache->detached)) {
3171-
node = list_entry(cache->detached.next,
3172-
struct btrfs_backref_node, list);
3173-
btrfs_backref_cleanup_node(cache, node);
3174-
}
31753153

3176-
while (!list_empty(&cache->leaves)) {
3177-
node = list_entry(cache->leaves.next,
3178-
struct btrfs_backref_node, lower);
3154+
while ((node = rb_entry_safe(rb_first(&cache->rb_root),
3155+
struct btrfs_backref_node, rb_node)))
31793156
btrfs_backref_cleanup_node(cache, node);
3180-
}
31813157

3182-
for (i = 0; i < BTRFS_MAX_LEVEL; i++) {
3183-
while (!list_empty(&cache->pending[i])) {
3184-
node = list_first_entry(&cache->pending[i],
3185-
struct btrfs_backref_node,
3186-
list);
3187-
btrfs_backref_cleanup_node(cache, node);
3188-
}
3189-
}
31903158
ASSERT(list_empty(&cache->pending_edge));
31913159
ASSERT(list_empty(&cache->useless_node));
3192-
ASSERT(list_empty(&cache->changed));
3193-
ASSERT(list_empty(&cache->detached));
3194-
ASSERT(RB_EMPTY_ROOT(&cache->rb_root));
31953160
ASSERT(!cache->nr_nodes);
31963161
ASSERT(!cache->nr_edges);
31973162
}
@@ -3315,8 +3280,16 @@ static int handle_indirect_tree_backref(struct btrfs_trans_handle *trans,
33153280
root = btrfs_get_fs_root(fs_info, ref_key->offset, false);
33163281
if (IS_ERR(root))
33173282
return PTR_ERR(root);
3318-
if (!test_bit(BTRFS_ROOT_SHAREABLE, &root->state))
3319-
cur->cowonly = 1;
3283+
3284+
/*
3285+
* We shouldn't be using backref cache for non shareable roots, ASSERT
3286+
* for developers, return -EUCLEAN for users.
3287+
*/
3288+
if (!test_bit(BTRFS_ROOT_SHAREABLE, &root->state)) {
3289+
btrfs_put_root(root);
3290+
ASSERT(0);
3291+
return -EUCLEAN;
3292+
}
33203293

33213294
if (btrfs_root_level(&root->root_item) == cur->level) {
33223295
/* Tree root */
@@ -3402,8 +3375,20 @@ static int handle_indirect_tree_backref(struct btrfs_trans_handle *trans,
34023375
goto out;
34033376
}
34043377
upper->owner = btrfs_header_owner(eb);
3405-
if (!test_bit(BTRFS_ROOT_SHAREABLE, &root->state))
3406-
upper->cowonly = 1;
3378+
3379+
/*
3380+
* We shouldn't be using backref cache for non shareable
3381+
* roots, ASSERT for developers, return -EUCLEAN for
3382+
* users.
3383+
*/
3384+
if (!test_bit(BTRFS_ROOT_SHAREABLE, &root->state)) {
3385+
btrfs_put_root(root);
3386+
btrfs_backref_free_edge(cache, edge);
3387+
btrfs_backref_free_node(cache, upper);
3388+
ASSERT(0);
3389+
ret = -EUCLEAN;
3390+
goto out;
3391+
}
34073392

34083393
/*
34093394
* If we know the block isn't shared we can avoid
@@ -3594,15 +3579,11 @@ int btrfs_backref_finish_upper_links(struct btrfs_backref_cache *cache,
35943579

35953580
ASSERT(start->checked);
35963581

3597-
/* Insert this node to cache if it's not COW-only */
3598-
if (!start->cowonly) {
3599-
rb_node = rb_simple_insert(&cache->rb_root, start->bytenr,
3600-
&start->rb_node);
3601-
if (rb_node)
3602-
btrfs_backref_panic(cache->fs_info, start->bytenr,
3603-
-EEXIST);
3604-
list_add_tail(&start->lower, &cache->leaves);
3605-
}
3582+
rb_node = rb_simple_insert(&cache->rb_root, start->bytenr,
3583+
&start->rb_node);
3584+
if (rb_node)
3585+
btrfs_backref_panic(cache->fs_info, start->bytenr,
3586+
-EEXIST);
36063587

36073588
/*
36083589
* Use breadth first search to iterate all related edges.
@@ -3641,11 +3622,6 @@ int btrfs_backref_finish_upper_links(struct btrfs_backref_cache *cache,
36413622
* parents have already been linked.
36423623
*/
36433624
if (!RB_EMPTY_NODE(&upper->rb_node)) {
3644-
if (upper->lowest) {
3645-
list_del_init(&upper->lower);
3646-
upper->lowest = 0;
3647-
}
3648-
36493625
list_add_tail(&edge->list[UPPER], &upper->lower);
36503626
continue;
36513627
}
@@ -3656,23 +3632,14 @@ int btrfs_backref_finish_upper_links(struct btrfs_backref_cache *cache,
36563632
return -EUCLEAN;
36573633
}
36583634

3659-
/* Sanity check, COW-only node has non-COW-only parent */
3660-
if (start->cowonly != upper->cowonly) {
3661-
ASSERT(0);
3635+
rb_node = rb_simple_insert(&cache->rb_root, upper->bytenr,
3636+
&upper->rb_node);
3637+
if (rb_node) {
3638+
btrfs_backref_panic(cache->fs_info,
3639+
upper->bytenr, -EEXIST);
36623640
return -EUCLEAN;
36633641
}
36643642

3665-
/* Only cache non-COW-only (subvolume trees) tree blocks */
3666-
if (!upper->cowonly) {
3667-
rb_node = rb_simple_insert(&cache->rb_root, upper->bytenr,
3668-
&upper->rb_node);
3669-
if (rb_node) {
3670-
btrfs_backref_panic(cache->fs_info,
3671-
upper->bytenr, -EEXIST);
3672-
return -EUCLEAN;
3673-
}
3674-
}
3675-
36763643
list_add_tail(&edge->list[UPPER], &upper->lower);
36773644

36783645
/*

fs/btrfs/backref.h

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,12 @@ struct btrfs_backref_node {
318318
u64 bytenr;
319319
}; /* Use rb_simple_node for search/insert */
320320

321+
/*
322+
* This is a sanity check, whenever we cow a block we will update
323+
* new_bytenr with it's current location, and we will check this in
324+
* various places to validate that the cache makes sense, it shouldn't
325+
* be used for anything else.
326+
*/
321327
u64 new_bytenr;
322328
/* Objectid of tree block owner, can be not uptodate */
323329
u64 owner;
@@ -335,10 +341,6 @@ struct btrfs_backref_node {
335341
struct extent_buffer *eb;
336342
/* Level of the tree block */
337343
unsigned int level:8;
338-
/* Is the block in a non-shareable tree */
339-
unsigned int cowonly:1;
340-
/* 1 if no child node is in the cache */
341-
unsigned int lowest:1;
342344
/* Is the extent buffer locked */
343345
unsigned int locked:1;
344346
/* Has the block been processed */
@@ -391,12 +393,6 @@ struct btrfs_backref_cache {
391393
* level blocks may not reflect the new location
392394
*/
393395
struct list_head pending[BTRFS_MAX_LEVEL];
394-
/* List of backref nodes with no child node */
395-
struct list_head leaves;
396-
/* List of blocks that have been COWed in current transaction */
397-
struct list_head changed;
398-
/* List of detached backref node. */
399-
struct list_head detached;
400396

401397
u64 last_trans;
402398

fs/btrfs/btrfs_inode.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -577,7 +577,6 @@ void btrfs_merge_delalloc_extent(struct btrfs_inode *inode, struct extent_state
577577
struct extent_state *other);
578578
void btrfs_split_delalloc_extent(struct btrfs_inode *inode,
579579
struct extent_state *orig, u64 split);
580-
void btrfs_set_range_writeback(struct btrfs_inode *inode, u64 start, u64 end);
581580
void btrfs_evict_inode(struct inode *inode);
582581
struct inode *btrfs_alloc_inode(struct super_block *sb);
583582
void btrfs_destroy_inode(struct inode *inode);

fs/btrfs/extent-tree.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5165,8 +5165,16 @@ struct extent_buffer *btrfs_alloc_tree_block(struct btrfs_trans_handle *trans,
51655165
parent = ins.objectid;
51665166
flags |= BTRFS_BLOCK_FLAG_FULL_BACKREF;
51675167
owning_root = reloc_src_root;
5168-
} else
5169-
BUG_ON(parent > 0);
5168+
} else {
5169+
if (unlikely(parent > 0)) {
5170+
/*
5171+
* Other roots than reloc tree don't expect start
5172+
* offset of a parent block.
5173+
*/
5174+
ret = -EUCLEAN;
5175+
goto out_free_reserved;
5176+
}
5177+
}
51705178

51715179
if (root_objectid != BTRFS_TREE_LOG_OBJECTID) {
51725180
struct btrfs_delayed_extent_op *extent_op;

fs/btrfs/extent_io.c

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -262,22 +262,21 @@ static noinline int lock_delalloc_folios(struct inode *inode,
262262

263263
for (i = 0; i < found_folios; i++) {
264264
struct folio *folio = fbatch.folios[i];
265-
u32 len = end + 1 - start;
265+
u64 range_start = max_t(u64, folio_pos(folio), start);
266+
u32 range_len = min_t(u64, folio_pos(folio) + folio_size(folio),
267+
end + 1) - range_start;
266268

267269
if (folio == locked_folio)
268270
continue;
269271

270-
if (btrfs_folio_start_writer_lock(fs_info, folio, start,
271-
len))
272-
goto out;
273-
272+
folio_lock(folio);
274273
if (!folio_test_dirty(folio) || folio->mapping != mapping) {
275-
btrfs_folio_end_writer_lock(fs_info, folio, start,
276-
len);
274+
folio_unlock(folio);
277275
goto out;
278276
}
277+
btrfs_folio_set_writer_lock(fs_info, folio, range_start, range_len);
279278

280-
processed_end = folio_pos(folio) + folio_size(folio) - 1;
279+
processed_end = range_start + range_len - 1;
281280
}
282281
folio_batch_release(&fbatch);
283282
cond_resched();
@@ -1359,7 +1358,7 @@ static int submit_one_sector(struct btrfs_inode *inode,
13591358
* a folio for a range already written to disk.
13601359
*/
13611360
btrfs_folio_clear_dirty(fs_info, folio, filepos, sectorsize);
1362-
btrfs_set_range_writeback(inode, filepos, filepos + sectorsize - 1);
1361+
btrfs_folio_set_writeback(fs_info, folio, filepos, sectorsize);
13631362
/*
13641363
* Above call should set the whole folio with writeback flag, even
13651364
* just for a single subpage sector.

0 commit comments

Comments
 (0)