Skip to content

Commit 0e39a73

Browse files
committed
Merge tag 'for-6.17-rc1-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux
Pull btrfs fixes from David Sterba: - fix bug in qgroups reporting incorrect usage for higher level qgroups - in zoned mode, do not select metadata group as finish target - convert xarray lock to RCU when trying to release extent buffer to avoid a deadlock - do not allow relocation on partially dropped subvolumes, which is normally not possible but has been reported on old filesystems - in tree-log, report errors on missing block group when unaccounting log tree extent buffers - with large folios, fix range length when processing ordered extents * tag 'for-6.17-rc1-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux: btrfs: fix iteration bug in __qgroup_excl_accounting() btrfs: zoned: do not select metadata BG as finish target btrfs: do not allow relocation of partially dropped subvolumes btrfs: error on missing block group when unaccounting log tree extent buffers btrfs: fix wrong length parameter for btrfs_cleanup_ordered_extents() btrfs: make btrfs_cleanup_ordered_extents() support large folios btrfs: fix subpage deadlock in try_release_subpage_extent_buffer()
2 parents 20e0d85 + 7b63259 commit 0e39a73

File tree

6 files changed

+39
-23
lines changed

6 files changed

+39
-23
lines changed

fs/btrfs/extent_io.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4331,15 +4331,18 @@ static int try_release_subpage_extent_buffer(struct folio *folio)
43314331
unsigned long end = index + (PAGE_SIZE >> fs_info->nodesize_bits) - 1;
43324332
int ret;
43334333

4334-
xa_lock_irq(&fs_info->buffer_tree);
4334+
rcu_read_lock();
43354335
xa_for_each_range(&fs_info->buffer_tree, index, eb, start, end) {
43364336
/*
43374337
* The same as try_release_extent_buffer(), to ensure the eb
43384338
* won't disappear out from under us.
43394339
*/
43404340
spin_lock(&eb->refs_lock);
4341+
rcu_read_unlock();
4342+
43414343
if (refcount_read(&eb->refs) != 1 || extent_buffer_under_io(eb)) {
43424344
spin_unlock(&eb->refs_lock);
4345+
rcu_read_lock();
43434346
continue;
43444347
}
43454348

@@ -4358,11 +4361,10 @@ static int try_release_subpage_extent_buffer(struct folio *folio)
43584361
* check the folio private at the end. And
43594362
* release_extent_buffer() will release the refs_lock.
43604363
*/
4361-
xa_unlock_irq(&fs_info->buffer_tree);
43624364
release_extent_buffer(eb);
4363-
xa_lock_irq(&fs_info->buffer_tree);
4365+
rcu_read_lock();
43644366
}
4365-
xa_unlock_irq(&fs_info->buffer_tree);
4367+
rcu_read_unlock();
43664368

43674369
/*
43684370
* Finally to check if we have cleared folio private, as if we have
@@ -4375,7 +4377,6 @@ static int try_release_subpage_extent_buffer(struct folio *folio)
43754377
ret = 0;
43764378
spin_unlock(&folio->mapping->i_private_lock);
43774379
return ret;
4378-
43794380
}
43804381

43814382
int try_release_extent_buffer(struct folio *folio)

fs/btrfs/inode.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -401,10 +401,12 @@ static inline void btrfs_cleanup_ordered_extents(struct btrfs_inode *inode,
401401

402402
while (index <= end_index) {
403403
folio = filemap_get_folio(inode->vfs_inode.i_mapping, index);
404-
index++;
405-
if (IS_ERR(folio))
404+
if (IS_ERR(folio)) {
405+
index++;
406406
continue;
407+
}
407408

409+
index = folio_end(folio) >> PAGE_SHIFT;
408410
/*
409411
* Here we just clear all Ordered bits for every page in the
410412
* range, then btrfs_mark_ordered_io_finished() will handle
@@ -2013,7 +2015,7 @@ static int nocow_one_range(struct btrfs_inode *inode, struct folio *locked_folio
20132015
* cleaered by the caller.
20142016
*/
20152017
if (ret < 0)
2016-
btrfs_cleanup_ordered_extents(inode, file_pos, end);
2018+
btrfs_cleanup_ordered_extents(inode, file_pos, len);
20172019
return ret;
20182020
}
20192021

fs/btrfs/qgroup.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1453,7 +1453,6 @@ static int __qgroup_excl_accounting(struct btrfs_fs_info *fs_info, u64 ref_root,
14531453
struct btrfs_qgroup *src, int sign)
14541454
{
14551455
struct btrfs_qgroup *qgroup;
1456-
struct btrfs_qgroup *cur;
14571456
LIST_HEAD(qgroup_list);
14581457
u64 num_bytes = src->excl;
14591458
int ret = 0;
@@ -1463,7 +1462,7 @@ static int __qgroup_excl_accounting(struct btrfs_fs_info *fs_info, u64 ref_root,
14631462
goto out;
14641463

14651464
qgroup_iterator_add(&qgroup_list, qgroup);
1466-
list_for_each_entry(cur, &qgroup_list, iterator) {
1465+
list_for_each_entry(qgroup, &qgroup_list, iterator) {
14671466
struct btrfs_qgroup_list *glist;
14681467

14691468
qgroup->rfer += sign * num_bytes;

fs/btrfs/relocation.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -602,6 +602,25 @@ static struct btrfs_root *create_reloc_root(struct btrfs_trans_handle *trans,
602602
if (btrfs_root_id(root) == objectid) {
603603
u64 commit_root_gen;
604604

605+
/*
606+
* Relocation will wait for cleaner thread, and any half-dropped
607+
* subvolume will be fully cleaned up at mount time.
608+
* So here we shouldn't hit a subvolume with non-zero drop_progress.
609+
*
610+
* If this isn't the case, error out since it can make us attempt to
611+
* drop references for extents that were already dropped before.
612+
*/
613+
if (unlikely(btrfs_disk_key_objectid(&root->root_item.drop_progress))) {
614+
struct btrfs_key cpu_key;
615+
616+
btrfs_disk_key_to_cpu(&cpu_key, &root->root_item.drop_progress);
617+
btrfs_err(fs_info,
618+
"cannot relocate partially dropped subvolume %llu, drop progress key (%llu %u %llu)",
619+
objectid, cpu_key.objectid, cpu_key.type, cpu_key.offset);
620+
ret = -EUCLEAN;
621+
goto fail;
622+
}
623+
605624
/* called by btrfs_init_reloc_root */
606625
ret = btrfs_copy_root(trans, root, root->commit_root, &eb,
607626
BTRFS_TREE_RELOC_OBJECTID);

fs/btrfs/tree-log.c

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2605,14 +2605,14 @@ static int replay_one_buffer(struct btrfs_root *log, struct extent_buffer *eb,
26052605
/*
26062606
* Correctly adjust the reserved bytes occupied by a log tree extent buffer
26072607
*/
2608-
static void unaccount_log_buffer(struct btrfs_fs_info *fs_info, u64 start)
2608+
static int unaccount_log_buffer(struct btrfs_fs_info *fs_info, u64 start)
26092609
{
26102610
struct btrfs_block_group *cache;
26112611

26122612
cache = btrfs_lookup_block_group(fs_info, start);
26132613
if (!cache) {
26142614
btrfs_err(fs_info, "unable to find block group for %llu", start);
2615-
return;
2615+
return -ENOENT;
26162616
}
26172617

26182618
spin_lock(&cache->space_info->lock);
@@ -2623,27 +2623,22 @@ static void unaccount_log_buffer(struct btrfs_fs_info *fs_info, u64 start)
26232623
spin_unlock(&cache->space_info->lock);
26242624

26252625
btrfs_put_block_group(cache);
2626+
2627+
return 0;
26262628
}
26272629

26282630
static int clean_log_buffer(struct btrfs_trans_handle *trans,
26292631
struct extent_buffer *eb)
26302632
{
2631-
int ret;
2632-
26332633
btrfs_tree_lock(eb);
26342634
btrfs_clear_buffer_dirty(trans, eb);
26352635
wait_on_extent_buffer_writeback(eb);
26362636
btrfs_tree_unlock(eb);
26372637

2638-
if (trans) {
2639-
ret = btrfs_pin_reserved_extent(trans, eb);
2640-
if (ret)
2641-
return ret;
2642-
} else {
2643-
unaccount_log_buffer(eb->fs_info, eb->start);
2644-
}
2638+
if (trans)
2639+
return btrfs_pin_reserved_extent(trans, eb);
26452640

2646-
return 0;
2641+
return unaccount_log_buffer(eb->fs_info, eb->start);
26472642
}
26482643

26492644
static noinline int walk_down_log_tree(struct btrfs_trans_handle *trans,

fs/btrfs/zoned.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2650,7 +2650,7 @@ int btrfs_zone_finish_one_bg(struct btrfs_fs_info *fs_info)
26502650

26512651
spin_lock(&block_group->lock);
26522652
if (block_group->reserved || block_group->alloc_offset == 0 ||
2653-
(block_group->flags & BTRFS_BLOCK_GROUP_SYSTEM) ||
2653+
!(block_group->flags & BTRFS_BLOCK_GROUP_DATA) ||
26542654
test_bit(BLOCK_GROUP_FLAG_ZONED_DATA_RELOC, &block_group->runtime_flags)) {
26552655
spin_unlock(&block_group->lock);
26562656
continue;

0 commit comments

Comments
 (0)