Skip to content

Commit e7c8765

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 <[email protected]> Signed-off-by: David Sterba <[email protected]>
1 parent ce6952f commit e7c8765

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
@@ -1774,7 +1774,7 @@ static noinline_for_stack bool lock_extent_buffer_for_io(struct extent_buffer *e
17741774
*/
17751775
spin_lock(&eb->refs_lock);
17761776
if (test_and_clear_bit(EXTENT_BUFFER_DIRTY, &eb->bflags)) {
1777-
XA_STATE(xas, &fs_info->buffer_tree, eb->start >> fs_info->sectorsize_bits);
1777+
XA_STATE(xas, &fs_info->buffer_tree, eb->start >> fs_info->node_bits);
17781778
unsigned long flags;
17791779

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

18801880
xas_lock_irqsave(&xas, flags);
@@ -1886,7 +1886,7 @@ static void buffer_tree_set_mark(const struct extent_buffer *eb, xa_mark_t mark)
18861886
static void buffer_tree_clear_mark(const struct extent_buffer *eb, xa_mark_t mark)
18871887
{
18881888
struct btrfs_fs_info *fs_info = eb->fs_info;
1889-
XA_STATE(xas, &fs_info->buffer_tree, eb->start >> fs_info->sectorsize_bits);
1889+
XA_STATE(xas, &fs_info->buffer_tree, eb->start >> fs_info->node_bits);
18901890
unsigned long flags;
18911891

18921892
xas_lock_irqsave(&xas, flags);
@@ -1986,7 +1986,7 @@ static unsigned int buffer_tree_get_ebs_tag(struct btrfs_fs_info *fs_info,
19861986
rcu_read_lock();
19871987
while ((eb = find_get_eb(&xas, end, tag)) != NULL) {
19881988
if (!eb_batch_add(batch, eb)) {
1989-
*start = ((eb->start + eb->len) >> fs_info->sectorsize_bits);
1989+
*start = ((eb->start + eb->len) >> fs_info->node_bits);
19901990
goto out;
19911991
}
19921992
}
@@ -2008,7 +2008,7 @@ static struct extent_buffer *find_extent_buffer_nolock(
20082008
struct btrfs_fs_info *fs_info, u64 start)
20092009
{
20102010
struct extent_buffer *eb;
2011-
unsigned long index = (start >> fs_info->sectorsize_bits);
2011+
unsigned long index = (start >> fs_info->node_bits);
20122012

20132013
rcu_read_lock();
20142014
eb = xa_load(&fs_info->buffer_tree, index);
@@ -2114,8 +2114,8 @@ void btrfs_btree_wait_writeback_range(struct btrfs_fs_info *fs_info, u64 start,
21142114
u64 end)
21152115
{
21162116
struct eb_batch batch;
2117-
unsigned long start_index = (start >> fs_info->sectorsize_bits);
2118-
unsigned long end_index = (end >> fs_info->sectorsize_bits);
2117+
unsigned long start_index = (start >> fs_info->node_bits);
2118+
unsigned long end_index = (end >> fs_info->node_bits);
21192119

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

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

21572157
/*
@@ -2160,8 +2160,8 @@ int btree_write_cache_pages(struct address_space *mapping,
21602160
*/
21612161
scanned = (index == 0);
21622162
} else {
2163-
index = (wbc->range_start >> fs_info->sectorsize_bits);
2164-
end = (wbc->range_end >> fs_info->sectorsize_bits);
2163+
index = (wbc->range_start >> fs_info->node_bits);
2164+
end = (wbc->range_end >> fs_info->node_bits);
21652165

21662166
scanned = 1;
21672167
}
@@ -3038,7 +3038,7 @@ struct extent_buffer *alloc_test_extent_buffer(struct btrfs_fs_info *fs_info,
30383038
eb->fs_info = fs_info;
30393039
again:
30403040
xa_lock_irq(&fs_info->buffer_tree);
3041-
exists = __xa_cmpxchg(&fs_info->buffer_tree, start >> fs_info->sectorsize_bits,
3041+
exists = __xa_cmpxchg(&fs_info->buffer_tree, start >> fs_info->node_bits,
30423042
NULL, eb, GFP_NOFS);
30433043
if (xa_is_err(exists)) {
30443044
ret = xa_err(exists);
@@ -3355,7 +3355,7 @@ struct extent_buffer *alloc_extent_buffer(struct btrfs_fs_info *fs_info,
33553355
again:
33563356
xa_lock_irq(&fs_info->buffer_tree);
33573357
existing_eb = __xa_cmpxchg(&fs_info->buffer_tree,
3358-
start >> fs_info->sectorsize_bits, NULL, eb,
3358+
start >> fs_info->node_bits, NULL, eb,
33593359
GFP_NOFS);
33603360
if (xa_is_err(existing_eb)) {
33613361
ret = xa_err(existing_eb);
@@ -3458,7 +3458,7 @@ static int release_extent_buffer(struct extent_buffer *eb)
34583458
* in this case.
34593459
*/
34603460
xa_cmpxchg_irq(&fs_info->buffer_tree,
3461-
eb->start >> fs_info->sectorsize_bits, eb, NULL,
3461+
eb->start >> fs_info->node_bits, eb, NULL,
34623462
GFP_ATOMIC);
34633463

34643464
btrfs_leak_debug_del_eb(eb);
@@ -4300,9 +4300,9 @@ static int try_release_subpage_extent_buffer(struct folio *folio)
43004300
{
43014301
struct btrfs_fs_info *fs_info = folio_to_fs_info(folio);
43024302
struct extent_buffer *eb;
4303-
unsigned long start = (folio_pos(folio) >> fs_info->sectorsize_bits);
4303+
unsigned long start = (folio_pos(folio) >> fs_info->node_bits);
43044304
unsigned long index = start;
4305-
unsigned long end = index + (PAGE_SIZE >> fs_info->sectorsize_bits) - 1;
4305+
unsigned long end = index + (PAGE_SIZE >> fs_info->node_bits) - 1;
43064306
int ret;
43074307

43084308
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)