aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_alloc.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/xfs_alloc.c')
-rw-r--r--fs/xfs/xfs_alloc.c31
1 files changed, 4 insertions, 27 deletions
diff --git a/fs/xfs/xfs_alloc.c b/fs/xfs/xfs_alloc.c
index 27d64d752eab..37c4952c2f53 100644
--- a/fs/xfs/xfs_alloc.c
+++ b/fs/xfs/xfs_alloc.c
@@ -1326,6 +1326,8 @@ xfs_alloc_ag_vextent_small(
1326 if (error) 1326 if (error)
1327 goto error0; 1327 goto error0;
1328 if (fbno != NULLAGBLOCK) { 1328 if (fbno != NULLAGBLOCK) {
1329 if (xfs_alloc_busy_search(args->mp, args->agno, fbno, 1))
1330 xfs_trans_set_sync(args->tp);
1329 if (args->userdata) { 1331 if (args->userdata) {
1330 xfs_buf_t *bp; 1332 xfs_buf_t *bp;
1331 1333
@@ -1617,18 +1619,6 @@ xfs_free_ag_extent(
1617 1619
1618 trace_xfs_free_extent(mp, agno, bno, len, isfl, haveleft, haveright); 1620 trace_xfs_free_extent(mp, agno, bno, len, isfl, haveleft, haveright);
1619 1621
1620 /*
1621 * Since blocks move to the free list without the coordination
1622 * used in xfs_bmap_finish, we can't allow block to be available
1623 * for reallocation and non-transaction writing (user data)
1624 * until we know that the transaction that moved it to the free
1625 * list is permanently on disk. We track the blocks by declaring
1626 * these blocks as "busy"; the busy list is maintained on a per-ag
1627 * basis and each transaction records which entries should be removed
1628 * when the iclog commits to disk. If a busy block is allocated,
1629 * the iclog is pushed up to the LSN that freed the block.
1630 */
1631 xfs_alloc_busy_insert(tp, agno, bno, len);
1632 return 0; 1622 return 0;
1633 1623
1634 error0: 1624 error0:
@@ -1923,21 +1913,6 @@ xfs_alloc_get_freelist(
1923 xfs_alloc_log_agf(tp, agbp, logflags); 1913 xfs_alloc_log_agf(tp, agbp, logflags);
1924 *bnop = bno; 1914 *bnop = bno;
1925 1915
1926 /*
1927 * As blocks are freed, they are added to the per-ag busy list and
1928 * remain there until the freeing transaction is committed to disk.
1929 * Now that we have allocated blocks, this list must be searched to see
1930 * if a block is being reused. If one is, then the freeing transaction
1931 * must be pushed to disk before this transaction.
1932 *
1933 * We do this by setting the current transaction to a sync transaction
1934 * which guarantees that the freeing transaction is on disk before this
1935 * transaction. This is done instead of a synchronous log force here so
1936 * that we don't sit and wait with the AGF locked in the transaction
1937 * during the log force.
1938 */
1939 if (xfs_alloc_busy_search(mp, be32_to_cpu(agf->agf_seqno), bno, 1))
1940 xfs_trans_set_sync(tp);
1941 return 0; 1916 return 0;
1942} 1917}
1943 1918
@@ -2423,6 +2398,8 @@ xfs_free_extent(
2423 } 2398 }
2424 2399
2425 error = xfs_free_ag_extent(tp, args.agbp, args.agno, args.agbno, len, 0); 2400 error = xfs_free_ag_extent(tp, args.agbp, args.agno, args.agbno, len, 0);
2401 if (!error)
2402 xfs_alloc_busy_insert(tp, args.agno, args.agbno, len);
2426error0: 2403error0:
2427 xfs_perag_put(args.pag); 2404 xfs_perag_put(args.pag);
2428 return error; 2405 return error;