diff options
-rw-r--r-- | fs/xfs/libxfs/xfs_alloc.c | 81 | ||||
-rw-r--r-- | fs/xfs/libxfs/xfs_alloc.h | 2 |
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 | */ | ||
372 | STATIC int | ||
373 | xfs_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, <new); | 1298 | args->datatype, ltbnoa, ltlena, <new); |
@@ -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. |