Skip to content

Commit 2210bb4

Browse files
adam900710kdave
authored andcommitted
btrfs: enable large data folios for data reloc inode
For data reloc inodes, they are a special type of inodes that are not exposed to user space, and are only utilized during data block groups relocation. They do not go under regular read-write operations, but have their file extents manually created to have the same layout of a block group, then its content is read from the original block group, and written back to the new location which is in a new block group. Previously all the handling was done in page units, and commit c283289 ("btrfs: make relocate_one_page() handle subpage case") changed the handling to subpage blocks. On the other hand, data reloc inodes are a perfect match for large data folios, as each relocation cluster represents one or more data extents that are contiguous in their logical addresses. This patch enables large folios for data reloc inodes by: - Remove the special handling of data reloc inodes when setting folio order - Change relocate_one_folio() to return the file offset of the next folio Originally it's designed to handle fixed page sized blocks, but with large folios, we can handle a large folio, thus we have to return the end of the current folio. - Remove the warning on folio_order() - Use folio_size() to replace fixed PAGE_SIZE usage - Use file_offset as iterator inside relocate_file_extent_cluster Signed-off-by: Qu Wenruo <[email protected]> Signed-off-by: David Sterba <[email protected]>
1 parent 422662b commit 2210bb4

File tree

2 files changed

+13
-15
lines changed

2 files changed

+13
-15
lines changed

fs/btrfs/btrfs_inode.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -530,10 +530,6 @@ static inline void btrfs_set_inode_mapping_order(struct btrfs_inode *inode)
530530
/* Metadata inode should not reach here. */
531531
ASSERT(is_data_inode(inode));
532532

533-
/* For data reloc inode, it still requires page sized folio. */
534-
if (unlikely(btrfs_is_data_reloc_root(inode->root)))
535-
return;
536-
537533
/* We only allows BITS_PER_LONGS blocks for each bitmap. */
538534
#ifdef CONFIG_BTRFS_EXPERIMENTAL
539535
mapping_set_folio_order_range(inode->vfs_inode.i_mapping, 0,

fs/btrfs/relocation.c

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2772,13 +2772,15 @@ static u64 get_cluster_boundary_end(const struct file_extent_cluster *cluster,
27722772

27732773
static int relocate_one_folio(struct reloc_control *rc,
27742774
struct file_ra_state *ra,
2775-
int *cluster_nr, pgoff_t index)
2775+
int *cluster_nr, u64 *file_offset_ret)
27762776
{
27772777
const struct file_extent_cluster *cluster = &rc->cluster;
27782778
struct inode *inode = rc->data_inode;
27792779
struct btrfs_fs_info *fs_info = inode_to_fs_info(inode);
2780+
const u64 orig_file_offset = *file_offset_ret;
27802781
u64 offset = BTRFS_I(inode)->reloc_block_group_start;
27812782
const pgoff_t last_index = (cluster->end - offset) >> PAGE_SHIFT;
2783+
const pgoff_t index = orig_file_offset >> PAGE_SHIFT;
27822784
gfp_t mask = btrfs_alloc_write_mask(inode->i_mapping);
27832785
struct folio *folio;
27842786
u64 folio_start;
@@ -2811,8 +2813,6 @@ static int relocate_one_folio(struct reloc_control *rc,
28112813
return PTR_ERR(folio);
28122814
}
28132815

2814-
WARN_ON(folio_order(folio));
2815-
28162816
if (folio_test_readahead(folio) && !use_rst)
28172817
page_cache_async_readahead(inode->i_mapping, ra, NULL,
28182818
folio, last_index + 1 - index);
@@ -2841,7 +2841,7 @@ static int relocate_one_folio(struct reloc_control *rc,
28412841
goto release_folio;
28422842

28432843
folio_start = folio_pos(folio);
2844-
folio_end = folio_start + PAGE_SIZE - 1;
2844+
folio_end = folio_start + folio_size(folio) - 1;
28452845

28462846
/*
28472847
* Start from the cluster, as for subpage case, the cluster can start
@@ -2889,7 +2889,8 @@ static int relocate_one_folio(struct reloc_control *rc,
28892889
* EXTENT_BOUNDARY bit prevents current extent from being merged
28902890
* with previous extent.
28912891
*/
2892-
if (in_range(cluster->boundary[*cluster_nr] - offset, folio_start, PAGE_SIZE)) {
2892+
if (in_range(cluster->boundary[*cluster_nr] - offset,
2893+
folio_start, folio_size(folio))) {
28932894
u64 boundary_start = cluster->boundary[*cluster_nr] -
28942895
offset;
28952896
u64 boundary_end = boundary_start +
@@ -2919,6 +2920,7 @@ static int relocate_one_folio(struct reloc_control *rc,
29192920
btrfs_throttle(fs_info);
29202921
if (btrfs_should_cancel_balance(fs_info))
29212922
ret = -ECANCELED;
2923+
*file_offset_ret = folio_end + 1;
29222924
return ret;
29232925

29242926
release_folio:
@@ -2932,8 +2934,7 @@ static int relocate_file_extent_cluster(struct reloc_control *rc)
29322934
struct inode *inode = rc->data_inode;
29332935
const struct file_extent_cluster *cluster = &rc->cluster;
29342936
u64 offset = BTRFS_I(inode)->reloc_block_group_start;
2935-
pgoff_t index;
2936-
pgoff_t last_index;
2937+
u64 cur_file_offset = cluster->start - offset;
29372938
struct file_ra_state *ra;
29382939
int cluster_nr = 0;
29392940
int ret = 0;
@@ -2955,10 +2956,11 @@ static int relocate_file_extent_cluster(struct reloc_control *rc)
29552956
if (ret)
29562957
goto out;
29572958

2958-
last_index = (cluster->end - offset) >> PAGE_SHIFT;
2959-
for (index = (cluster->start - offset) >> PAGE_SHIFT;
2960-
index <= last_index && !ret; index++)
2961-
ret = relocate_one_folio(rc, ra, &cluster_nr, index);
2959+
while (cur_file_offset < cluster->end - offset) {
2960+
ret = relocate_one_folio(rc, ra, &cluster_nr, &cur_file_offset);
2961+
if (ret)
2962+
break;
2963+
}
29622964
if (ret == 0)
29632965
WARN_ON(cluster_nr != cluster->nr);
29642966
out:

0 commit comments

Comments
 (0)