Skip to content

Commit 6d8694f

Browse files
Daniel Vacekkdave
authored andcommitted
btrfs: index buffer_tree using node size
So far we are deriving the buffer tree index using the sector size. But each extent buffer covers multiple sectors. This makes the buffer tree rather sparse. For example the typical and quite common configuration uses sector size of 4KiB and node size of 16KiB. In this case it means the buffer tree is using up to the maximum of 25% of it's slots. Or in other words at least 75% of the tree slots are wasted as never used. We can score significant memory savings on the required tree nodes by indexing the tree using the node size instead. As a result far less slots are wasted and the tree can now use up to all 100% of it's slots this way. Signed-off-by: Daniel Vacek <neelx@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
1 parent 9ff8035 commit 6d8694f

File tree

3 files changed

+18
-16
lines changed

3 files changed

+18
-16
lines changed

fs/btrfs/disk-io.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3396,6 +3396,7 @@ int __cold open_ctree(struct super_block *sb, struct btrfs_fs_devices *fs_device
33963396
fs_info->delalloc_batch = sectorsize * 512 * (1 + ilog2(nr_cpu_ids));
33973397

33983398
fs_info->nodesize = nodesize;
3399+
fs_info->node_bits = ilog2(nodesize);
33993400
fs_info->sectorsize = sectorsize;
34003401
fs_info->sectorsize_bits = ilog2(sectorsize);
34013402
fs_info->csums_per_leaf = BTRFS_MAX_ITEM_SIZE(fs_info) / fs_info->csum_size;

fs/btrfs/extent_io.c

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1773,7 +1773,7 @@ static noinline_for_stack bool lock_extent_buffer_for_io(struct extent_buffer *e
17731773
*/
17741774
spin_lock(&eb->refs_lock);
17751775
if (test_and_clear_bit(EXTENT_BUFFER_DIRTY, &eb->bflags)) {
1776-
XA_STATE(xas, &fs_info->buffer_tree, eb->start >> fs_info->sectorsize_bits);
1776+
XA_STATE(xas, &fs_info->buffer_tree, eb->start >> fs_info->node_bits);
17771777
unsigned long flags;
17781778

17791779
set_bit(EXTENT_BUFFER_WRITEBACK, &eb->bflags);
@@ -1873,7 +1873,7 @@ static void set_btree_ioerr(struct extent_buffer *eb)
18731873
static void buffer_tree_set_mark(const struct extent_buffer *eb, xa_mark_t mark)
18741874
{
18751875
struct btrfs_fs_info *fs_info = eb->fs_info;
1876-
XA_STATE(xas, &fs_info->buffer_tree, eb->start >> fs_info->sectorsize_bits);
1876+
XA_STATE(xas, &fs_info->buffer_tree, eb->start >> fs_info->node_bits);
18771877
unsigned long flags;
18781878

18791879
xas_lock_irqsave(&xas, flags);
@@ -1885,7 +1885,7 @@ static void buffer_tree_set_mark(const struct extent_buffer *eb, xa_mark_t mark)
18851885
static void buffer_tree_clear_mark(const struct extent_buffer *eb, xa_mark_t mark)
18861886
{
18871887
struct btrfs_fs_info *fs_info = eb->fs_info;
1888-
XA_STATE(xas, &fs_info->buffer_tree, eb->start >> fs_info->sectorsize_bits);
1888+
XA_STATE(xas, &fs_info->buffer_tree, eb->start >> fs_info->node_bits);
18891889
unsigned long flags;
18901890

18911891
xas_lock_irqsave(&xas, flags);
@@ -1985,7 +1985,7 @@ static unsigned int buffer_tree_get_ebs_tag(struct btrfs_fs_info *fs_info,
19851985
rcu_read_lock();
19861986
while ((eb = find_get_eb(&xas, end, tag)) != NULL) {
19871987
if (!eb_batch_add(batch, eb)) {
1988-
*start = ((eb->start + eb->len) >> fs_info->sectorsize_bits);
1988+
*start = ((eb->start + eb->len) >> fs_info->node_bits);
19891989
goto out;
19901990
}
19911991
}
@@ -2007,7 +2007,7 @@ static struct extent_buffer *find_extent_buffer_nolock(
20072007
struct btrfs_fs_info *fs_info, u64 start)
20082008
{
20092009
struct extent_buffer *eb;
2010-
unsigned long index = (start >> fs_info->sectorsize_bits);
2010+
unsigned long index = (start >> fs_info->node_bits);
20112011

20122012
rcu_read_lock();
20132013
eb = xa_load(&fs_info->buffer_tree, index);
@@ -2113,8 +2113,8 @@ void btrfs_btree_wait_writeback_range(struct btrfs_fs_info *fs_info, u64 start,
21132113
u64 end)
21142114
{
21152115
struct eb_batch batch;
2116-
unsigned long start_index = (start >> fs_info->sectorsize_bits);
2117-
unsigned long end_index = (end >> fs_info->sectorsize_bits);
2116+
unsigned long start_index = (start >> fs_info->node_bits);
2117+
unsigned long end_index = (end >> fs_info->node_bits);
21182118

21192119
eb_batch_init(&batch);
21202120
while (start_index <= end_index) {
@@ -2150,7 +2150,7 @@ int btree_write_cache_pages(struct address_space *mapping,
21502150

21512151
eb_batch_init(&batch);
21522152
if (wbc->range_cyclic) {
2153-
index = ((mapping->writeback_index << PAGE_SHIFT) >> fs_info->sectorsize_bits);
2153+
index = ((mapping->writeback_index << PAGE_SHIFT) >> fs_info->node_bits);
21542154
end = -1;
21552155

21562156
/*
@@ -2159,8 +2159,8 @@ int btree_write_cache_pages(struct address_space *mapping,
21592159
*/
21602160
scanned = (index == 0);
21612161
} else {
2162-
index = (wbc->range_start >> fs_info->sectorsize_bits);
2163-
end = (wbc->range_end >> fs_info->sectorsize_bits);
2162+
index = (wbc->range_start >> fs_info->node_bits);
2163+
end = (wbc->range_end >> fs_info->node_bits);
21642164

21652165
scanned = 1;
21662166
}
@@ -3037,7 +3037,7 @@ struct extent_buffer *alloc_test_extent_buffer(struct btrfs_fs_info *fs_info,
30373037
eb->fs_info = fs_info;
30383038
again:
30393039
xa_lock_irq(&fs_info->buffer_tree);
3040-
exists = __xa_cmpxchg(&fs_info->buffer_tree, start >> fs_info->sectorsize_bits,
3040+
exists = __xa_cmpxchg(&fs_info->buffer_tree, start >> fs_info->node_bits,
30413041
NULL, eb, GFP_NOFS);
30423042
if (xa_is_err(exists)) {
30433043
ret = xa_err(exists);
@@ -3354,7 +3354,7 @@ struct extent_buffer *alloc_extent_buffer(struct btrfs_fs_info *fs_info,
33543354
again:
33553355
xa_lock_irq(&fs_info->buffer_tree);
33563356
existing_eb = __xa_cmpxchg(&fs_info->buffer_tree,
3357-
start >> fs_info->sectorsize_bits, NULL, eb,
3357+
start >> fs_info->node_bits, NULL, eb,
33583358
GFP_NOFS);
33593359
if (xa_is_err(existing_eb)) {
33603360
ret = xa_err(existing_eb);
@@ -3457,7 +3457,7 @@ static int release_extent_buffer(struct extent_buffer *eb)
34573457
* in this case.
34583458
*/
34593459
xa_cmpxchg_irq(&fs_info->buffer_tree,
3460-
eb->start >> fs_info->sectorsize_bits, eb, NULL,
3460+
eb->start >> fs_info->node_bits, eb, NULL,
34613461
GFP_ATOMIC);
34623462

34633463
btrfs_leak_debug_del_eb(eb);
@@ -4299,9 +4299,9 @@ static int try_release_subpage_extent_buffer(struct folio *folio)
42994299
{
43004300
struct btrfs_fs_info *fs_info = folio_to_fs_info(folio);
43014301
struct extent_buffer *eb;
4302-
unsigned long start = (folio_pos(folio) >> fs_info->sectorsize_bits);
4302+
unsigned long start = (folio_pos(folio) >> fs_info->node_bits);
43034303
unsigned long index = start;
4304-
unsigned long end = index + (PAGE_SIZE >> fs_info->sectorsize_bits) - 1;
4304+
unsigned long end = index + (PAGE_SIZE >> fs_info->node_bits) - 1;
43054305
int ret;
43064306

43074307
xa_lock_irq(&fs_info->buffer_tree);

fs/btrfs/fs.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -781,8 +781,9 @@ struct btrfs_fs_info {
781781

782782
struct btrfs_delayed_root *delayed_root;
783783

784-
/* Entries are eb->start / sectorsize */
784+
/* Entries are eb->start >> node_bits */
785785
struct xarray buffer_tree;
786+
int node_bits;
786787

787788
/* Next backup root to be overwritten */
788789
int backup_root_index;

0 commit comments

Comments
 (0)