Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

+102 -33
+10 -9
fs/btrfs/backref.c
··· 45 45 int root_count; 46 46 bool cached; 47 47 48 - if (!btrfs_file_extent_compression(eb, fi) && 48 + if (!ctx->ignore_extent_item_pos && 49 + !btrfs_file_extent_compression(eb, fi) && 49 50 !btrfs_file_extent_encryption(eb, fi) && 50 51 !btrfs_file_extent_other_encoding(eb, fi)) { 51 52 u64 data_offset; ··· 553 552 count++; 554 553 else 555 554 goto next; 556 - if (!ctx->ignore_extent_item_pos) { 555 + if (!ctx->skip_inode_ref_list) { 557 556 ret = check_extent_in_eb(ctx, &key, eb, fi, &eie); 558 557 if (ret == BTRFS_ITERATE_EXTENT_INODES_STOP || 559 558 ret < 0) ··· 565 564 eie, (void **)&old, GFP_NOFS); 566 565 if (ret < 0) 567 566 break; 568 - if (!ret && !ctx->ignore_extent_item_pos) { 567 + if (!ret && !ctx->skip_inode_ref_list) { 569 568 while (old->next) 570 569 old = old->next; 571 570 old->next = eie; ··· 1607 1606 goto out; 1608 1607 } 1609 1608 if (ref->count && ref->parent) { 1610 - if (!ctx->ignore_extent_item_pos && !ref->inode_list && 1609 + if (!ctx->skip_inode_ref_list && !ref->inode_list && 1611 1610 ref->level == 0) { 1612 1611 struct btrfs_tree_parent_check check = { 0 }; 1613 1612 struct extent_buffer *eb; ··· 1648 1647 (void **)&eie, GFP_NOFS); 1649 1648 if (ret < 0) 1650 1649 goto out; 1651 - if (!ret && !ctx->ignore_extent_item_pos) { 1650 + if (!ret && !ctx->skip_inode_ref_list) { 1652 1651 /* 1653 1652 * We've recorded that parent, so we must extend 1654 1653 * its inode list here. ··· 1744 1743 static int btrfs_find_all_roots_safe(struct btrfs_backref_walk_ctx *ctx) 1745 1744 { 1746 1745 const u64 orig_bytenr = ctx->bytenr; 1747 - const bool orig_ignore_extent_item_pos = ctx->ignore_extent_item_pos; 1746 + const bool orig_skip_inode_ref_list = ctx->skip_inode_ref_list; 1748 1747 bool roots_ulist_allocated = false; 1749 1748 struct ulist_iterator uiter; 1750 1749 int ret = 0; ··· 1765 1764 roots_ulist_allocated = true; 1766 1765 } 1767 1766 1768 - ctx->ignore_extent_item_pos = true; 1767 + ctx->skip_inode_ref_list = true; 1769 1768 1770 1769 ULIST_ITER_INIT(&uiter); 1771 1770 while (1) { ··· 1790 1789 ulist_free(ctx->refs); 1791 1790 ctx->refs = NULL; 1792 1791 ctx->bytenr = orig_bytenr; 1793 - ctx->ignore_extent_item_pos = orig_ignore_extent_item_pos; 1792 + ctx->skip_inode_ref_list = orig_skip_inode_ref_list; 1794 1793 1795 1794 return ret; 1796 1795 } ··· 1913 1912 goto out_trans; 1914 1913 } 1915 1914 1916 - walk_ctx.ignore_extent_item_pos = true; 1915 + walk_ctx.skip_inode_ref_list = true; 1917 1916 walk_ctx.trans = trans; 1918 1917 walk_ctx.fs_info = fs_info; 1919 1918 walk_ctx.refs = &ctx->refs;
+6
fs/btrfs/backref.h
··· 60 60 * @extent_item_pos is ignored. 61 61 */ 62 62 bool ignore_extent_item_pos; 63 + /* 64 + * If true and bytenr corresponds to a data extent, then the inode list 65 + * (each member describing inode number, file offset and root) is not 66 + * added to each reference added to the @refs ulist. 67 + */ 68 + bool skip_inode_ref_list; 63 69 /* A valid transaction handle or NULL. */ 64 70 struct btrfs_trans_handle *trans; 65 71 /*
+18 -7
fs/btrfs/disk-io.c
··· 3121 3121 { 3122 3122 int ret; 3123 3123 const bool cache_opt = btrfs_test_opt(fs_info, SPACE_CACHE); 3124 - bool clear_free_space_tree = false; 3124 + bool rebuild_free_space_tree = false; 3125 3125 3126 3126 if (btrfs_test_opt(fs_info, CLEAR_CACHE) && 3127 3127 btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE)) { 3128 - clear_free_space_tree = true; 3128 + rebuild_free_space_tree = true; 3129 3129 } else if (btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE) && 3130 3130 !btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE_VALID)) { 3131 3131 btrfs_warn(fs_info, "free space tree is invalid"); 3132 - clear_free_space_tree = true; 3132 + rebuild_free_space_tree = true; 3133 3133 } 3134 3134 3135 - if (clear_free_space_tree) { 3136 - btrfs_info(fs_info, "clearing free space tree"); 3137 - ret = btrfs_clear_free_space_tree(fs_info); 3135 + if (rebuild_free_space_tree) { 3136 + btrfs_info(fs_info, "rebuilding free space tree"); 3137 + ret = btrfs_rebuild_free_space_tree(fs_info); 3138 3138 if (ret) { 3139 3139 btrfs_warn(fs_info, 3140 - "failed to clear free space tree: %d", ret); 3140 + "failed to rebuild free space tree: %d", ret); 3141 + goto out; 3142 + } 3143 + } 3144 + 3145 + if (btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE) && 3146 + !btrfs_test_opt(fs_info, FREE_SPACE_TREE)) { 3147 + btrfs_info(fs_info, "disabling free space tree"); 3148 + ret = btrfs_delete_free_space_tree(fs_info); 3149 + if (ret) { 3150 + btrfs_warn(fs_info, 3151 + "failed to disable free space tree: %d", ret); 3141 3152 goto out; 3142 3153 } 3143 3154 }
+4 -3
fs/btrfs/free-space-cache.c
··· 870 870 } 871 871 spin_lock(&ctl->tree_lock); 872 872 ret = link_free_space(ctl, e); 873 - ctl->total_bitmaps++; 874 - recalculate_thresholds(ctl); 875 - spin_unlock(&ctl->tree_lock); 876 873 if (ret) { 874 + spin_unlock(&ctl->tree_lock); 877 875 btrfs_err(fs_info, 878 876 "Duplicate entries in free space cache, dumping"); 879 877 kmem_cache_free(btrfs_free_space_cachep, e); 880 878 goto free_cache; 881 879 } 880 + ctl->total_bitmaps++; 881 + recalculate_thresholds(ctl); 882 + spin_unlock(&ctl->tree_lock); 882 883 list_add_tail(&e->list, &bitmaps); 883 884 } 884 885
+49 -1
fs/btrfs/free-space-tree.c
··· 1252 1252 return ret; 1253 1253 } 1254 1254 1255 - int btrfs_clear_free_space_tree(struct btrfs_fs_info *fs_info) 1255 + int btrfs_delete_free_space_tree(struct btrfs_fs_info *fs_info) 1256 1256 { 1257 1257 struct btrfs_trans_handle *trans; 1258 1258 struct btrfs_root *tree_root = fs_info->tree_root; ··· 1292 1292 1293 1293 return btrfs_commit_transaction(trans); 1294 1294 1295 + abort: 1296 + btrfs_abort_transaction(trans, ret); 1297 + btrfs_end_transaction(trans); 1298 + return ret; 1299 + } 1300 + 1301 + int btrfs_rebuild_free_space_tree(struct btrfs_fs_info *fs_info) 1302 + { 1303 + struct btrfs_trans_handle *trans; 1304 + struct btrfs_key key = { 1305 + .objectid = BTRFS_FREE_SPACE_TREE_OBJECTID, 1306 + .type = BTRFS_ROOT_ITEM_KEY, 1307 + .offset = 0, 1308 + }; 1309 + struct btrfs_root *free_space_root = btrfs_global_root(fs_info, &key); 1310 + struct rb_node *node; 1311 + int ret; 1312 + 1313 + trans = btrfs_start_transaction(free_space_root, 1); 1314 + if (IS_ERR(trans)) 1315 + return PTR_ERR(trans); 1316 + 1317 + set_bit(BTRFS_FS_CREATING_FREE_SPACE_TREE, &fs_info->flags); 1318 + set_bit(BTRFS_FS_FREE_SPACE_TREE_UNTRUSTED, &fs_info->flags); 1319 + 1320 + ret = clear_free_space_tree(trans, free_space_root); 1321 + if (ret) 1322 + goto abort; 1323 + 1324 + node = rb_first_cached(&fs_info->block_group_cache_tree); 1325 + while (node) { 1326 + struct btrfs_block_group *block_group; 1327 + 1328 + block_group = rb_entry(node, struct btrfs_block_group, 1329 + cache_node); 1330 + ret = populate_free_space_tree(trans, block_group); 1331 + if (ret) 1332 + goto abort; 1333 + node = rb_next(node); 1334 + } 1335 + 1336 + btrfs_set_fs_compat_ro(fs_info, FREE_SPACE_TREE); 1337 + btrfs_set_fs_compat_ro(fs_info, FREE_SPACE_TREE_VALID); 1338 + clear_bit(BTRFS_FS_CREATING_FREE_SPACE_TREE, &fs_info->flags); 1339 + 1340 + ret = btrfs_commit_transaction(trans); 1341 + clear_bit(BTRFS_FS_FREE_SPACE_TREE_UNTRUSTED, &fs_info->flags); 1342 + return ret; 1295 1343 abort: 1296 1344 btrfs_abort_transaction(trans, ret); 1297 1345 btrfs_end_transaction(trans);
+2 -1
fs/btrfs/free-space-tree.h
··· 18 18 19 19 void set_free_space_tree_thresholds(struct btrfs_block_group *block_group); 20 20 int btrfs_create_free_space_tree(struct btrfs_fs_info *fs_info); 21 - int btrfs_clear_free_space_tree(struct btrfs_fs_info *fs_info); 21 + int btrfs_delete_free_space_tree(struct btrfs_fs_info *fs_info); 22 + int btrfs_rebuild_free_space_tree(struct btrfs_fs_info *fs_info); 22 23 int load_free_space_tree(struct btrfs_caching_control *caching_ctl); 23 24 int add_block_group_free_space(struct btrfs_trans_handle *trans, 24 25 struct btrfs_block_group *block_group);
+3
fs/btrfs/inode.c
··· 3108 3108 btrfs_rewrite_logical_zoned(ordered_extent); 3109 3109 btrfs_zone_finish_endio(fs_info, ordered_extent->disk_bytenr, 3110 3110 ordered_extent->disk_num_bytes); 3111 + } else if (btrfs_is_data_reloc_root(inode->root)) { 3112 + btrfs_zone_finish_endio(fs_info, ordered_extent->disk_bytenr, 3113 + ordered_extent->disk_num_bytes); 3111 3114 } 3112 3115 3113 3116 if (test_bit(BTRFS_ORDERED_TRUNCATED, &ordered_extent->flags)) {
+3 -3
fs/btrfs/print-tree.c
··· 151 151 pr_cont("shared data backref parent %llu count %u\n", 152 152 offset, btrfs_shared_data_ref_count(eb, sref)); 153 153 /* 154 - * offset is supposed to be a tree block which 155 - * must be aligned to nodesize. 154 + * Offset is supposed to be a tree block which must be 155 + * aligned to sectorsize. 156 156 */ 157 - if (!IS_ALIGNED(offset, eb->fs_info->nodesize)) 157 + if (!IS_ALIGNED(offset, eb->fs_info->sectorsize)) 158 158 pr_info( 159 159 "\t\t\t(parent %llu not aligned to sectorsize %u)\n", 160 160 offset, eb->fs_info->sectorsize);
+1 -1
fs/btrfs/relocation.c
··· 3422 3422 btrfs_release_path(path); 3423 3423 3424 3424 ctx.bytenr = extent_key->objectid; 3425 - ctx.ignore_extent_item_pos = true; 3425 + ctx.skip_inode_ref_list = true; 3426 3426 ctx.fs_info = rc->extent_root->fs_info; 3427 3427 3428 3428 ret = btrfs_find_all_leafs(&ctx);
+1 -2
fs/btrfs/super.c
··· 828 828 ret = -EINVAL; 829 829 } 830 830 if (btrfs_fs_compat_ro(info, BLOCK_GROUP_TREE) && 831 - (btrfs_test_opt(info, CLEAR_CACHE) || 832 - !btrfs_test_opt(info, FREE_SPACE_TREE))) { 831 + !btrfs_test_opt(info, FREE_SPACE_TREE)) { 833 832 btrfs_err(info, "cannot disable free space tree with block-group-tree feature"); 834 833 ret = -EINVAL; 835 834 }
+5 -6
fs/btrfs/zoned.c
··· 122 122 int i; 123 123 124 124 for (i = 0; i < BTRFS_NR_SB_LOG_ZONES; i++) { 125 - u64 bytenr; 126 - 127 - bytenr = ((zones[i].start + zones[i].len) 128 - << SECTOR_SHIFT) - BTRFS_SUPER_INFO_SIZE; 125 + u64 zone_end = (zones[i].start + zones[i].capacity) << SECTOR_SHIFT; 126 + u64 bytenr = ALIGN_DOWN(zone_end, BTRFS_SUPER_INFO_SIZE) - 127 + BTRFS_SUPER_INFO_SIZE; 129 128 130 129 page[i] = read_cache_page_gfp(mapping, 131 130 bytenr >> PAGE_SHIFT, GFP_NOFS); ··· 1609 1610 !list_empty(&eb->release_list)) 1610 1611 return; 1611 1612 1613 + memzero_extent_buffer(eb, 0, eb->len); 1614 + set_bit(EXTENT_BUFFER_NO_CHECK, &eb->bflags); 1612 1615 set_extent_buffer_dirty(eb); 1613 1616 set_extent_bits_nowait(&trans->dirty_pages, eb->start, 1614 1617 eb->start + eb->len - 1, EXTENT_DIRTY); 1615 - memzero_extent_buffer(eb, 0, eb->len); 1616 - set_bit(EXTENT_BUFFER_NO_CHECK, &eb->bflags); 1617 1618 1618 1619 spin_lock(&trans->releasing_ebs_lock); 1619 1620 list_add_tail(&eb->release_list, &trans->releasing_ebs);