Commit 4b2892ba authored by Stephen Lord's avatar Stephen Lord

XFS: busylist fixups

xfs_alloc_put_freelist marks the blocks it gets as "busy".  However, this
function is used in two different ways:
   
  1.  xfs_alloc_fix_freelist calls xfs_alloc_put_freelist to add new
  blocks to the freelist (that is, blocks it allocated with
  xfs_alloc_ag_vextent).
   
  2.  xfs_alloc_delrec calls xfs_alloc_put_freelist to free deleted
  b+tree blocks.  
   
In case 1, the blocks should not be on the busy list; in case 2, they
should.

Modid: 2.5.x-xfs:slinx:129987a
parent 9beb225e
...@@ -1768,18 +1768,6 @@ xfs_free_ag_extent( ...@@ -1768,18 +1768,6 @@ xfs_free_ag_extent(
(haveright ? "right" : "none"), (haveright ? "right" : "none"),
agno, bno, len, isfl); agno, bno, len, isfl);
/*
* Since blocks move to the free list without the coordination
* used in xfs_bmap_finish, we can't allow block to be available
* for reallocation and non-transaction writing (user data)
* until we know that the transaction that moved it to the free
* list is permanently on disk. We track the blocks by declaring
* these blocks as "busy"; the busy list is maintained on a per-ag
* basis and each transaction records which entries should be removed
* when the iclog commits to disk. If a busy block is allocated,
* the iclog is pushed up to the LSN that freed the block.
*/
xfs_alloc_mark_busy(tp, agno, bno, len);
return 0; return 0;
error0: error0:
......
...@@ -223,6 +223,22 @@ xfs_alloc_delrec( ...@@ -223,6 +223,22 @@ xfs_alloc_delrec(
if ((error = xfs_alloc_put_freelist(cur->bc_tp, if ((error = xfs_alloc_put_freelist(cur->bc_tp,
cur->bc_private.a.agbp, NULL, bno))) cur->bc_private.a.agbp, NULL, bno)))
return error; return error;
/*
* Since blocks move to the free list without the
* coordination used in xfs_bmap_finish, we can't allow
* block to be available for reallocation and
* non-transaction writing (user data) until we know
* that the transaction that moved it to the free list
* is permanently on disk. We track the blocks by
* declaring these blocks as "busy"; the busy list is
* maintained on a per-ag basis and each transaction
* records which entries should be removed when the
* iclog commits to disk. If a busy block is
* allocated, the iclog is pushed up to the LSN
* that freed the block.
*/
xfs_alloc_mark_busy(cur->bc_tp, agf->agf_seqno, bno, 1);
xfs_trans_agbtree_delta(cur->bc_tp, -1); xfs_trans_agbtree_delta(cur->bc_tp, -1);
xfs_alloc_log_agf(cur->bc_tp, cur->bc_private.a.agbp, xfs_alloc_log_agf(cur->bc_tp, cur->bc_private.a.agbp,
XFS_AGF_ROOTS | XFS_AGF_LEVELS); XFS_AGF_ROOTS | XFS_AGF_LEVELS);
...@@ -528,6 +544,20 @@ xfs_alloc_delrec( ...@@ -528,6 +544,20 @@ xfs_alloc_delrec(
if ((error = xfs_alloc_put_freelist(cur->bc_tp, cur->bc_private.a.agbp, if ((error = xfs_alloc_put_freelist(cur->bc_tp, cur->bc_private.a.agbp,
NULL, rbno))) NULL, rbno)))
return error; return error;
/*
* Since blocks move to the free list without the coordination
* used in xfs_bmap_finish, we can't allow block to be available
* for reallocation and non-transaction writing (user data)
* until we know that the transaction that moved it to the free
* list is permanently on disk. We track the blocks by declaring
* these blocks as "busy"; the busy list is maintained on a
* per-ag basis and each transaction records which entries
* should be removed when the iclog commits to disk. If a
* busy block is allocated, the iclog is pushed up to the
* LSN that freed the block.
*/
xfs_alloc_mark_busy(cur->bc_tp, agf->agf_seqno, bno, 1);
xfs_trans_agbtree_delta(cur->bc_tp, -1); xfs_trans_agbtree_delta(cur->bc_tp, -1);
/* /*
* Adjust the current level's cursor so that we're left referring * Adjust the current level's cursor so that we're left referring
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment