diff options
Diffstat (limited to 'fs/xfs/xfs_alloc.c')
-rw-r--r-- | fs/xfs/xfs_alloc.c | 29 |
1 files changed, 23 insertions, 6 deletions
diff --git a/fs/xfs/xfs_alloc.c b/fs/xfs/xfs_alloc.c index 8558226281c4..22af489d3f34 100644 --- a/fs/xfs/xfs_alloc.c +++ b/fs/xfs/xfs_alloc.c | |||
@@ -1862,7 +1862,7 @@ xfs_alloc_fix_freelist( | |||
1862 | (pag->pagf_longest - delta) : | 1862 | (pag->pagf_longest - delta) : |
1863 | (pag->pagf_flcount > 0 || pag->pagf_longest > 0); | 1863 | (pag->pagf_flcount > 0 || pag->pagf_longest > 0); |
1864 | if (args->minlen + args->alignment + args->minalignslop - 1 > longest || | 1864 | if (args->minlen + args->alignment + args->minalignslop - 1 > longest || |
1865 | (args->minleft && | 1865 | (!(flags & XFS_ALLOC_FLAG_FREEING) && |
1866 | (int)(pag->pagf_freeblks + pag->pagf_flcount - | 1866 | (int)(pag->pagf_freeblks + pag->pagf_flcount - |
1867 | need - args->total) < | 1867 | need - args->total) < |
1868 | (int)args->minleft)) { | 1868 | (int)args->minleft)) { |
@@ -1898,7 +1898,7 @@ xfs_alloc_fix_freelist( | |||
1898 | longest = (longest > delta) ? (longest - delta) : | 1898 | longest = (longest > delta) ? (longest - delta) : |
1899 | (be32_to_cpu(agf->agf_flcount) > 0 || longest > 0); | 1899 | (be32_to_cpu(agf->agf_flcount) > 0 || longest > 0); |
1900 | if (args->minlen + args->alignment + args->minalignslop - 1 > longest || | 1900 | if (args->minlen + args->alignment + args->minalignslop - 1 > longest || |
1901 | (args->minleft && | 1901 | (!(flags & XFS_ALLOC_FLAG_FREEING) && |
1902 | (int)(be32_to_cpu(agf->agf_freeblks) + | 1902 | (int)(be32_to_cpu(agf->agf_freeblks) + |
1903 | be32_to_cpu(agf->agf_flcount) - need - args->total) < | 1903 | be32_to_cpu(agf->agf_flcount) - need - args->total) < |
1904 | (int)args->minleft)) { | 1904 | (int)args->minleft)) { |
@@ -1951,8 +1951,14 @@ xfs_alloc_fix_freelist( | |||
1951 | * the restrictions correctly. Can happen for free calls | 1951 | * the restrictions correctly. Can happen for free calls |
1952 | * on a completely full ag. | 1952 | * on a completely full ag. |
1953 | */ | 1953 | */ |
1954 | if (targs.agbno == NULLAGBLOCK) | 1954 | if (targs.agbno == NULLAGBLOCK) { |
1955 | if (!(flags & XFS_ALLOC_FLAG_FREEING)) { | ||
1956 | xfs_trans_brelse(tp, agflbp); | ||
1957 | args->agbp = NULL; | ||
1958 | return 0; | ||
1959 | } | ||
1955 | break; | 1960 | break; |
1961 | } | ||
1956 | /* | 1962 | /* |
1957 | * Put each allocated block on the list. | 1963 | * Put each allocated block on the list. |
1958 | */ | 1964 | */ |
@@ -2360,8 +2366,19 @@ xfs_alloc_vextent( | |||
2360 | if (args->agno == sagno && | 2366 | if (args->agno == sagno && |
2361 | type == XFS_ALLOCTYPE_START_BNO) | 2367 | type == XFS_ALLOCTYPE_START_BNO) |
2362 | args->type = XFS_ALLOCTYPE_THIS_AG; | 2368 | args->type = XFS_ALLOCTYPE_THIS_AG; |
2363 | if (++(args->agno) == mp->m_sb.sb_agcount) | 2369 | /* |
2364 | args->agno = 0; | 2370 | * For the first allocation, we can try any AG to get |
2371 | * space. However, if we already have allocated a | ||
2372 | * block, we don't want to try AGs whose number is below | ||
2373 | * sagno. Otherwise, we may end up with out-of-order | ||
2374 | * locking of AGF, which might cause deadlock. | ||
2375 | */ | ||
2376 | if (++(args->agno) == mp->m_sb.sb_agcount) { | ||
2377 | if (args->firstblock != NULLFSBLOCK) | ||
2378 | args->agno = sagno; | ||
2379 | else | ||
2380 | args->agno = 0; | ||
2381 | } | ||
2365 | /* | 2382 | /* |
2366 | * Reached the starting a.g., must either be done | 2383 | * Reached the starting a.g., must either be done |
2367 | * or switch to non-trylock mode. | 2384 | * or switch to non-trylock mode. |
@@ -2443,7 +2460,7 @@ xfs_free_extent( | |||
2443 | args.minlen = args.minleft = args.minalignslop = 0; | 2460 | args.minlen = args.minleft = args.minalignslop = 0; |
2444 | down_read(&args.mp->m_peraglock); | 2461 | down_read(&args.mp->m_peraglock); |
2445 | args.pag = &args.mp->m_perag[args.agno]; | 2462 | args.pag = &args.mp->m_perag[args.agno]; |
2446 | if ((error = xfs_alloc_fix_freelist(&args, 0))) | 2463 | if ((error = xfs_alloc_fix_freelist(&args, XFS_ALLOC_FLAG_FREEING))) |
2447 | goto error0; | 2464 | goto error0; |
2448 | #ifdef DEBUG | 2465 | #ifdef DEBUG |
2449 | ASSERT(args.agbp != NULL); | 2466 | ASSERT(args.agbp != NULL); |