diff options
-rw-r--r-- | fs/xfs/xfs_alloc.h | 16 | ||||
-rw-r--r-- | fs/xfs/xfs_bmap.c | 18 |
2 files changed, 26 insertions, 8 deletions
diff --git a/fs/xfs/xfs_alloc.h b/fs/xfs/xfs_alloc.h index 0ab56b32c7eb..d0b3bc72005b 100644 --- a/fs/xfs/xfs_alloc.h +++ b/fs/xfs/xfs_alloc.h | |||
@@ -75,6 +75,22 @@ typedef unsigned int xfs_alloctype_t; | |||
75 | #define XFS_ALLOC_SET_ASIDE(mp) (4 + ((mp)->m_sb.sb_agcount * 4)) | 75 | #define XFS_ALLOC_SET_ASIDE(mp) (4 + ((mp)->m_sb.sb_agcount * 4)) |
76 | 76 | ||
77 | /* | 77 | /* |
78 | * When deciding how much space to allocate out of an AG, we limit the | ||
79 | * allocation maximum size to the size the AG. However, we cannot use all the | ||
80 | * blocks in the AG - some are permanently used by metadata. These | ||
81 | * blocks are generally: | ||
82 | * - the AG superblock, AGF, AGI and AGFL | ||
83 | * - the AGF (bno and cnt) and AGI btree root blocks | ||
84 | * - 4 blocks on the AGFL according to XFS_ALLOC_SET_ASIDE() limits | ||
85 | * | ||
86 | * The AG headers are sector sized, so the amount of space they take up is | ||
87 | * dependent on filesystem geometry. The others are all single blocks. | ||
88 | */ | ||
89 | #define XFS_ALLOC_AG_MAX_USABLE(mp) \ | ||
90 | ((mp)->m_sb.sb_agblocks - XFS_BB_TO_FSB(mp, XFS_FSS_TO_BB(mp, 4)) - 7) | ||
91 | |||
92 | |||
93 | /* | ||
78 | * Argument structure for xfs_alloc routines. | 94 | * Argument structure for xfs_alloc routines. |
79 | * This is turned into a structure to avoid having 20 arguments passed | 95 | * This is turned into a structure to avoid having 20 arguments passed |
80 | * down several levels of the stack. | 96 | * down several levels of the stack. |
diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c index 4111cd3966c7..f3a3768189bb 100644 --- a/fs/xfs/xfs_bmap.c +++ b/fs/xfs/xfs_bmap.c | |||
@@ -2430,7 +2430,7 @@ xfs_bmap_btalloc_nullfb( | |||
2430 | startag = ag = 0; | 2430 | startag = ag = 0; |
2431 | 2431 | ||
2432 | pag = xfs_perag_get(mp, ag); | 2432 | pag = xfs_perag_get(mp, ag); |
2433 | while (*blen < ap->alen) { | 2433 | while (*blen < args->maxlen) { |
2434 | if (!pag->pagf_init) { | 2434 | if (!pag->pagf_init) { |
2435 | error = xfs_alloc_pagf_init(mp, args->tp, ag, | 2435 | error = xfs_alloc_pagf_init(mp, args->tp, ag, |
2436 | XFS_ALLOC_FLAG_TRYLOCK); | 2436 | XFS_ALLOC_FLAG_TRYLOCK); |
@@ -2452,7 +2452,7 @@ xfs_bmap_btalloc_nullfb( | |||
2452 | notinit = 1; | 2452 | notinit = 1; |
2453 | 2453 | ||
2454 | if (xfs_inode_is_filestream(ap->ip)) { | 2454 | if (xfs_inode_is_filestream(ap->ip)) { |
2455 | if (*blen >= ap->alen) | 2455 | if (*blen >= args->maxlen) |
2456 | break; | 2456 | break; |
2457 | 2457 | ||
2458 | if (ap->userdata) { | 2458 | if (ap->userdata) { |
@@ -2498,14 +2498,14 @@ xfs_bmap_btalloc_nullfb( | |||
2498 | * If the best seen length is less than the request | 2498 | * If the best seen length is less than the request |
2499 | * length, use the best as the minimum. | 2499 | * length, use the best as the minimum. |
2500 | */ | 2500 | */ |
2501 | else if (*blen < ap->alen) | 2501 | else if (*blen < args->maxlen) |
2502 | args->minlen = *blen; | 2502 | args->minlen = *blen; |
2503 | /* | 2503 | /* |
2504 | * Otherwise we've seen an extent as big as alen, | 2504 | * Otherwise we've seen an extent as big as maxlen, |
2505 | * use that as the minimum. | 2505 | * use that as the minimum. |
2506 | */ | 2506 | */ |
2507 | else | 2507 | else |
2508 | args->minlen = ap->alen; | 2508 | args->minlen = args->maxlen; |
2509 | 2509 | ||
2510 | /* | 2510 | /* |
2511 | * set the failure fallback case to look in the selected | 2511 | * set the failure fallback case to look in the selected |
@@ -2573,7 +2573,9 @@ xfs_bmap_btalloc( | |||
2573 | args.tp = ap->tp; | 2573 | args.tp = ap->tp; |
2574 | args.mp = mp; | 2574 | args.mp = mp; |
2575 | args.fsbno = ap->rval; | 2575 | args.fsbno = ap->rval; |
2576 | args.maxlen = MIN(ap->alen, mp->m_sb.sb_agblocks); | 2576 | |
2577 | /* Trim the allocation back to the maximum an AG can fit. */ | ||
2578 | args.maxlen = MIN(ap->alen, XFS_ALLOC_AG_MAX_USABLE(mp)); | ||
2577 | args.firstblock = ap->firstblock; | 2579 | args.firstblock = ap->firstblock; |
2578 | blen = 0; | 2580 | blen = 0; |
2579 | if (nullfb) { | 2581 | if (nullfb) { |
@@ -2621,7 +2623,7 @@ xfs_bmap_btalloc( | |||
2621 | /* | 2623 | /* |
2622 | * Adjust for alignment | 2624 | * Adjust for alignment |
2623 | */ | 2625 | */ |
2624 | if (blen > args.alignment && blen <= ap->alen) | 2626 | if (blen > args.alignment && blen <= args.maxlen) |
2625 | args.minlen = blen - args.alignment; | 2627 | args.minlen = blen - args.alignment; |
2626 | args.minalignslop = 0; | 2628 | args.minalignslop = 0; |
2627 | } else { | 2629 | } else { |
@@ -2640,7 +2642,7 @@ xfs_bmap_btalloc( | |||
2640 | * of minlen+alignment+slop doesn't go up | 2642 | * of minlen+alignment+slop doesn't go up |
2641 | * between the calls. | 2643 | * between the calls. |
2642 | */ | 2644 | */ |
2643 | if (blen > mp->m_dalign && blen <= ap->alen) | 2645 | if (blen > mp->m_dalign && blen <= args.maxlen) |
2644 | nextminlen = blen - mp->m_dalign; | 2646 | nextminlen = blen - mp->m_dalign; |
2645 | else | 2647 | else |
2646 | nextminlen = args.minlen; | 2648 | nextminlen = args.minlen; |