for-6.4-rc1-tag
-----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEE8rQSAMVO+zA4DBdWxWXV+ddtWDsFAmRebDIACgkQxWXV+ddt WDu3vA//RNyRGjEz0HgfhTc1119DXJLwK6j544waYLrzRcMtBK4xKByiaFkAA4tL PQidGX+nAQPm+pZl0jcK30cBMObik5GXJwoSOZGl7/ectx4O7aFfXqiSfwPTyqZU 3fTavoqoJxbxJCVbifcXOPNhsUxMlEGYJmA3CVRsllLviXY+3HMpX2ZpWZ7vch+N MLENNBfUo1HVdWaxOYfQif/qT5iR9G7D8dBjX9DUK0kVwrbwBB0rolJy4fPrY6z5 gBLED9Ks3FBgyU3mYq4qrfPmbfF8mPiaU0+1j+B46vw3PdPtIwjIForR+91GsZ1v iHojbykf6VWTQV+gO78mgv4O4vRtn3C+UJaGxLL86OMOaiQQHFYdSETn9arPmoho p1wCBidI82tvfIOGYXgrTGorLN27hhyPJinHe/2Bqo+1wUL8/J8mwCWunIox7a8z rxO5QhDIDFX7gamsvYjkW3tBkYuGiGvBjx+Ic2cBHTkVp9wSPL9PCvqNNru2qexA t0BpAL9DxvN+T1xO1thC3qsm2Ogx0QEmgdDfRglbEVASnRZKZZsJEMO90FzFbkFg vLbs0KnT7yS7mTwq4NklDrgHZ0eiiJLZVCb8bR8xkzVW+ADrUmZuDM8WOcCgJAUp fUoMmFsJZi5zsdAOygDWr1bBHorLV5szrY0bSB5L2eHwJjYZ6KE= =uWUN -----END PGP SIGNATURE----- Merge tag 'for-6.4-rc1-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux Pull more btrfs fixes from David Sterba: - fix incorrect number of bitmap entries for space cache if loading is interrupted by some error - fix backref walking, this breaks a mode of LOGICAL_INO_V2 ioctl that is used in deduplication tools - zoned mode fixes: - properly finish zone reserved for relocation - correctly calculate super block zone end on ZNS - properly initialize new extent buffer for redirty - make mount option clear_cache work with block-group-tree, to rebuild free-space-tree instead of temporarily disabling it that would lead to a forced read-only mount - fix alignment check for offset when printing extent item * tag 'for-6.4-rc1-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux: btrfs: make clear_cache mount option to rebuild FST without disabling it btrfs: zero the buffer before marking it dirty in btrfs_redirty_list_add btrfs: zoned: fix full zone super block reading on ZNS btrfs: zoned: zone finish data relocation BG with last IO btrfs: fix backref walking not returning all inode refs btrfs: fix space cache inconsistency after error loading it from disk btrfs: print-tree: parent bytenr must be aligned to sector size
This commit is contained in:
commit
76c7f8873a
|
@ -45,7 +45,8 @@ static int check_extent_in_eb(struct btrfs_backref_walk_ctx *ctx,
|
|||
int root_count;
|
||||
bool cached;
|
||||
|
||||
if (!btrfs_file_extent_compression(eb, fi) &&
|
||||
if (!ctx->ignore_extent_item_pos &&
|
||||
!btrfs_file_extent_compression(eb, fi) &&
|
||||
!btrfs_file_extent_encryption(eb, fi) &&
|
||||
!btrfs_file_extent_other_encoding(eb, fi)) {
|
||||
u64 data_offset;
|
||||
|
@ -552,7 +553,7 @@ static int add_all_parents(struct btrfs_backref_walk_ctx *ctx,
|
|||
count++;
|
||||
else
|
||||
goto next;
|
||||
if (!ctx->ignore_extent_item_pos) {
|
||||
if (!ctx->skip_inode_ref_list) {
|
||||
ret = check_extent_in_eb(ctx, &key, eb, fi, &eie);
|
||||
if (ret == BTRFS_ITERATE_EXTENT_INODES_STOP ||
|
||||
ret < 0)
|
||||
|
@ -564,7 +565,7 @@ static int add_all_parents(struct btrfs_backref_walk_ctx *ctx,
|
|||
eie, (void **)&old, GFP_NOFS);
|
||||
if (ret < 0)
|
||||
break;
|
||||
if (!ret && !ctx->ignore_extent_item_pos) {
|
||||
if (!ret && !ctx->skip_inode_ref_list) {
|
||||
while (old->next)
|
||||
old = old->next;
|
||||
old->next = eie;
|
||||
|
@ -1606,7 +1607,7 @@ again:
|
|||
goto out;
|
||||
}
|
||||
if (ref->count && ref->parent) {
|
||||
if (!ctx->ignore_extent_item_pos && !ref->inode_list &&
|
||||
if (!ctx->skip_inode_ref_list && !ref->inode_list &&
|
||||
ref->level == 0) {
|
||||
struct btrfs_tree_parent_check check = { 0 };
|
||||
struct extent_buffer *eb;
|
||||
|
@ -1647,7 +1648,7 @@ again:
|
|||
(void **)&eie, GFP_NOFS);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
if (!ret && !ctx->ignore_extent_item_pos) {
|
||||
if (!ret && !ctx->skip_inode_ref_list) {
|
||||
/*
|
||||
* We've recorded that parent, so we must extend
|
||||
* its inode list here.
|
||||
|
@ -1743,7 +1744,7 @@ int btrfs_find_all_leafs(struct btrfs_backref_walk_ctx *ctx)
|
|||
static int btrfs_find_all_roots_safe(struct btrfs_backref_walk_ctx *ctx)
|
||||
{
|
||||
const u64 orig_bytenr = ctx->bytenr;
|
||||
const bool orig_ignore_extent_item_pos = ctx->ignore_extent_item_pos;
|
||||
const bool orig_skip_inode_ref_list = ctx->skip_inode_ref_list;
|
||||
bool roots_ulist_allocated = false;
|
||||
struct ulist_iterator uiter;
|
||||
int ret = 0;
|
||||
|
@ -1764,7 +1765,7 @@ static int btrfs_find_all_roots_safe(struct btrfs_backref_walk_ctx *ctx)
|
|||
roots_ulist_allocated = true;
|
||||
}
|
||||
|
||||
ctx->ignore_extent_item_pos = true;
|
||||
ctx->skip_inode_ref_list = true;
|
||||
|
||||
ULIST_ITER_INIT(&uiter);
|
||||
while (1) {
|
||||
|
@ -1789,7 +1790,7 @@ static int btrfs_find_all_roots_safe(struct btrfs_backref_walk_ctx *ctx)
|
|||
ulist_free(ctx->refs);
|
||||
ctx->refs = NULL;
|
||||
ctx->bytenr = orig_bytenr;
|
||||
ctx->ignore_extent_item_pos = orig_ignore_extent_item_pos;
|
||||
ctx->skip_inode_ref_list = orig_skip_inode_ref_list;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -1912,7 +1913,7 @@ int btrfs_is_data_extent_shared(struct btrfs_inode *inode, u64 bytenr,
|
|||
goto out_trans;
|
||||
}
|
||||
|
||||
walk_ctx.ignore_extent_item_pos = true;
|
||||
walk_ctx.skip_inode_ref_list = true;
|
||||
walk_ctx.trans = trans;
|
||||
walk_ctx.fs_info = fs_info;
|
||||
walk_ctx.refs = &ctx->refs;
|
||||
|
|
|
@ -60,6 +60,12 @@ struct btrfs_backref_walk_ctx {
|
|||
* @extent_item_pos is ignored.
|
||||
*/
|
||||
bool ignore_extent_item_pos;
|
||||
/*
|
||||
* If true and bytenr corresponds to a data extent, then the inode list
|
||||
* (each member describing inode number, file offset and root) is not
|
||||
* added to each reference added to the @refs ulist.
|
||||
*/
|
||||
bool skip_inode_ref_list;
|
||||
/* A valid transaction handle or NULL. */
|
||||
struct btrfs_trans_handle *trans;
|
||||
/*
|
||||
|
|
|
@ -3121,23 +3121,34 @@ int btrfs_start_pre_rw_mount(struct btrfs_fs_info *fs_info)
|
|||
{
|
||||
int ret;
|
||||
const bool cache_opt = btrfs_test_opt(fs_info, SPACE_CACHE);
|
||||
bool clear_free_space_tree = false;
|
||||
bool rebuild_free_space_tree = false;
|
||||
|
||||
if (btrfs_test_opt(fs_info, CLEAR_CACHE) &&
|
||||
btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE)) {
|
||||
clear_free_space_tree = true;
|
||||
rebuild_free_space_tree = true;
|
||||
} else if (btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE) &&
|
||||
!btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE_VALID)) {
|
||||
btrfs_warn(fs_info, "free space tree is invalid");
|
||||
clear_free_space_tree = true;
|
||||
rebuild_free_space_tree = true;
|
||||
}
|
||||
|
||||
if (clear_free_space_tree) {
|
||||
btrfs_info(fs_info, "clearing free space tree");
|
||||
ret = btrfs_clear_free_space_tree(fs_info);
|
||||
if (rebuild_free_space_tree) {
|
||||
btrfs_info(fs_info, "rebuilding free space tree");
|
||||
ret = btrfs_rebuild_free_space_tree(fs_info);
|
||||
if (ret) {
|
||||
btrfs_warn(fs_info,
|
||||
"failed to clear free space tree: %d", ret);
|
||||
"failed to rebuild free space tree: %d", ret);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE) &&
|
||||
!btrfs_test_opt(fs_info, FREE_SPACE_TREE)) {
|
||||
btrfs_info(fs_info, "disabling free space tree");
|
||||
ret = btrfs_delete_free_space_tree(fs_info);
|
||||
if (ret) {
|
||||
btrfs_warn(fs_info,
|
||||
"failed to disable free space tree: %d", ret);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -870,15 +870,16 @@ static int __load_free_space_cache(struct btrfs_root *root, struct inode *inode,
|
|||
}
|
||||
spin_lock(&ctl->tree_lock);
|
||||
ret = link_free_space(ctl, e);
|
||||
ctl->total_bitmaps++;
|
||||
recalculate_thresholds(ctl);
|
||||
spin_unlock(&ctl->tree_lock);
|
||||
if (ret) {
|
||||
spin_unlock(&ctl->tree_lock);
|
||||
btrfs_err(fs_info,
|
||||
"Duplicate entries in free space cache, dumping");
|
||||
kmem_cache_free(btrfs_free_space_cachep, e);
|
||||
goto free_cache;
|
||||
}
|
||||
ctl->total_bitmaps++;
|
||||
recalculate_thresholds(ctl);
|
||||
spin_unlock(&ctl->tree_lock);
|
||||
list_add_tail(&e->list, &bitmaps);
|
||||
}
|
||||
|
||||
|
|
|
@ -1252,7 +1252,7 @@ out:
|
|||
return ret;
|
||||
}
|
||||
|
||||
int btrfs_clear_free_space_tree(struct btrfs_fs_info *fs_info)
|
||||
int btrfs_delete_free_space_tree(struct btrfs_fs_info *fs_info)
|
||||
{
|
||||
struct btrfs_trans_handle *trans;
|
||||
struct btrfs_root *tree_root = fs_info->tree_root;
|
||||
|
@ -1298,6 +1298,54 @@ abort:
|
|||
return ret;
|
||||
}
|
||||
|
||||
int btrfs_rebuild_free_space_tree(struct btrfs_fs_info *fs_info)
|
||||
{
|
||||
struct btrfs_trans_handle *trans;
|
||||
struct btrfs_key key = {
|
||||
.objectid = BTRFS_FREE_SPACE_TREE_OBJECTID,
|
||||
.type = BTRFS_ROOT_ITEM_KEY,
|
||||
.offset = 0,
|
||||
};
|
||||
struct btrfs_root *free_space_root = btrfs_global_root(fs_info, &key);
|
||||
struct rb_node *node;
|
||||
int ret;
|
||||
|
||||
trans = btrfs_start_transaction(free_space_root, 1);
|
||||
if (IS_ERR(trans))
|
||||
return PTR_ERR(trans);
|
||||
|
||||
set_bit(BTRFS_FS_CREATING_FREE_SPACE_TREE, &fs_info->flags);
|
||||
set_bit(BTRFS_FS_FREE_SPACE_TREE_UNTRUSTED, &fs_info->flags);
|
||||
|
||||
ret = clear_free_space_tree(trans, free_space_root);
|
||||
if (ret)
|
||||
goto abort;
|
||||
|
||||
node = rb_first_cached(&fs_info->block_group_cache_tree);
|
||||
while (node) {
|
||||
struct btrfs_block_group *block_group;
|
||||
|
||||
block_group = rb_entry(node, struct btrfs_block_group,
|
||||
cache_node);
|
||||
ret = populate_free_space_tree(trans, block_group);
|
||||
if (ret)
|
||||
goto abort;
|
||||
node = rb_next(node);
|
||||
}
|
||||
|
||||
btrfs_set_fs_compat_ro(fs_info, FREE_SPACE_TREE);
|
||||
btrfs_set_fs_compat_ro(fs_info, FREE_SPACE_TREE_VALID);
|
||||
clear_bit(BTRFS_FS_CREATING_FREE_SPACE_TREE, &fs_info->flags);
|
||||
|
||||
ret = btrfs_commit_transaction(trans);
|
||||
clear_bit(BTRFS_FS_FREE_SPACE_TREE_UNTRUSTED, &fs_info->flags);
|
||||
return ret;
|
||||
abort:
|
||||
btrfs_abort_transaction(trans, ret);
|
||||
btrfs_end_transaction(trans);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int __add_block_group_free_space(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_block_group *block_group,
|
||||
struct btrfs_path *path)
|
||||
|
|
|
@ -18,7 +18,8 @@ struct btrfs_caching_control;
|
|||
|
||||
void set_free_space_tree_thresholds(struct btrfs_block_group *block_group);
|
||||
int btrfs_create_free_space_tree(struct btrfs_fs_info *fs_info);
|
||||
int btrfs_clear_free_space_tree(struct btrfs_fs_info *fs_info);
|
||||
int btrfs_delete_free_space_tree(struct btrfs_fs_info *fs_info);
|
||||
int btrfs_rebuild_free_space_tree(struct btrfs_fs_info *fs_info);
|
||||
int load_free_space_tree(struct btrfs_caching_control *caching_ctl);
|
||||
int add_block_group_free_space(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_block_group *block_group);
|
||||
|
|
|
@ -3108,6 +3108,9 @@ int btrfs_finish_ordered_io(struct btrfs_ordered_extent *ordered_extent)
|
|||
btrfs_rewrite_logical_zoned(ordered_extent);
|
||||
btrfs_zone_finish_endio(fs_info, ordered_extent->disk_bytenr,
|
||||
ordered_extent->disk_num_bytes);
|
||||
} else if (btrfs_is_data_reloc_root(inode->root)) {
|
||||
btrfs_zone_finish_endio(fs_info, ordered_extent->disk_bytenr,
|
||||
ordered_extent->disk_num_bytes);
|
||||
}
|
||||
|
||||
if (test_bit(BTRFS_ORDERED_TRUNCATED, &ordered_extent->flags)) {
|
||||
|
|
|
@ -151,10 +151,10 @@ static void print_extent_item(struct extent_buffer *eb, int slot, int type)
|
|||
pr_cont("shared data backref parent %llu count %u\n",
|
||||
offset, btrfs_shared_data_ref_count(eb, sref));
|
||||
/*
|
||||
* offset is supposed to be a tree block which
|
||||
* must be aligned to nodesize.
|
||||
* Offset is supposed to be a tree block which must be
|
||||
* aligned to sectorsize.
|
||||
*/
|
||||
if (!IS_ALIGNED(offset, eb->fs_info->nodesize))
|
||||
if (!IS_ALIGNED(offset, eb->fs_info->sectorsize))
|
||||
pr_info(
|
||||
"\t\t\t(parent %llu not aligned to sectorsize %u)\n",
|
||||
offset, eb->fs_info->sectorsize);
|
||||
|
|
|
@ -3422,7 +3422,7 @@ int add_data_references(struct reloc_control *rc,
|
|||
btrfs_release_path(path);
|
||||
|
||||
ctx.bytenr = extent_key->objectid;
|
||||
ctx.ignore_extent_item_pos = true;
|
||||
ctx.skip_inode_ref_list = true;
|
||||
ctx.fs_info = rc->extent_root->fs_info;
|
||||
|
||||
ret = btrfs_find_all_leafs(&ctx);
|
||||
|
|
|
@ -828,8 +828,7 @@ out:
|
|||
ret = -EINVAL;
|
||||
}
|
||||
if (btrfs_fs_compat_ro(info, BLOCK_GROUP_TREE) &&
|
||||
(btrfs_test_opt(info, CLEAR_CACHE) ||
|
||||
!btrfs_test_opt(info, FREE_SPACE_TREE))) {
|
||||
!btrfs_test_opt(info, FREE_SPACE_TREE)) {
|
||||
btrfs_err(info, "cannot disable free space tree with block-group-tree feature");
|
||||
ret = -EINVAL;
|
||||
}
|
||||
|
|
|
@ -122,10 +122,9 @@ static int sb_write_pointer(struct block_device *bdev, struct blk_zone *zones,
|
|||
int i;
|
||||
|
||||
for (i = 0; i < BTRFS_NR_SB_LOG_ZONES; i++) {
|
||||
u64 bytenr;
|
||||
|
||||
bytenr = ((zones[i].start + zones[i].len)
|
||||
<< SECTOR_SHIFT) - BTRFS_SUPER_INFO_SIZE;
|
||||
u64 zone_end = (zones[i].start + zones[i].capacity) << SECTOR_SHIFT;
|
||||
u64 bytenr = ALIGN_DOWN(zone_end, BTRFS_SUPER_INFO_SIZE) -
|
||||
BTRFS_SUPER_INFO_SIZE;
|
||||
|
||||
page[i] = read_cache_page_gfp(mapping,
|
||||
bytenr >> PAGE_SHIFT, GFP_NOFS);
|
||||
|
@ -1610,11 +1609,11 @@ void btrfs_redirty_list_add(struct btrfs_transaction *trans,
|
|||
!list_empty(&eb->release_list))
|
||||
return;
|
||||
|
||||
memzero_extent_buffer(eb, 0, eb->len);
|
||||
set_bit(EXTENT_BUFFER_NO_CHECK, &eb->bflags);
|
||||
set_extent_buffer_dirty(eb);
|
||||
set_extent_bits_nowait(&trans->dirty_pages, eb->start,
|
||||
eb->start + eb->len - 1, EXTENT_DIRTY);
|
||||
memzero_extent_buffer(eb, 0, eb->len);
|
||||
set_bit(EXTENT_BUFFER_NO_CHECK, &eb->bflags);
|
||||
|
||||
spin_lock(&trans->releasing_ebs_lock);
|
||||
list_add_tail(&eb->release_list, &trans->releasing_ebs);
|
||||
|
|
Loading…
Reference in New Issue