[Ocfs2-devel] [PATCH v2] ocfs2: fix non-auto defrag path not working issue
Joseph Qi
joseph.qi at linux.alibaba.com
Mon Feb 20 06:26:19 UTC 2023
On 2/20/23 1:05 PM, Heming Zhao wrote:
> This fixes three issues on move extents ioctl without auto defrag:
>
> a) In ocfs2_find_victim_alloc_group(), we have to convert bits to block
> first in case of global bitmap.
> b) In ocfs2_probe_alloc_group(), when finding enough bits in block group
> bitmap, we have to back off move_len to start pos as well, otherwise it
> may corrupt filesystem.
> c) In ocfs2_ioctl_move_extents(), set me_threshold both for non-auto and
> auto defrag paths. Otherwise it will set move_max_hop to 0 and finally
> cause unexpectedly ENOSPC error.
>
> Currently there is no tools triggering the above issues since
> defragfs.ocfs2 enables auto defrag by default. Test with manually
> changing defragfs.ocfs2 to run non auto defrag path.
>
> Signed-off-by: Heming Zhao <heming.zhao at suse.com>
Reviewed-by: Joseph Qi <joseph.qi at linux.alibaba.com>
> ---
> v2: revise commit log under review comment
>
> ---
> fs/ocfs2/move_extents.c | 24 +++++++++++++-----------
> 1 file changed, 13 insertions(+), 11 deletions(-)
>
> diff --git a/fs/ocfs2/move_extents.c b/fs/ocfs2/move_extents.c
> index 6251748c695b..b1e32ec4a9d4 100644
> --- a/fs/ocfs2/move_extents.c
> +++ b/fs/ocfs2/move_extents.c
> @@ -434,7 +434,7 @@ static int ocfs2_find_victim_alloc_group(struct inode *inode,
> bg = (struct ocfs2_group_desc *)gd_bh->b_data;
>
> if (vict_blkno < (le64_to_cpu(bg->bg_blkno) +
> - le16_to_cpu(bg->bg_bits))) {
> + (le16_to_cpu(bg->bg_bits) << bits_per_unit))) {
>
> *ret_bh = gd_bh;
> *vict_bit = (vict_blkno - blkno) >>
> @@ -549,6 +549,7 @@ static void ocfs2_probe_alloc_group(struct inode *inode, struct buffer_head *bh,
> last_free_bits++;
>
> if (last_free_bits == move_len) {
> + i -= move_len;
> *goal_bit = i;
> *phys_cpos = base_cpos + i;
> break;
> @@ -1020,18 +1021,19 @@ int ocfs2_ioctl_move_extents(struct file *filp, void __user *argp)
>
> context->range = ⦥
>
> + /*
> + * ok, the default theshold for the defragmentation
> + * is 1M, since our maximum clustersize was 1M also.
> + * any thought?
> + */
> + if (!range.me_threshold)
> + range.me_threshold = 1024 * 1024;
> +
> + if (range.me_threshold > i_size_read(inode))
> + range.me_threshold = i_size_read(inode);
> +
> if (range.me_flags & OCFS2_MOVE_EXT_FL_AUTO_DEFRAG) {
> context->auto_defrag = 1;
> - /*
> - * ok, the default theshold for the defragmentation
> - * is 1M, since our maximum clustersize was 1M also.
> - * any thought?
> - */
> - if (!range.me_threshold)
> - range.me_threshold = 1024 * 1024;
> -
> - if (range.me_threshold > i_size_read(inode))
> - range.me_threshold = i_size_read(inode);
>
> if (range.me_flags & OCFS2_MOVE_EXT_FL_PART_DEFRAG)
> context->partial = 1;
More information about the Ocfs2-devel
mailing list