diff options
Diffstat (limited to 'fs/xfs/xfs_alloc_btree.c')
-rw-r--r-- | fs/xfs/xfs_alloc_btree.c | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/fs/xfs/xfs_alloc_btree.c b/fs/xfs/xfs_alloc_btree.c index 818adca77fc6..f124ddd91c08 100644 --- a/fs/xfs/xfs_alloc_btree.c +++ b/fs/xfs/xfs_alloc_btree.c | |||
@@ -834,6 +834,37 @@ xfs_allocbt_alloc_block( | |||
834 | return 0; | 834 | return 0; |
835 | } | 835 | } |
836 | 836 | ||
837 | STATIC int | ||
838 | xfs_allocbt_free_block( | ||
839 | struct xfs_btree_cur *cur, | ||
840 | struct xfs_buf *bp) | ||
841 | { | ||
842 | struct xfs_buf *agbp = cur->bc_private.a.agbp; | ||
843 | struct xfs_agf *agf = XFS_BUF_TO_AGF(agbp); | ||
844 | xfs_agblock_t bno; | ||
845 | int error; | ||
846 | |||
847 | bno = XFS_DADDR_TO_AGBNO(cur->bc_mp, XFS_BUF_ADDR(bp)); | ||
848 | error = xfs_alloc_put_freelist(cur->bc_tp, agbp, NULL, bno, 1); | ||
849 | if (error) | ||
850 | return error; | ||
851 | |||
852 | /* | ||
853 | * Since blocks move to the free list without the coordination used in | ||
854 | * xfs_bmap_finish, we can't allow block to be available for | ||
855 | * reallocation and non-transaction writing (user data) until we know | ||
856 | * that the transaction that moved it to the free list is permanently | ||
857 | * on disk. We track the blocks by declaring these blocks as "busy"; | ||
858 | * the busy list is maintained on a per-ag basis and each transaction | ||
859 | * records which entries should be removed when the iclog commits to | ||
860 | * disk. If a busy block is allocated, the iclog is pushed up to the | ||
861 | * LSN that freed the block. | ||
862 | */ | ||
863 | xfs_alloc_mark_busy(cur->bc_tp, be32_to_cpu(agf->agf_seqno), bno, 1); | ||
864 | xfs_trans_agbtree_delta(cur->bc_tp, -1); | ||
865 | return 0; | ||
866 | } | ||
867 | |||
837 | /* | 868 | /* |
838 | * Update the longest extent in the AGF | 869 | * Update the longest extent in the AGF |
839 | */ | 870 | */ |
@@ -1025,6 +1056,7 @@ static const struct xfs_btree_ops xfs_allocbt_ops = { | |||
1025 | .dup_cursor = xfs_allocbt_dup_cursor, | 1056 | .dup_cursor = xfs_allocbt_dup_cursor, |
1026 | .set_root = xfs_allocbt_set_root, | 1057 | .set_root = xfs_allocbt_set_root, |
1027 | .alloc_block = xfs_allocbt_alloc_block, | 1058 | .alloc_block = xfs_allocbt_alloc_block, |
1059 | .free_block = xfs_allocbt_free_block, | ||
1028 | .update_lastrec = xfs_allocbt_update_lastrec, | 1060 | .update_lastrec = xfs_allocbt_update_lastrec, |
1029 | .get_maxrecs = xfs_allocbt_get_maxrecs, | 1061 | .get_maxrecs = xfs_allocbt_get_maxrecs, |
1030 | .init_key_from_rec = xfs_allocbt_init_key_from_rec, | 1062 | .init_key_from_rec = xfs_allocbt_init_key_from_rec, |