Skip to content

Commit 72731b0

Browse files
adam900710kdave
authored andcommitted
btrfs: enable experimental large data folio support
With all the preparation patches already merged, it's pretty easy to enable large data folios: - Remove the ASSERT() on folio size in btrfs_end_repair_bio() - Add a helper to properly set the max folio order Currently due to several call sites are fetching the bitmap content directly into an unsigned long, we can only support BITS_PER_LONG blocks for each bitmap. - Call the helper when reading/creating an inode The support has the following limits: - No large folios for data reloc inode The relocation code still requires page sized folio. But it's not that hot nor common compared to regular buffered ios. Will be improved in the future. - Requires CONFIG_BTRFS_EXPERIMENTAL Unfortunately I do not have a physical machine for performance test, but if everything goes like XFS/EXT4, it should mostly bring single digits percentage performance improvement in the real world. Although I believe there are still quite some optimizations to be done, let's focus on testing the current large data folio support first. Signed-off-by: Qu Wenruo <wqu@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
1 parent 8ea2218 commit 72731b0

File tree

3 files changed

+19
-6
lines changed

3 files changed

+19
-6
lines changed

fs/btrfs/bio.c

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -165,12 +165,6 @@ static void btrfs_end_repair_bio(struct btrfs_bio *repair_bbio,
165165
struct bio_vec *bv = bio_first_bvec_all(&repair_bbio->bio);
166166
int mirror = repair_bbio->mirror_num;
167167

168-
/*
169-
* We can only trigger this for data bio, which doesn't support larger
170-
* folios yet.
171-
*/
172-
ASSERT(folio_order(page_folio(bv->bv_page)) == 0);
173-
174168
if (repair_bbio->bio.bi_status ||
175169
!btrfs_data_csum_ok(repair_bbio, dev, 0, bv)) {
176170
bio_reset(&repair_bbio->bio, NULL, REQ_OP_READ);

fs/btrfs/btrfs_inode.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -525,6 +525,23 @@ static inline void btrfs_update_inode_mapping_flags(struct btrfs_inode *inode)
525525
mapping_set_stable_writes(inode->vfs_inode.i_mapping);
526526
}
527527

528+
static inline void btrfs_set_inode_mapping_order(struct btrfs_inode *inode)
529+
{
530+
/* Metadata inode should not reach here. */
531+
ASSERT(is_data_inode(inode));
532+
533+
/* For data reloc inode, it still requires page sized folio. */
534+
if (unlikely(btrfs_is_data_reloc_root(inode->root)))
535+
return;
536+
537+
/* We only allows BITS_PER_LONGS blocks for each bitmap. */
538+
#ifdef CONFIG_BTRFS_EXPERIMENTAL
539+
mapping_set_folio_order_range(inode->vfs_inode.i_mapping, 0,
540+
ilog2(((BITS_PER_LONG << inode->root->fs_info->sectorsize_bits)
541+
>> PAGE_SHIFT)));
542+
#endif
543+
}
544+
528545
/* Array of bytes with variable length, hexadecimal format 0x1234 */
529546
#define CSUM_FMT "0x%*phN"
530547
#define CSUM_FMT_VALUE(size, bytes) size, bytes

fs/btrfs/inode.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3946,6 +3946,7 @@ static int btrfs_read_locked_inode(struct btrfs_inode *inode, struct btrfs_path
39463946
btrfs_inode_split_flags(btrfs_inode_flags(leaf, inode_item),
39473947
&inode->flags, &inode->ro_flags);
39483948
btrfs_update_inode_mapping_flags(inode);
3949+
btrfs_set_inode_mapping_order(inode);
39493950

39503951
cache_index:
39513952
/*
@@ -6463,6 +6464,7 @@ int btrfs_create_new_inode(struct btrfs_trans_handle *trans,
64636464
BTRFS_I(inode)->flags |= BTRFS_INODE_NODATACOW |
64646465
BTRFS_INODE_NODATASUM;
64656466
btrfs_update_inode_mapping_flags(BTRFS_I(inode));
6467+
btrfs_set_inode_mapping_order(BTRFS_I(inode));
64666468
}
64676469

64686470
ret = btrfs_insert_inode_locked(inode);

0 commit comments

Comments
 (0)