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