- open-code the empty cntbt case Signed-off-by: Brian Foster <bfoster@xxxxxxxxxx> --- fs/xfs/libxfs/xfs_alloc.c | 61 +++++++++++++++++++++++++-------------- 1 file changed, 39 insertions(+), 22 deletions(-) diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c index a7e3daa16717..cd35502eee2b 100644 --- a/fs/xfs/libxfs/xfs_alloc.c +++ b/fs/xfs/libxfs/xfs_alloc.c @@ -1323,21 +1323,21 @@ xfs_alloc_ag_vextent_near_bnobt( */ STATIC int /* error */ xfs_alloc_ag_vextent_near( - xfs_alloc_arg_t *args) /* allocation argument structure */ + struct xfs_alloc_arg *args) /* allocation argument structure */ { - xfs_btree_cur_t *bno_cur = NULL;/* cursor for bno btree */ - xfs_btree_cur_t *cnt_cur; /* cursor for count btree */ - int error; /* error code */ - int i; /* result code, temporary */ - xfs_agblock_t ltbno; /* start bno of left side entry */ - xfs_extlen_t ltlen; /* length of left side entry */ - bool busy; - unsigned busy_gen; + struct xfs_btree_cur *bno_cur = NULL;/* cursor for bno btree */ + struct xfs_btree_cur *cnt_cur; /* cursor for count btree */ + int error; /* error code */ + int i; /* result code, temporary */ + xfs_agblock_t ltbno; /* start bno of left side entry */ + xfs_extlen_t ltlen; /* length of left side entry */ + bool busy; + unsigned busy_gen; #ifdef DEBUG /* * Randomly don't execute the first algorithm. */ - int dofirst; /* set to do first algorithm */ + int dofirst; /* set to do first algorithm */ dofirst = prandom_u32() & 1; #endif @@ -1358,32 +1358,49 @@ xfs_alloc_ag_vextent_near( busy = false; /* - * Get a cursor for the by-size btree. + * Get a cursor for the by-size btree and start with a lookup for maxlen + * free extents. */ cnt_cur = xfs_allocbt_init_cursor(args->mp, args->tp, args->agbp, - args->agno, XFS_BTNUM_CNT); - - /* - * See if there are any free extents as big as maxlen. - */ + args->agno, XFS_BTNUM_CNT); error = xfs_alloc_lookup_ge(cnt_cur, 0, args->maxlen, &i); if (error) goto error; + /* - * If none, then pick up the last entry in the tree unless the - * tree is empty. + * If there are no maxlen extents, check the last (largest) record + * against minlen. If it's usable, the cntbt search will find the best + * >= minlen extent to use in the last block. If the cntbt is completely + * empty, the only other option is to try and allocate from the AGFL. */ if (!i) { - error = xfs_alloc_ag_vextent_small(args, cnt_cur, <bno, - <len, &i); + error = xfs_btree_decrement(cnt_cur, 0, &i); if (error) goto error; - if (i == 0 || ltlen == 0) { + if (i) { + error = xfs_alloc_get_rec(cnt_cur, <bno, <len, &i); + if (error) + goto error; + XFS_WANT_CORRUPTED_GOTO(args->mp, i == 1, error); + if (ltlen < args->minlen) { + trace_xfs_alloc_small_notenough(args); + return 0; + } + } else { + /* + * We only get here if the cntbt is empty so this call + * returns an AGFL block or nothing. We're done either + * way. + */ + error = xfs_alloc_ag_vextent_small(args, cnt_cur, + <bno, <len, &i); + if (error) + goto error; + ASSERT(i == 0 || (i && ltlen == 0)); xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR); trace_xfs_alloc_near_noentry(args); return 0; } - ASSERT(i == 1); } args->wasfromfl = 0; -- 2.17.2