aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/xfs/libxfs/xfs_alloc.c81
-rw-r--r--fs/xfs/libxfs/xfs_alloc.h2
2 files changed, 18 insertions, 65 deletions
diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c
index fe925702c955..f2e7eb6e5243 100644
--- a/fs/xfs/libxfs/xfs_alloc.c
+++ b/fs/xfs/libxfs/xfs_alloc.c
@@ -362,36 +362,12 @@ xfs_alloc_fix_len(
362 return; 362 return;
363 ASSERT(rlen >= args->minlen && rlen <= args->maxlen); 363 ASSERT(rlen >= args->minlen && rlen <= args->maxlen);
364 ASSERT(rlen % args->prod == args->mod); 364 ASSERT(rlen % args->prod == args->mod);
365 ASSERT(args->pag->pagf_freeblks + args->pag->pagf_flcount >=
366 rlen + args->minleft);
365 args->len = rlen; 367 args->len = rlen;
366} 368}
367 369
368/* 370/*
369 * Fix up length if there is too little space left in the a.g.
370 * Return 1 if ok, 0 if too little, should give up.
371 */
372STATIC int
373xfs_alloc_fix_minleft(
374 xfs_alloc_arg_t *args) /* allocation argument structure */
375{
376 xfs_agf_t *agf; /* a.g. freelist header */
377 int diff; /* free space difference */
378
379 if (args->minleft == 0)
380 return 1;
381 agf = XFS_BUF_TO_AGF(args->agbp);
382 diff = be32_to_cpu(agf->agf_freeblks)
383 - args->len - args->minleft;
384 if (diff >= 0)
385 return 1;
386 args->len += diff; /* shrink the allocated space */
387 /* casts to (int) catch length underflows */
388 if ((int)args->len >= (int)args->minlen)
389 return 1;
390 args->agbno = NULLAGBLOCK;
391 return 0;
392}
393
394/*
395 * Update the two btrees, logically removing from freespace the extent 371 * Update the two btrees, logically removing from freespace the extent
396 * starting at rbno, rlen blocks. The extent is contained within the 372 * starting at rbno, rlen blocks. The extent is contained within the
397 * actual (current) free extent fbno for flen blocks. 373 * actual (current) free extent fbno for flen blocks.
@@ -686,8 +662,6 @@ xfs_alloc_ag_vextent(
686 xfs_alloc_arg_t *args) /* argument structure for allocation */ 662 xfs_alloc_arg_t *args) /* argument structure for allocation */
687{ 663{
688 int error=0; 664 int error=0;
689 xfs_extlen_t reservation;
690 xfs_extlen_t oldmax;
691 665
692 ASSERT(args->minlen > 0); 666 ASSERT(args->minlen > 0);
693 ASSERT(args->maxlen > 0); 667 ASSERT(args->maxlen > 0);
@@ -696,20 +670,6 @@ xfs_alloc_ag_vextent(
696 ASSERT(args->alignment > 0); 670 ASSERT(args->alignment > 0);
697 671
698 /* 672 /*
699 * Clamp maxlen to the amount of free space minus any reservations
700 * that have been made.
701 */
702 oldmax = args->maxlen;
703 reservation = xfs_ag_resv_needed(args->pag, args->resv);
704 if (args->maxlen > args->pag->pagf_freeblks - reservation)
705 args->maxlen = args->pag->pagf_freeblks - reservation;
706 if (args->maxlen == 0) {
707 args->agbno = NULLAGBLOCK;
708 args->maxlen = oldmax;
709 return 0;
710 }
711
712 /*
713 * Branch to correct routine based on the type. 673 * Branch to correct routine based on the type.
714 */ 674 */
715 args->wasfromfl = 0; 675 args->wasfromfl = 0;
@@ -728,8 +688,6 @@ xfs_alloc_ag_vextent(
728 /* NOTREACHED */ 688 /* NOTREACHED */
729 } 689 }
730 690
731 args->maxlen = oldmax;
732
733 if (error || args->agbno == NULLAGBLOCK) 691 if (error || args->agbno == NULLAGBLOCK)
734 return error; 692 return error;
735 693
@@ -838,9 +796,6 @@ xfs_alloc_ag_vextent_exact(
838 args->len = XFS_AGBLOCK_MIN(tend, args->agbno + args->maxlen) 796 args->len = XFS_AGBLOCK_MIN(tend, args->agbno + args->maxlen)
839 - args->agbno; 797 - args->agbno;
840 xfs_alloc_fix_len(args); 798 xfs_alloc_fix_len(args);
841 if (!xfs_alloc_fix_minleft(args))
842 goto not_found;
843
844 ASSERT(args->agbno + args->len <= tend); 799 ASSERT(args->agbno + args->len <= tend);
845 800
846 /* 801 /*
@@ -1146,12 +1101,7 @@ restart:
1146 XFS_WANT_CORRUPTED_GOTO(args->mp, i == 1, error0); 1101 XFS_WANT_CORRUPTED_GOTO(args->mp, i == 1, error0);
1147 ASSERT(ltbno + ltlen <= be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_length)); 1102 ASSERT(ltbno + ltlen <= be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_length));
1148 args->len = blen; 1103 args->len = blen;
1149 if (!xfs_alloc_fix_minleft(args)) { 1104
1150 xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR);
1151 trace_xfs_alloc_near_nominleft(args);
1152 return 0;
1153 }
1154 blen = args->len;
1155 /* 1105 /*
1156 * We are allocating starting at bnew for blen blocks. 1106 * We are allocating starting at bnew for blen blocks.
1157 */ 1107 */
@@ -1343,12 +1293,6 @@ restart:
1343 */ 1293 */
1344 args->len = XFS_EXTLEN_MIN(ltlena, args->maxlen); 1294 args->len = XFS_EXTLEN_MIN(ltlena, args->maxlen);
1345 xfs_alloc_fix_len(args); 1295 xfs_alloc_fix_len(args);
1346 if (!xfs_alloc_fix_minleft(args)) {
1347 trace_xfs_alloc_near_nominleft(args);
1348 xfs_btree_del_cursor(bno_cur_lt, XFS_BTREE_NOERROR);
1349 xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR);
1350 return 0;
1351 }
1352 rlen = args->len; 1296 rlen = args->len;
1353 (void)xfs_alloc_compute_diff(args->agbno, rlen, args->alignment, 1297 (void)xfs_alloc_compute_diff(args->agbno, rlen, args->alignment,
1354 args->datatype, ltbnoa, ltlena, &ltnew); 1298 args->datatype, ltbnoa, ltlena, &ltnew);
@@ -1550,8 +1494,6 @@ restart:
1550 } 1494 }
1551 xfs_alloc_fix_len(args); 1495 xfs_alloc_fix_len(args);
1552 1496
1553 if (!xfs_alloc_fix_minleft(args))
1554 goto out_nominleft;
1555 rlen = args->len; 1497 rlen = args->len;
1556 XFS_WANT_CORRUPTED_GOTO(args->mp, rlen <= flen, error0); 1498 XFS_WANT_CORRUPTED_GOTO(args->mp, rlen <= flen, error0);
1557 /* 1499 /*
@@ -2070,10 +2012,20 @@ xfs_alloc_space_available(
2070 2012
2071 /* do we have enough free space remaining for the allocation? */ 2013 /* do we have enough free space remaining for the allocation? */
2072 available = (int)(pag->pagf_freeblks + pag->pagf_flcount - 2014 available = (int)(pag->pagf_freeblks + pag->pagf_flcount -
2073 reservation - min_free - args->total); 2015 reservation - min_free - args->minleft);
2074 if (available < (int)args->minleft || available <= 0) 2016 if (available < (int)args->total)
2075 return false; 2017 return false;
2076 2018
2019 /*
2020 * Clamp maxlen to the amount of free space available for the actual
2021 * extent allocation.
2022 */
2023 if (available < (int)args->maxlen && !(flags & XFS_ALLOC_FLAG_CHECK)) {
2024 args->maxlen = available;
2025 ASSERT(args->maxlen > 0);
2026 ASSERT(args->maxlen >= args->minlen);
2027 }
2028
2077 return true; 2029 return true;
2078} 2030}
2079 2031
@@ -2119,7 +2071,8 @@ xfs_alloc_fix_freelist(
2119 } 2071 }
2120 2072
2121 need = xfs_alloc_min_freelist(mp, pag); 2073 need = xfs_alloc_min_freelist(mp, pag);
2122 if (!xfs_alloc_space_available(args, need, flags)) 2074 if (!xfs_alloc_space_available(args, need, flags |
2075 XFS_ALLOC_FLAG_CHECK))
2123 goto out_agbp_relse; 2076 goto out_agbp_relse;
2124 2077
2125 /* 2078 /*
diff --git a/fs/xfs/libxfs/xfs_alloc.h b/fs/xfs/libxfs/xfs_alloc.h
index 7c404a6b0ae3..1d0f48a501a3 100644
--- a/fs/xfs/libxfs/xfs_alloc.h
+++ b/fs/xfs/libxfs/xfs_alloc.h
@@ -56,7 +56,7 @@ typedef unsigned int xfs_alloctype_t;
56#define XFS_ALLOC_FLAG_FREEING 0x00000002 /* indicate caller is freeing extents*/ 56#define XFS_ALLOC_FLAG_FREEING 0x00000002 /* indicate caller is freeing extents*/
57#define XFS_ALLOC_FLAG_NORMAP 0x00000004 /* don't modify the rmapbt */ 57#define XFS_ALLOC_FLAG_NORMAP 0x00000004 /* don't modify the rmapbt */
58#define XFS_ALLOC_FLAG_NOSHRINK 0x00000008 /* don't shrink the freelist */ 58#define XFS_ALLOC_FLAG_NOSHRINK 0x00000008 /* don't shrink the freelist */
59 59#define XFS_ALLOC_FLAG_CHECK 0x00000010 /* test only, don't modify args */
60 60
61/* 61/*
62 * Argument structure for xfs_alloc routines. 62 * Argument structure for xfs_alloc routines.