Skip to content

Commit 3173a18

Browse files
author
Josef Bacik
committed
Btrfs: add a incompatible format change for smaller metadata extent refs
We currently store the first key of the tree block inside the reference for the tree block in the extent tree. This takes up quite a bit of space. Make a new key type for metadata which holds the level as the offset and completely removes storing the btrfs_tree_block_info inside the extent ref. This reduces the size from 51 bytes to 33 bytes per extent reference for each tree block. In practice this results in a 30-35% decrease in the size of our extent tree, which means we COW less and can keep more of the extent tree in memory which makes our heavy metadata operations go much faster. This is not an automatic format change, you must enable it at mkfs time or with btrfstune. This patch deals with having metadata stored as either the old format or the new format so it is easy to convert. Thanks, Signed-off-by: Josef Bacik <[email protected]>
1 parent be283b2 commit 3173a18

File tree

7 files changed

+290
-67
lines changed

7 files changed

+290
-67
lines changed

fs/btrfs/ctree.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -867,7 +867,8 @@ static noinline int update_ref_for_cow(struct btrfs_trans_handle *trans,
867867

868868
if (btrfs_block_can_be_shared(root, buf)) {
869869
ret = btrfs_lookup_extent_info(trans, root, buf->start,
870-
buf->len, &refs, &flags);
870+
btrfs_header_level(buf), 1,
871+
&refs, &flags);
871872
if (ret)
872873
return ret;
873874
if (refs == 0) {

fs/btrfs/ctree.h

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -509,6 +509,7 @@ struct btrfs_super_block {
509509

510510
#define BTRFS_FEATURE_INCOMPAT_EXTENDED_IREF (1ULL << 6)
511511
#define BTRFS_FEATURE_INCOMPAT_RAID56 (1ULL << 7)
512+
#define BTRFS_FEATURE_INCOMPAT_SKINNY_METADATA (1ULL << 8)
512513

513514
#define BTRFS_FEATURE_COMPAT_SUPP 0ULL
514515
#define BTRFS_FEATURE_COMPAT_RO_SUPP 0ULL
@@ -519,7 +520,8 @@ struct btrfs_super_block {
519520
BTRFS_FEATURE_INCOMPAT_BIG_METADATA | \
520521
BTRFS_FEATURE_INCOMPAT_COMPRESS_LZO | \
521522
BTRFS_FEATURE_INCOMPAT_RAID56 | \
522-
BTRFS_FEATURE_INCOMPAT_EXTENDED_IREF)
523+
BTRFS_FEATURE_INCOMPAT_EXTENDED_IREF | \
524+
BTRFS_FEATURE_INCOMPAT_SKINNY_METADATA)
523525

524526
/*
525527
* A leaf is full of items. offset and size tell us where to find
@@ -1809,6 +1811,12 @@ struct btrfs_ioctl_defrag_range_args {
18091811
*/
18101812
#define BTRFS_EXTENT_ITEM_KEY 168
18111813

1814+
/*
1815+
* The same as the BTRFS_EXTENT_ITEM_KEY, except it's metadata we already know
1816+
* the length, so we save the level in key->offset instead of the length.
1817+
*/
1818+
#define BTRFS_METADATA_ITEM_KEY 169
1819+
18121820
#define BTRFS_TREE_BLOCK_REF_KEY 176
18131821

18141822
#define BTRFS_EXTENT_DATA_REF_KEY 178
@@ -3006,7 +3014,7 @@ int btrfs_run_delayed_refs(struct btrfs_trans_handle *trans,
30063014
int btrfs_lookup_extent(struct btrfs_root *root, u64 start, u64 len);
30073015
int btrfs_lookup_extent_info(struct btrfs_trans_handle *trans,
30083016
struct btrfs_root *root, u64 bytenr,
3009-
u64 num_bytes, u64 *refs, u64 *flags);
3017+
u64 offset, int metadata, u64 *refs, u64 *flags);
30103018
int btrfs_pin_extent(struct btrfs_root *root,
30113019
u64 bytenr, u64 num, int reserved);
30123020
int btrfs_pin_extent_for_log_replay(struct btrfs_root *root,
@@ -3669,6 +3677,16 @@ static inline void __btrfs_set_fs_incompat(struct btrfs_fs_info *fs_info,
36693677
}
36703678
}
36713679

3680+
#define btrfs_fs_incompat(fs_info, opt) \
3681+
__btrfs_fs_incompat((fs_info), BTRFS_FEATURE_INCOMPAT_##opt)
3682+
3683+
static inline int __btrfs_fs_incompat(struct btrfs_fs_info *fs_info, u64 flag)
3684+
{
3685+
struct btrfs_super_block *disk_super;
3686+
disk_super = fs_info->super_copy;
3687+
return !!(btrfs_super_incompat_flags(disk_super) & flag);
3688+
}
3689+
36723690
/*
36733691
* Call btrfs_abort_transaction as early as possible when an error condition is
36743692
* detected, that way the exact line number is reported.

fs/btrfs/disk-io.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2290,6 +2290,9 @@ int open_ctree(struct super_block *sb,
22902290
if (tree_root->fs_info->compress_type == BTRFS_COMPRESS_LZO)
22912291
features |= BTRFS_FEATURE_INCOMPAT_COMPRESS_LZO;
22922292

2293+
if (features & BTRFS_FEATURE_INCOMPAT_SKINNY_METADATA)
2294+
printk(KERN_ERR "btrfs: has skinny extents\n");
2295+
22932296
/*
22942297
* flag our filesystem as having big metadata blocks if
22952298
* they are bigger than the page size

0 commit comments

Comments
 (0)