diff options
| author | Christoph Hellwig <hch@infradead.org> | 2008-10-30 16:57:51 +1100 | 
|---|---|---|
| committer | Lachlan McIlroy <lachlan@sgi.com> | 2008-10-30 16:57:51 +1100 | 
| commit | d4b3a4b7dd62f2e111d4d0afa9ef3f9b6cd955c0 (patch) | |
| tree | cd0b5a46d81fa9d9b0253c489f64ad698e3a0fa9 /fs/xfs/xfs_alloc_btree.c | |
| parent | 4b22a57188d87e873346b73c227607715be96399 (diff) | |
| download | olio-linux-3.10-d4b3a4b7dd62f2e111d4d0afa9ef3f9b6cd955c0.tar.xz olio-linux-3.10-d4b3a4b7dd62f2e111d4d0afa9ef3f9b6cd955c0.zip  | |
[XFS] move xfs_bmbt_killroot to common code
xfs_bmbt_killroot is a mostly generic implementation of moving from a real
block based root to an inode based root. So move it to xfs_btree.c where
it can use all the nice infrastructure there and make it pointer size
agnostic
The new name for it is xfs_btree_kill_iroot, following the old naming but
making it clear we're dealing with the root in inode case here, and to
avoid confusion with xfs_btree_new_root which is used for the not inode
rooted case. I've also added a comment describing what it does and why
it's named the way it is.
SGI-PV: 985583
SGI-Modid: xfs-linux-melb:xfs-kern:32203a
Signed-off-by: Christoph Hellwig <hch@infradead.org>
Signed-off-by: Lachlan McIlroy <lachlan@sgi.com>
Signed-off-by: Bill O'Donnell <billodo@sgi.com>
Signed-off-by: David Chinner <david@fromorbit.com>
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 818adca77fc..f124ddd91c0 100644 --- a/fs/xfs/xfs_alloc_btree.c +++ b/fs/xfs/xfs_alloc_btree.c @@ -834,6 +834,37 @@ xfs_allocbt_alloc_block(  	return 0;  } +STATIC int +xfs_allocbt_free_block( +	struct xfs_btree_cur	*cur, +	struct xfs_buf		*bp) +{ +	struct xfs_buf		*agbp = cur->bc_private.a.agbp; +	struct xfs_agf		*agf = XFS_BUF_TO_AGF(agbp); +	xfs_agblock_t		bno; +	int			error; + +	bno = XFS_DADDR_TO_AGBNO(cur->bc_mp, XFS_BUF_ADDR(bp)); +	error = xfs_alloc_put_freelist(cur->bc_tp, agbp, NULL, bno, 1); +	if (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, be32_to_cpu(agf->agf_seqno), bno, 1); +	xfs_trans_agbtree_delta(cur->bc_tp, -1); +	return 0; +} +  /*   * Update the longest extent in the AGF   */ @@ -1025,6 +1056,7 @@ static const struct xfs_btree_ops xfs_allocbt_ops = {  	.dup_cursor		= xfs_allocbt_dup_cursor,  	.set_root		= xfs_allocbt_set_root,  	.alloc_block		= xfs_allocbt_alloc_block, +	.free_block		= xfs_allocbt_free_block,  	.update_lastrec		= xfs_allocbt_update_lastrec,  	.get_maxrecs		= xfs_allocbt_get_maxrecs,  	.init_key_from_rec	= xfs_allocbt_init_key_from_rec,  |