Re: [PATCH 21/25] ext4: make online defragmentation support large block size

From: Jan Kara

Date: Wed Nov 05 2025 - 04:50:28 EST


On Sat 25-10-25 11:22:17, libaokun@xxxxxxxxxxxxxxx wrote:
> From: Zhihao Cheng <chengzhihao1@xxxxxxxxxx>
>
> There are several places assuming that block size <= PAGE_SIZE, modify
> them to support large block size (bs > ps).
>
> Signed-off-by: Zhihao Cheng <chengzhihao1@xxxxxxxxxx>
> Signed-off-by: Baokun Li <libaokun1@xxxxxxxxxx>

...

> @@ -565,7 +564,7 @@ ext4_move_extents(struct file *o_filp, struct file *d_filp, __u64 orig_blk,
> struct inode *orig_inode = file_inode(o_filp);
> struct inode *donor_inode = file_inode(d_filp);
> struct ext4_ext_path *path = NULL;
> - int blocks_per_page = PAGE_SIZE >> orig_inode->i_blkbits;
> + int blocks_per_page = 1;
> ext4_lblk_t o_end, o_start = orig_blk;
> ext4_lblk_t d_start = donor_blk;
> int ret;
> @@ -608,6 +607,9 @@ ext4_move_extents(struct file *o_filp, struct file *d_filp, __u64 orig_blk,
> return -EOPNOTSUPP;
> }
>
> + if (i_blocksize(orig_inode) < PAGE_SIZE)
> + blocks_per_page = PAGE_SIZE >> orig_inode->i_blkbits;
> +

I think these are strange and the only reason for this is that
ext4_move_extents() tries to make life easier to move_extent_per_page() and
that doesn't really work with larger folios anymore. I think
ext4_move_extents() just shouldn't care about pages / folios at all and
pass 'cur_len' as the length to the end of extent / moved range and
move_extent_per_page() will trim the length based on the folios it has got.

Also then we can rename some of the variables and functions from 'page' to
'folio'.

Honza

> /* Protect orig and donor inodes against a truncate */
> lock_two_nondirectories(orig_inode, donor_inode);
>
> @@ -665,10 +667,8 @@ ext4_move_extents(struct file *o_filp, struct file *d_filp, __u64 orig_blk,
> if (o_end - o_start < cur_len)
> cur_len = o_end - o_start;
>
> - orig_page_index = o_start >> (PAGE_SHIFT -
> - orig_inode->i_blkbits);
> - donor_page_index = d_start >> (PAGE_SHIFT -
> - donor_inode->i_blkbits);
> + orig_page_index = EXT4_LBLK_TO_P(orig_inode, o_start);
> + donor_page_index = EXT4_LBLK_TO_P(donor_inode, d_start);
> offset_in_page = o_start % blocks_per_page;
> if (cur_len > blocks_per_page - offset_in_page)
> cur_len = blocks_per_page - offset_in_page;
> --
> 2.46.1
>
--
Jan Kara <jack@xxxxxxxx>
SUSE Labs, CR