From: Shida Zhang <zhangshida@xxxxxxxxxx> Add a function to search through all the AFs in a alloction. Add two members in *args* to trace the current AF. And properly initialize these members so as to keeping the behavior exacly the same with the original code logic. And for those bmbt alloction, we can slightly break the roles imposed by AF, since it's allocating one block at a time. Remember our goal to propose the concept of AF is to avoid a badly fragmented filesystem to consume all the continuous free space. So just initialize it in a way like this alloctions are in a AF ranging from [0, ag_count). Signed-off-by: Shida Zhang <zhangshida@xxxxxxxxxx> --- fs/xfs/libxfs/xfs_alloc.h | 2 ++ fs/xfs/libxfs/xfs_bmap.c | 34 ++++++++++++++++++++++++++++++++++ fs/xfs/libxfs/xfs_bmap_btree.c | 2 ++ 3 files changed, 38 insertions(+) diff --git a/fs/xfs/libxfs/xfs_alloc.h b/fs/xfs/libxfs/xfs_alloc.h index 0165452e7cd0..ab34aceecc72 100644 --- a/fs/xfs/libxfs/xfs_alloc.h +++ b/fs/xfs/libxfs/xfs_alloc.h @@ -56,6 +56,8 @@ typedef struct xfs_alloc_arg { bool alloc_minlen_only; /* allocate exact minlen extent */ struct xfs_owner_info oinfo; /* owner of blocks being allocated */ enum xfs_ag_resv_type resv; /* block reservation to use */ + xfs_agnumber_t curr_af; /* start agno of the allocation field */ + xfs_agnumber_t next_af; /* next point of the allocation field */ } xfs_alloc_arg_t; /* diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 36dd08d13293..b55b8670730c 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -683,6 +683,8 @@ xfs_bmap_extents_to_btree( args.minlen = args.maxlen = args.prod = 1; args.wasdel = wasdel; *logflagsp = 0; + args.curr_af = 0; + args.next_af = mp->m_sb.sb_agcount; error = xfs_alloc_vextent_start_ag(&args, XFS_INO_TO_FSB(mp, ip->i_ino)); if (error) @@ -830,6 +832,8 @@ xfs_bmap_local_to_extents( */ args.total = total; args.minlen = args.maxlen = args.prod = 1; + args.curr_af = 0; + args.next_af = args.mp->m_sb.sb_agcount; error = xfs_alloc_vextent_start_ag(&args, XFS_INO_TO_FSB(args.mp, ip->i_ino)); if (error) @@ -3630,6 +3634,8 @@ xfs_bmap_btalloc_low_space( if (args->minlen > ap->minlen) { args->minlen = ap->minlen; + args->curr_af = 0; + args->next_af = args->mp->m_sb.sb_agcount; error = xfs_alloc_vextent_start_ag(args, ap->blkno); if (error || args->fsbno != NULLFSBLOCK) return error; @@ -3735,6 +3741,32 @@ xfs_bmap_btalloc_best_length( return xfs_bmap_btalloc_low_space(ap, args); } +static int +xfs_bmap_btalloc_best_length_iterate_afs( + struct xfs_bmalloca *ap, + struct xfs_alloc_arg *args, + int stripe_align) +{ + struct xfs_mount *mp = ap->ip->i_mount; + int error; + unsigned int i; + + args->curr_af = 0; + + for (i = 0; args->curr_af < mp->m_sb.sb_agcount; i++) { + args->next_af = mp->m_sb.sb_agcount - mp->m_af[i]; + error = xfs_bmap_btalloc_best_length(ap, args, stripe_align); + if (error || args->fsbno != NULLFSBLOCK) + break; + + args->curr_af = args->next_af; + /* Exit LOWMODE when going to the next AF. */ + ap->tp->t_flags &= ~XFS_TRANS_LOWMODE; + } + + return error; +} + static int xfs_bmap_btalloc( struct xfs_bmalloca *ap) @@ -3751,6 +3783,8 @@ xfs_bmap_btalloc( .datatype = ap->datatype, .alignment = 1, .minalignslop = 0, + .curr_af = 0, + .next_af = mp->m_sb.sb_agcount, }; xfs_fileoff_t orig_offset; xfs_extlen_t orig_length; diff --git a/fs/xfs/libxfs/xfs_bmap_btree.c b/fs/xfs/libxfs/xfs_bmap_btree.c index 3464be771f95..4e57b6f897e8 100644 --- a/fs/xfs/libxfs/xfs_bmap_btree.c +++ b/fs/xfs/libxfs/xfs_bmap_btree.c @@ -234,6 +234,8 @@ xfs_bmbt_alloc_block( args.minleft = xfs_bmapi_minleft(cur->bc_tp, cur->bc_ino.ip, cur->bc_ino.whichfork); + args.curr_af = 0; + args.next_af = args.mp->m_sb.sb_agcount; error = xfs_alloc_vextent_start_ag(&args, be64_to_cpu(start->l)); if (error) return error; -- 2.33.0