mirror of
https://github.com/torvalds/linux.git
synced 2026-06-01 19:13:47 +02:00
for-6.17-rc1-tag
-----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEE8rQSAMVO+zA4DBdWxWXV+ddtWDsFAmibLJAACgkQxWXV+ddt WDvQnQ/7Bo9ruVKwbLrGAoLE0KAUIRL5gdLJrPdSUiKHXDXTqBqls+ST8Lo4u9VW jifNLva2lEH3Hexp8n2qDwm5jgmEz/cZT/91+xAIolwlleQuvN0aR4JcEOqYGG3U zp/py1cqtWfw04Kf8aGRB+kaGGR1snciOFoe/1i0sorHNXdhp23VGXJ2Vn1J8smG fCS5dkebI0z58AOj61D0MVo1MfM2NfjP6Xs89waHU9kdM89UY/iapFQ+OYBumJ3H OeHuuuHmFOkv0yKMToJ9kU0MUx+28SgvXRgmoLnsx74SLno8shJkO3uRChZqtSZ3 1xAJh29tLWw7zsgXfr/5qeaCmUAoHJ4SIZnCkFhooglcpWsjlhaBb/PhI79VJFQ7 1+lTRoFdtA/I3389xyvveZGn0ELCuhkvkb40NWGMBM3NT112k1ulC9jKMbXzytK0 zJiSfkWChQJwWgPaEi8d4s4tvcyJlSQzzNgfEWSXVVeUFq6Ff2+7JWEqx1mBcNsc /gV4nrBANcT57Wb2MNLGbnW6A5SW5VTUx1rUNOOLU5RM1o5tFtGpX+YTQkkNUZs2 ZfwxFW+VkvRuXPl6W+F2QsQSpmovk1giC0ezWOtwEzhQbLdxZq9LDXC8SJflEp/A w8fKaHlaSJOYRR3XL1Wxo/KFdMBOz2UJY2eT35dfPbHKc5FkJU8= =fB9v -----END PGP SIGNATURE----- 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()
This commit is contained in:
commit
0e39a73182
|
|
@ -4331,15 +4331,18 @@ static int try_release_subpage_extent_buffer(struct folio *folio)
|
|||
unsigned long end = index + (PAGE_SIZE >> fs_info->nodesize_bits) - 1;
|
||||
int ret;
|
||||
|
||||
xa_lock_irq(&fs_info->buffer_tree);
|
||||
rcu_read_lock();
|
||||
xa_for_each_range(&fs_info->buffer_tree, index, eb, start, end) {
|
||||
/*
|
||||
* The same as try_release_extent_buffer(), to ensure the eb
|
||||
* won't disappear out from under us.
|
||||
*/
|
||||
spin_lock(&eb->refs_lock);
|
||||
rcu_read_unlock();
|
||||
|
||||
if (refcount_read(&eb->refs) != 1 || extent_buffer_under_io(eb)) {
|
||||
spin_unlock(&eb->refs_lock);
|
||||
rcu_read_lock();
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -4358,11 +4361,10 @@ static int try_release_subpage_extent_buffer(struct folio *folio)
|
|||
* check the folio private at the end. And
|
||||
* release_extent_buffer() will release the refs_lock.
|
||||
*/
|
||||
xa_unlock_irq(&fs_info->buffer_tree);
|
||||
release_extent_buffer(eb);
|
||||
xa_lock_irq(&fs_info->buffer_tree);
|
||||
rcu_read_lock();
|
||||
}
|
||||
xa_unlock_irq(&fs_info->buffer_tree);
|
||||
rcu_read_unlock();
|
||||
|
||||
/*
|
||||
* 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)
|
|||
ret = 0;
|
||||
spin_unlock(&folio->mapping->i_private_lock);
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
int try_release_extent_buffer(struct folio *folio)
|
||||
|
|
|
|||
|
|
@ -401,10 +401,12 @@ static inline void btrfs_cleanup_ordered_extents(struct btrfs_inode *inode,
|
|||
|
||||
while (index <= end_index) {
|
||||
folio = filemap_get_folio(inode->vfs_inode.i_mapping, index);
|
||||
index++;
|
||||
if (IS_ERR(folio))
|
||||
if (IS_ERR(folio)) {
|
||||
index++;
|
||||
continue;
|
||||
}
|
||||
|
||||
index = folio_end(folio) >> PAGE_SHIFT;
|
||||
/*
|
||||
* Here we just clear all Ordered bits for every page in the
|
||||
* 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
|
|||
* cleaered by the caller.
|
||||
*/
|
||||
if (ret < 0)
|
||||
btrfs_cleanup_ordered_extents(inode, file_pos, end);
|
||||
btrfs_cleanup_ordered_extents(inode, file_pos, len);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1453,7 +1453,6 @@ static int __qgroup_excl_accounting(struct btrfs_fs_info *fs_info, u64 ref_root,
|
|||
struct btrfs_qgroup *src, int sign)
|
||||
{
|
||||
struct btrfs_qgroup *qgroup;
|
||||
struct btrfs_qgroup *cur;
|
||||
LIST_HEAD(qgroup_list);
|
||||
u64 num_bytes = src->excl;
|
||||
int ret = 0;
|
||||
|
|
@ -1463,7 +1462,7 @@ static int __qgroup_excl_accounting(struct btrfs_fs_info *fs_info, u64 ref_root,
|
|||
goto out;
|
||||
|
||||
qgroup_iterator_add(&qgroup_list, qgroup);
|
||||
list_for_each_entry(cur, &qgroup_list, iterator) {
|
||||
list_for_each_entry(qgroup, &qgroup_list, iterator) {
|
||||
struct btrfs_qgroup_list *glist;
|
||||
|
||||
qgroup->rfer += sign * num_bytes;
|
||||
|
|
|
|||
|
|
@ -602,6 +602,25 @@ static struct btrfs_root *create_reloc_root(struct btrfs_trans_handle *trans,
|
|||
if (btrfs_root_id(root) == objectid) {
|
||||
u64 commit_root_gen;
|
||||
|
||||
/*
|
||||
* Relocation will wait for cleaner thread, and any half-dropped
|
||||
* subvolume will be fully cleaned up at mount time.
|
||||
* So here we shouldn't hit a subvolume with non-zero drop_progress.
|
||||
*
|
||||
* If this isn't the case, error out since it can make us attempt to
|
||||
* drop references for extents that were already dropped before.
|
||||
*/
|
||||
if (unlikely(btrfs_disk_key_objectid(&root->root_item.drop_progress))) {
|
||||
struct btrfs_key cpu_key;
|
||||
|
||||
btrfs_disk_key_to_cpu(&cpu_key, &root->root_item.drop_progress);
|
||||
btrfs_err(fs_info,
|
||||
"cannot relocate partially dropped subvolume %llu, drop progress key (%llu %u %llu)",
|
||||
objectid, cpu_key.objectid, cpu_key.type, cpu_key.offset);
|
||||
ret = -EUCLEAN;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* called by btrfs_init_reloc_root */
|
||||
ret = btrfs_copy_root(trans, root, root->commit_root, &eb,
|
||||
BTRFS_TREE_RELOC_OBJECTID);
|
||||
|
|
|
|||
|
|
@ -2605,14 +2605,14 @@ static int replay_one_buffer(struct btrfs_root *log, struct extent_buffer *eb,
|
|||
/*
|
||||
* Correctly adjust the reserved bytes occupied by a log tree extent buffer
|
||||
*/
|
||||
static void unaccount_log_buffer(struct btrfs_fs_info *fs_info, u64 start)
|
||||
static int unaccount_log_buffer(struct btrfs_fs_info *fs_info, u64 start)
|
||||
{
|
||||
struct btrfs_block_group *cache;
|
||||
|
||||
cache = btrfs_lookup_block_group(fs_info, start);
|
||||
if (!cache) {
|
||||
btrfs_err(fs_info, "unable to find block group for %llu", start);
|
||||
return;
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
spin_lock(&cache->space_info->lock);
|
||||
|
|
@ -2623,27 +2623,22 @@ static void unaccount_log_buffer(struct btrfs_fs_info *fs_info, u64 start)
|
|||
spin_unlock(&cache->space_info->lock);
|
||||
|
||||
btrfs_put_block_group(cache);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int clean_log_buffer(struct btrfs_trans_handle *trans,
|
||||
struct extent_buffer *eb)
|
||||
{
|
||||
int ret;
|
||||
|
||||
btrfs_tree_lock(eb);
|
||||
btrfs_clear_buffer_dirty(trans, eb);
|
||||
wait_on_extent_buffer_writeback(eb);
|
||||
btrfs_tree_unlock(eb);
|
||||
|
||||
if (trans) {
|
||||
ret = btrfs_pin_reserved_extent(trans, eb);
|
||||
if (ret)
|
||||
return ret;
|
||||
} else {
|
||||
unaccount_log_buffer(eb->fs_info, eb->start);
|
||||
}
|
||||
if (trans)
|
||||
return btrfs_pin_reserved_extent(trans, eb);
|
||||
|
||||
return 0;
|
||||
return unaccount_log_buffer(eb->fs_info, eb->start);
|
||||
}
|
||||
|
||||
static noinline int walk_down_log_tree(struct btrfs_trans_handle *trans,
|
||||
|
|
|
|||
|
|
@ -2650,7 +2650,7 @@ int btrfs_zone_finish_one_bg(struct btrfs_fs_info *fs_info)
|
|||
|
||||
spin_lock(&block_group->lock);
|
||||
if (block_group->reserved || block_group->alloc_offset == 0 ||
|
||||
(block_group->flags & BTRFS_BLOCK_GROUP_SYSTEM) ||
|
||||
!(block_group->flags & BTRFS_BLOCK_GROUP_DATA) ||
|
||||
test_bit(BLOCK_GROUP_FLAG_ZONED_DATA_RELOC, &block_group->runtime_flags)) {
|
||||
spin_unlock(&block_group->lock);
|
||||
continue;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user