aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/libxfs/xfs_alloc.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/libxfs/xfs_alloc.c')
-rw-r--r--fs/xfs/libxfs/xfs_alloc.c115
1 files changed, 28 insertions, 87 deletions
diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c
index 5050056a0b06..9f06a211e157 100644
--- a/fs/xfs/libxfs/xfs_alloc.c
+++ b/fs/xfs/libxfs/xfs_alloc.c
@@ -95,10 +95,7 @@ unsigned int
95xfs_alloc_set_aside( 95xfs_alloc_set_aside(
96 struct xfs_mount *mp) 96 struct xfs_mount *mp)
97{ 97{
98 unsigned int blocks; 98 return mp->m_sb.sb_agcount * (XFS_ALLOC_AGFL_RESERVE + 4);
99
100 blocks = 4 + (mp->m_sb.sb_agcount * XFS_ALLOC_AGFL_RESERVE);
101 return blocks;
102} 99}
103 100
104/* 101/*
@@ -365,36 +362,12 @@ xfs_alloc_fix_len(
365 return; 362 return;
366 ASSERT(rlen >= args->minlen && rlen <= args->maxlen); 363 ASSERT(rlen >= args->minlen && rlen <= args->maxlen);
367 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);
368 args->len = rlen; 367 args->len = rlen;
369} 368}
370 369
371/* 370/*
372 * Fix up length if there is too little space left in the a.g.
373 * Return 1 if ok, 0 if too little, should give up.
374 */
375STATIC int
376xfs_alloc_fix_minleft(
377 xfs_alloc_arg_t *args) /* allocation argument structure */
378{
379 xfs_agf_t *agf; /* a.g. freelist header */
380 int diff; /* free space difference */
381
382 if (args->minleft == 0)
383 return 1;
384 agf = XFS_BUF_TO_AGF(args->agbp);
385 diff = be32_to_cpu(agf->agf_freeblks)
386 - args->len - args->minleft;
387 if (diff >= 0)
388 return 1;
389 args->len += diff; /* shrink the allocated space */
390 /* casts to (int) catch length underflows */
391 if ((int)args->len >= (int)args->minlen)
392 return 1;
393 args->agbno = NULLAGBLOCK;
394 return 0;
395}
396
397/*
398 * Update the two btrees, logically removing from freespace the extent 371 * Update the two btrees, logically removing from freespace the extent
399 * starting at rbno, rlen blocks. The extent is contained within the 372 * starting at rbno, rlen blocks. The extent is contained within the
400 * actual (current) free extent fbno for flen blocks. 373 * actual (current) free extent fbno for flen blocks.
@@ -689,8 +662,6 @@ xfs_alloc_ag_vextent(
689 xfs_alloc_arg_t *args) /* argument structure for allocation */ 662 xfs_alloc_arg_t *args) /* argument structure for allocation */
690{ 663{
691 int error=0; 664 int error=0;
692 xfs_extlen_t reservation;
693 xfs_extlen_t oldmax;
694 665
695 ASSERT(args->minlen > 0); 666 ASSERT(args->minlen > 0);
696 ASSERT(args->maxlen > 0); 667 ASSERT(args->maxlen > 0);
@@ -699,20 +670,6 @@ xfs_alloc_ag_vextent(
699 ASSERT(args->alignment > 0); 670 ASSERT(args->alignment > 0);
700 671
701 /* 672 /*
702 * Clamp maxlen to the amount of free space minus any reservations
703 * that have been made.
704 */
705 oldmax = args->maxlen;
706 reservation = xfs_ag_resv_needed(args->pag, args->resv);
707 if (args->maxlen > args->pag->pagf_freeblks - reservation)
708 args->maxlen = args->pag->pagf_freeblks - reservation;
709 if (args->maxlen == 0) {
710 args->agbno = NULLAGBLOCK;
711 args->maxlen = oldmax;
712 return 0;
713 }
714
715 /*
716 * Branch to correct routine based on the type. 673 * Branch to correct routine based on the type.
717 */ 674 */
718 args->wasfromfl = 0; 675 args->wasfromfl = 0;
@@ -731,8 +688,6 @@ xfs_alloc_ag_vextent(
731 /* NOTREACHED */ 688 /* NOTREACHED */
732 } 689 }
733 690
734 args->maxlen = oldmax;
735
736 if (error || args->agbno == NULLAGBLOCK) 691 if (error || args->agbno == NULLAGBLOCK)
737 return error; 692 return error;
738 693
@@ -841,9 +796,6 @@ xfs_alloc_ag_vextent_exact(
841 args->len = XFS_AGBLOCK_MIN(tend, args->agbno + args->maxlen) 796 args->len = XFS_AGBLOCK_MIN(tend, args->agbno + args->maxlen)
842 - args->agbno; 797 - args->agbno;
843 xfs_alloc_fix_len(args); 798 xfs_alloc_fix_len(args);
844 if (!xfs_alloc_fix_minleft(args))
845 goto not_found;
846
847 ASSERT(args->agbno + args->len <= tend); 799 ASSERT(args->agbno + args->len <= tend);
848 800
849 /* 801 /*
@@ -1149,12 +1101,7 @@ restart:
1149 XFS_WANT_CORRUPTED_GOTO(args->mp, i == 1, error0); 1101 XFS_WANT_CORRUPTED_GOTO(args->mp, i == 1, error0);
1150 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));
1151 args->len = blen; 1103 args->len = blen;
1152 if (!xfs_alloc_fix_minleft(args)) { 1104
1153 xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR);
1154 trace_xfs_alloc_near_nominleft(args);
1155 return 0;
1156 }
1157 blen = args->len;
1158 /* 1105 /*
1159 * We are allocating starting at bnew for blen blocks. 1106 * We are allocating starting at bnew for blen blocks.
1160 */ 1107 */
@@ -1346,12 +1293,6 @@ restart:
1346 */ 1293 */
1347 args->len = XFS_EXTLEN_MIN(ltlena, args->maxlen); 1294 args->len = XFS_EXTLEN_MIN(ltlena, args->maxlen);
1348 xfs_alloc_fix_len(args); 1295 xfs_alloc_fix_len(args);
1349 if (!xfs_alloc_fix_minleft(args)) {
1350 trace_xfs_alloc_near_nominleft(args);
1351 xfs_btree_del_cursor(bno_cur_lt, XFS_BTREE_NOERROR);
1352 xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR);
1353 return 0;
1354 }
1355 rlen = args->len; 1296 rlen = args->len;
1356 (void)xfs_alloc_compute_diff(args->agbno, rlen, args->alignment, 1297 (void)xfs_alloc_compute_diff(args->agbno, rlen, args->alignment,
1357 args->datatype, ltbnoa, ltlena, &ltnew); 1298 args->datatype, ltbnoa, ltlena, &ltnew);
@@ -1553,8 +1494,6 @@ restart:
1553 } 1494 }
1554 xfs_alloc_fix_len(args); 1495 xfs_alloc_fix_len(args);
1555 1496
1556 if (!xfs_alloc_fix_minleft(args))
1557 goto out_nominleft;
1558 rlen = args->len; 1497 rlen = args->len;
1559 XFS_WANT_CORRUPTED_GOTO(args->mp, rlen <= flen, error0); 1498 XFS_WANT_CORRUPTED_GOTO(args->mp, rlen <= flen, error0);
1560 /* 1499 /*
@@ -2056,7 +1995,7 @@ xfs_alloc_space_available(
2056 int flags) 1995 int flags)
2057{ 1996{
2058 struct xfs_perag *pag = args->pag; 1997 struct xfs_perag *pag = args->pag;
2059 xfs_extlen_t longest; 1998 xfs_extlen_t alloc_len, longest;
2060 xfs_extlen_t reservation; /* blocks that are still reserved */ 1999 xfs_extlen_t reservation; /* blocks that are still reserved */
2061 int available; 2000 int available;
2062 2001
@@ -2066,17 +2005,28 @@ xfs_alloc_space_available(
2066 reservation = xfs_ag_resv_needed(pag, args->resv); 2005 reservation = xfs_ag_resv_needed(pag, args->resv);
2067 2006
2068 /* do we have enough contiguous free space for the allocation? */ 2007 /* do we have enough contiguous free space for the allocation? */
2008 alloc_len = args->minlen + (args->alignment - 1) + args->minalignslop;
2069 longest = xfs_alloc_longest_free_extent(args->mp, pag, min_free, 2009 longest = xfs_alloc_longest_free_extent(args->mp, pag, min_free,
2070 reservation); 2010 reservation);
2071 if ((args->minlen + args->alignment + args->minalignslop - 1) > longest) 2011 if (longest < alloc_len)
2072 return false; 2012 return false;
2073 2013
2074 /* do we have enough free space remaining for the allocation? */ 2014 /* do we have enough free space remaining for the allocation? */
2075 available = (int)(pag->pagf_freeblks + pag->pagf_flcount - 2015 available = (int)(pag->pagf_freeblks + pag->pagf_flcount -
2076 reservation - min_free - args->total); 2016 reservation - min_free - args->minleft);
2077 if (available < (int)args->minleft || available <= 0) 2017 if (available < (int)max(args->total, alloc_len))
2078 return false; 2018 return false;
2079 2019
2020 /*
2021 * Clamp maxlen to the amount of free space available for the actual
2022 * extent allocation.
2023 */
2024 if (available < (int)args->maxlen && !(flags & XFS_ALLOC_FLAG_CHECK)) {
2025 args->maxlen = available;
2026 ASSERT(args->maxlen > 0);
2027 ASSERT(args->maxlen >= args->minlen);
2028 }
2029
2080 return true; 2030 return true;
2081} 2031}
2082 2032
@@ -2122,7 +2072,8 @@ xfs_alloc_fix_freelist(
2122 } 2072 }
2123 2073
2124 need = xfs_alloc_min_freelist(mp, pag); 2074 need = xfs_alloc_min_freelist(mp, pag);
2125 if (!xfs_alloc_space_available(args, need, flags)) 2075 if (!xfs_alloc_space_available(args, need, flags |
2076 XFS_ALLOC_FLAG_CHECK))
2126 goto out_agbp_relse; 2077 goto out_agbp_relse;
2127 2078
2128 /* 2079 /*
@@ -2638,12 +2589,10 @@ xfs_alloc_vextent(
2638 xfs_agblock_t agsize; /* allocation group size */ 2589 xfs_agblock_t agsize; /* allocation group size */
2639 int error; 2590 int error;
2640 int flags; /* XFS_ALLOC_FLAG_... locking flags */ 2591 int flags; /* XFS_ALLOC_FLAG_... locking flags */
2641 xfs_extlen_t minleft;/* minimum left value, temp copy */
2642 xfs_mount_t *mp; /* mount structure pointer */ 2592 xfs_mount_t *mp; /* mount structure pointer */
2643 xfs_agnumber_t sagno; /* starting allocation group number */ 2593 xfs_agnumber_t sagno; /* starting allocation group number */
2644 xfs_alloctype_t type; /* input allocation type */ 2594 xfs_alloctype_t type; /* input allocation type */
2645 int bump_rotor = 0; 2595 int bump_rotor = 0;
2646 int no_min = 0;
2647 xfs_agnumber_t rotorstep = xfs_rotorstep; /* inode32 agf stepper */ 2596 xfs_agnumber_t rotorstep = xfs_rotorstep; /* inode32 agf stepper */
2648 2597
2649 mp = args->mp; 2598 mp = args->mp;
@@ -2672,7 +2621,6 @@ xfs_alloc_vextent(
2672 trace_xfs_alloc_vextent_badargs(args); 2621 trace_xfs_alloc_vextent_badargs(args);
2673 return 0; 2622 return 0;
2674 } 2623 }
2675 minleft = args->minleft;
2676 2624
2677 switch (type) { 2625 switch (type) {
2678 case XFS_ALLOCTYPE_THIS_AG: 2626 case XFS_ALLOCTYPE_THIS_AG:
@@ -2683,9 +2631,7 @@ xfs_alloc_vextent(
2683 */ 2631 */
2684 args->agno = XFS_FSB_TO_AGNO(mp, args->fsbno); 2632 args->agno = XFS_FSB_TO_AGNO(mp, args->fsbno);
2685 args->pag = xfs_perag_get(mp, args->agno); 2633 args->pag = xfs_perag_get(mp, args->agno);
2686 args->minleft = 0;
2687 error = xfs_alloc_fix_freelist(args, 0); 2634 error = xfs_alloc_fix_freelist(args, 0);
2688 args->minleft = minleft;
2689 if (error) { 2635 if (error) {
2690 trace_xfs_alloc_vextent_nofix(args); 2636 trace_xfs_alloc_vextent_nofix(args);
2691 goto error0; 2637 goto error0;
@@ -2750,9 +2696,7 @@ xfs_alloc_vextent(
2750 */ 2696 */
2751 for (;;) { 2697 for (;;) {
2752 args->pag = xfs_perag_get(mp, args->agno); 2698 args->pag = xfs_perag_get(mp, args->agno);
2753 if (no_min) args->minleft = 0;
2754 error = xfs_alloc_fix_freelist(args, flags); 2699 error = xfs_alloc_fix_freelist(args, flags);
2755 args->minleft = minleft;
2756 if (error) { 2700 if (error) {
2757 trace_xfs_alloc_vextent_nofix(args); 2701 trace_xfs_alloc_vextent_nofix(args);
2758 goto error0; 2702 goto error0;
@@ -2792,20 +2736,17 @@ xfs_alloc_vextent(
2792 * or switch to non-trylock mode. 2736 * or switch to non-trylock mode.
2793 */ 2737 */
2794 if (args->agno == sagno) { 2738 if (args->agno == sagno) {
2795 if (no_min == 1) { 2739 if (flags == 0) {
2796 args->agbno = NULLAGBLOCK; 2740 args->agbno = NULLAGBLOCK;
2797 trace_xfs_alloc_vextent_allfailed(args); 2741 trace_xfs_alloc_vextent_allfailed(args);
2798 break; 2742 break;
2799 } 2743 }
2800 if (flags == 0) { 2744
2801 no_min = 1; 2745 flags = 0;
2802 } else { 2746 if (type == XFS_ALLOCTYPE_START_BNO) {
2803 flags = 0; 2747 args->agbno = XFS_FSB_TO_AGBNO(mp,
2804 if (type == XFS_ALLOCTYPE_START_BNO) { 2748 args->fsbno);
2805 args->agbno = XFS_FSB_TO_AGBNO(mp, 2749 args->type = XFS_ALLOCTYPE_NEAR_BNO;
2806 args->fsbno);
2807 args->type = XFS_ALLOCTYPE_NEAR_BNO;
2808 }
2809 } 2750 }
2810 } 2751 }
2811 xfs_perag_put(args->pag); 2752 xfs_perag_put(args->pag);