aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@infradead.org>2011-04-24 15:06:14 -0400
committerAlex Elder <aelder@sgi.com>2011-04-28 14:17:56 -0400
commita870acd9b2671de56514a430edfa7867823c31c9 (patch)
treee288e41227c35c251a675e4901f0be35e0c26aa1 /fs
parent3eff1268994f72266b660782e87f215720c29639 (diff)
xfs: optimize AGFL refills
While we need to make sure we do not reuse busy extents, there is no need to force out busy extents when moving them between the AGFL and the freespace btree as we still take care of that when doing the real allocation. To avoid the log force when just moving extents from the different free space tracking structures, move the busy search out of xfs_alloc_get_freelist into the callers that need it, and move the busy list insert from xfs_free_ag_extent which is used both by AGFL refills and real allocation to xfs_free_extent, which is only used by the latter. Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Alex Elder <aelder@sgi.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/xfs/xfs_alloc.c31
-rw-r--r--fs/xfs/xfs_alloc_btree.c2
2 files changed, 6 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;
diff --git a/fs/xfs/xfs_alloc_btree.c b/fs/xfs/xfs_alloc_btree.c
index 3916925e2584..bcfe92f47edd 100644
--- a/fs/xfs/xfs_alloc_btree.c
+++ b/fs/xfs/xfs_alloc_btree.c
@@ -94,6 +94,8 @@ xfs_allocbt_alloc_block(
94 *stat = 0; 94 *stat = 0;
95 return 0; 95 return 0;
96 } 96 }
97 if (xfs_alloc_busy_search(cur->bc_mp, cur->bc_private.a.agno, bno, 1))
98 xfs_trans_set_sync(cur->bc_tp);
97 99
98 xfs_trans_agbtree_delta(cur->bc_tp, 1); 100 xfs_trans_agbtree_delta(cur->bc_tp, 1);
99 new->s = cpu_to_be32(bno); 101 new->s = cpu_to_be32(bno);