diff options
Diffstat (limited to 'fs/xfs/xfs_dir2_node.c')
| -rw-r--r-- | fs/xfs/xfs_dir2_node.c | 494 | 
1 files changed, 230 insertions, 264 deletions
diff --git a/fs/xfs/xfs_dir2_node.c b/fs/xfs/xfs_dir2_node.c index 4c3dba7ffb7..da43d304fca 100644 --- a/fs/xfs/xfs_dir2_node.c +++ b/fs/xfs/xfs_dir2_node.c @@ -18,22 +18,21 @@   */  #include "xfs.h"  #include "xfs_fs.h" -#include "xfs_types.h" -#include "xfs_log.h" -#include "xfs_trans.h" +#include "xfs_format.h" +#include "xfs_log_format.h" +#include "xfs_trans_resv.h"  #include "xfs_sb.h"  #include "xfs_ag.h"  #include "xfs_mount.h" +#include "xfs_da_format.h"  #include "xfs_da_btree.h" -#include "xfs_bmap_btree.h" -#include "xfs_dinode.h"  #include "xfs_inode.h"  #include "xfs_bmap.h" -#include "xfs_dir2_format.h"  #include "xfs_dir2.h"  #include "xfs_dir2_priv.h"  #include "xfs_error.h"  #include "xfs_trace.h" +#include "xfs_trans.h"  #include "xfs_buf_item.h"  #include "xfs_cksum.h" @@ -55,21 +54,21 @@ static int xfs_dir2_node_addname_int(xfs_da_args_t *args,   * Check internal consistency of a leafn block.   */  #ifdef DEBUG -#define	xfs_dir3_leaf_check(mp, bp) \ +#define	xfs_dir3_leaf_check(dp, bp) \  do { \ -	if (!xfs_dir3_leafn_check((mp), (bp))) \ +	if (!xfs_dir3_leafn_check((dp), (bp))) \  		ASSERT(0); \  } while (0);  static bool  xfs_dir3_leafn_check( -	struct xfs_mount	*mp, +	struct xfs_inode	*dp,  	struct xfs_buf		*bp)  {  	struct xfs_dir2_leaf	*leaf = bp->b_addr;  	struct xfs_dir3_icleaf_hdr leafhdr; -	xfs_dir3_leaf_hdr_from_disk(&leafhdr, leaf); +	dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf);  	if (leafhdr.magic == XFS_DIR3_LEAFN_MAGIC) {  		struct xfs_dir3_leaf_hdr *leaf3 = bp->b_addr; @@ -78,10 +77,10 @@ xfs_dir3_leafn_check(  	} else if (leafhdr.magic != XFS_DIR2_LEAFN_MAGIC)  		return false; -	return xfs_dir3_leaf_check_int(mp, &leafhdr, leaf); +	return xfs_dir3_leaf_check_int(dp->i_mount, dp, &leafhdr, leaf);  }  #else -#define	xfs_dir3_leaf_check(mp, bp) +#define	xfs_dir3_leaf_check(dp, bp)  #endif  static bool @@ -116,13 +115,14 @@ xfs_dir3_free_read_verify(  {  	struct xfs_mount	*mp = bp->b_target->bt_mount; -	if ((xfs_sb_version_hascrc(&mp->m_sb) && -	     !xfs_verify_cksum(bp->b_addr, BBTOB(bp->b_length), -					  XFS_DIR3_FREE_CRC_OFF)) || -	    !xfs_dir3_free_verify(bp)) { -		XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr); +	if (xfs_sb_version_hascrc(&mp->m_sb) && +	    !xfs_buf_verify_cksum(bp, XFS_DIR3_FREE_CRC_OFF)) +		xfs_buf_ioerror(bp, EFSBADCRC); +	else if (!xfs_dir3_free_verify(bp))  		xfs_buf_ioerror(bp, EFSCORRUPTED); -	} + +	if (bp->b_error) +		xfs_verifier_error(bp);  }  static void @@ -134,8 +134,8 @@ xfs_dir3_free_write_verify(  	struct xfs_dir3_blk_hdr	*hdr3 = bp->b_addr;  	if (!xfs_dir3_free_verify(bp)) { -		XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);  		xfs_buf_ioerror(bp, EFSCORRUPTED); +		xfs_verifier_error(bp);  		return;  	} @@ -145,7 +145,7 @@ xfs_dir3_free_write_verify(  	if (bip)  		hdr3->lsn = cpu_to_be64(bip->bli_item.li_lsn); -	xfs_update_cksum(bp->b_addr, BBTOB(bp->b_length), XFS_DIR3_FREE_CRC_OFF); +	xfs_buf_update_cksum(bp, XFS_DIR3_FREE_CRC_OFF);  }  const struct xfs_buf_ops xfs_dir3_free_buf_ops = { @@ -193,66 +193,20 @@ xfs_dir2_free_try_read(  	return __xfs_dir3_free_read(tp, dp, fbno, -2, bpp);  } - -void -xfs_dir3_free_hdr_from_disk( -	struct xfs_dir3_icfree_hdr	*to, -	struct xfs_dir2_free		*from) -{ -	if (from->hdr.magic == cpu_to_be32(XFS_DIR2_FREE_MAGIC)) { -		to->magic = be32_to_cpu(from->hdr.magic); -		to->firstdb = be32_to_cpu(from->hdr.firstdb); -		to->nvalid = be32_to_cpu(from->hdr.nvalid); -		to->nused = be32_to_cpu(from->hdr.nused); -	} else { -		struct xfs_dir3_free_hdr *hdr3 = (struct xfs_dir3_free_hdr *)from; - -		to->magic = be32_to_cpu(hdr3->hdr.magic); -		to->firstdb = be32_to_cpu(hdr3->firstdb); -		to->nvalid = be32_to_cpu(hdr3->nvalid); -		to->nused = be32_to_cpu(hdr3->nused); -	} - -	ASSERT(to->magic == XFS_DIR2_FREE_MAGIC || -	       to->magic == XFS_DIR3_FREE_MAGIC); -} - -static void -xfs_dir3_free_hdr_to_disk( -	struct xfs_dir2_free		*to, -	struct xfs_dir3_icfree_hdr	*from) -{ -	ASSERT(from->magic == XFS_DIR2_FREE_MAGIC || -	       from->magic == XFS_DIR3_FREE_MAGIC); - -	if (from->magic == XFS_DIR2_FREE_MAGIC) { -		to->hdr.magic = cpu_to_be32(from->magic); -		to->hdr.firstdb = cpu_to_be32(from->firstdb); -		to->hdr.nvalid = cpu_to_be32(from->nvalid); -		to->hdr.nused = cpu_to_be32(from->nused); -	} else { -		struct xfs_dir3_free_hdr *hdr3 = (struct xfs_dir3_free_hdr *)to; - -		hdr3->hdr.magic = cpu_to_be32(from->magic); -		hdr3->firstdb = cpu_to_be32(from->firstdb); -		hdr3->nvalid = cpu_to_be32(from->nvalid); -		hdr3->nused = cpu_to_be32(from->nused); -	} -} -  static int  xfs_dir3_free_get_buf( -	struct xfs_trans	*tp, -	struct xfs_inode	*dp, +	xfs_da_args_t		*args,  	xfs_dir2_db_t		fbno,  	struct xfs_buf		**bpp)  { +	struct xfs_trans	*tp = args->trans; +	struct xfs_inode	*dp = args->dp;  	struct xfs_mount	*mp = dp->i_mount;  	struct xfs_buf		*bp;  	int			error;  	struct xfs_dir3_icfree_hdr hdr; -	error = xfs_da_get_buf(tp, dp, xfs_dir2_db_to_da(mp, fbno), +	error = xfs_da_get_buf(tp, dp, xfs_dir2_db_to_da(args->geo, fbno),  				   -1, &bp, XFS_DATA_FORK);  	if (error)  		return error; @@ -277,7 +231,7 @@ xfs_dir3_free_get_buf(  		uuid_copy(&hdr3->hdr.uuid, &mp->m_sb.sb_uuid);  	} else  		hdr.magic = XFS_DIR2_FREE_MAGIC; -	xfs_dir3_free_hdr_to_disk(bp->b_addr, &hdr); +	dp->d_ops->free_hdr_to_disk(bp->b_addr, &hdr);  	*bpp = bp;  	return 0;  } @@ -287,7 +241,7 @@ xfs_dir3_free_get_buf(   */  STATIC void  xfs_dir2_free_log_bests( -	struct xfs_trans	*tp, +	struct xfs_da_args	*args,  	struct xfs_buf		*bp,  	int			first,		/* first entry to log */  	int			last)		/* last entry to log */ @@ -296,10 +250,10 @@ xfs_dir2_free_log_bests(  	__be16			*bests;  	free = bp->b_addr; -	bests = xfs_dir3_free_bests_p(tp->t_mountp, free); +	bests = args->dp->d_ops->free_bests_p(free);  	ASSERT(free->hdr.magic == cpu_to_be32(XFS_DIR2_FREE_MAGIC) ||  	       free->hdr.magic == cpu_to_be32(XFS_DIR3_FREE_MAGIC)); -	xfs_trans_log_buf(tp, bp, +	xfs_trans_log_buf(args->trans, bp,  		(uint)((char *)&bests[first] - (char *)free),  		(uint)((char *)&bests[last] - (char *)free +  		       sizeof(bests[0]) - 1)); @@ -310,7 +264,7 @@ xfs_dir2_free_log_bests(   */  static void  xfs_dir2_free_log_header( -	struct xfs_trans	*tp, +	struct xfs_da_args	*args,  	struct xfs_buf		*bp)  {  #ifdef DEBUG @@ -320,7 +274,8 @@ xfs_dir2_free_log_header(  	ASSERT(free->hdr.magic == cpu_to_be32(XFS_DIR2_FREE_MAGIC) ||  	       free->hdr.magic == cpu_to_be32(XFS_DIR3_FREE_MAGIC));  #endif -	xfs_trans_log_buf(tp, bp, 0, xfs_dir3_free_hdr_size(tp->t_mountp) - 1); +	xfs_trans_log_buf(args->trans, bp, 0, +			  args->dp->d_ops->free_hdr_size - 1);  }  /* @@ -360,27 +315,27 @@ xfs_dir2_leaf_to_node(  	if ((error = xfs_dir2_grow_inode(args, XFS_DIR2_FREE_SPACE, &fdb))) {  		return error;  	} -	ASSERT(fdb == XFS_DIR2_FREE_FIRSTDB(mp)); +	ASSERT(fdb == xfs_dir2_byte_to_db(args->geo, XFS_DIR2_FREE_OFFSET));  	/*  	 * Get the buffer for the new freespace block.  	 */ -	error = xfs_dir3_free_get_buf(tp, dp, fdb, &fbp); +	error = xfs_dir3_free_get_buf(args, fdb, &fbp);  	if (error)  		return error;  	free = fbp->b_addr; -	xfs_dir3_free_hdr_from_disk(&freehdr, free); +	dp->d_ops->free_hdr_from_disk(&freehdr, free);  	leaf = lbp->b_addr; -	ltp = xfs_dir2_leaf_tail_p(mp, leaf); +	ltp = xfs_dir2_leaf_tail_p(args->geo, leaf);  	ASSERT(be32_to_cpu(ltp->bestcount) <= -				(uint)dp->i_d.di_size / mp->m_dirblksize); +				(uint)dp->i_d.di_size / args->geo->blksize);  	/*  	 * Copy freespace entries from the leaf block to the new block.  	 * Count active entries.  	 */  	from = xfs_dir2_leaf_bests_p(ltp); -	to = xfs_dir3_free_bests_p(mp, free); +	to = dp->d_ops->free_bests_p(free);  	for (i = n = 0; i < be32_to_cpu(ltp->bestcount); i++, from++, to++) {  		if ((off = be16_to_cpu(*from)) != NULLDATAOFF)  			n++; @@ -393,9 +348,9 @@ xfs_dir2_leaf_to_node(  	freehdr.nused = n;  	freehdr.nvalid = be32_to_cpu(ltp->bestcount); -	xfs_dir3_free_hdr_to_disk(fbp->b_addr, &freehdr); -	xfs_dir2_free_log_bests(tp, fbp, 0, freehdr.nvalid - 1); -	xfs_dir2_free_log_header(tp, fbp); +	dp->d_ops->free_hdr_to_disk(fbp->b_addr, &freehdr); +	xfs_dir2_free_log_bests(args, fbp, 0, freehdr.nvalid - 1); +	xfs_dir2_free_log_header(args, fbp);  	/*  	 * Converting the leaf to a leafnode is just a matter of changing the @@ -409,8 +364,8 @@ xfs_dir2_leaf_to_node(  		leaf->hdr.info.magic = cpu_to_be16(XFS_DIR3_LEAFN_MAGIC);  	lbp->b_ops = &xfs_dir3_leafn_buf_ops;  	xfs_trans_buf_set_type(tp, lbp, XFS_BLFT_DIR_LEAFN_BUF); -	xfs_dir3_leaf_log_header(tp, lbp); -	xfs_dir3_leaf_check(mp, lbp); +	xfs_dir3_leaf_log_header(args, lbp); +	xfs_dir3_leaf_check(dp, lbp);  	return 0;  } @@ -443,8 +398,8 @@ xfs_dir2_leafn_add(  	mp = dp->i_mount;  	tp = args->trans;  	leaf = bp->b_addr; -	xfs_dir3_leaf_hdr_from_disk(&leafhdr, leaf); -	ents = xfs_dir3_leaf_ents_p(leaf); +	dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf); +	ents = dp->d_ops->leaf_ents_p(leaf);  	/*  	 * Quick check just to make sure we are not going to index @@ -460,7 +415,7 @@ xfs_dir2_leafn_add(  	 * a compact.  	 */ -	if (leafhdr.count == xfs_dir3_max_leaf_ents(mp, leaf)) { +	if (leafhdr.count == dp->d_ops->leaf_max_ents(args->geo)) {  		if (!leafhdr.stale)  			return XFS_ERROR(ENOSPC);  		compact = leafhdr.stale > 1; @@ -495,33 +450,34 @@ xfs_dir2_leafn_add(  				       highstale, &lfloglow, &lfloghigh);  	lep->hashval = cpu_to_be32(args->hashval); -	lep->address = cpu_to_be32(xfs_dir2_db_off_to_dataptr(mp, +	lep->address = cpu_to_be32(xfs_dir2_db_off_to_dataptr(args->geo,  				args->blkno, args->index)); -	xfs_dir3_leaf_hdr_to_disk(leaf, &leafhdr); -	xfs_dir3_leaf_log_header(tp, bp); -	xfs_dir3_leaf_log_ents(tp, bp, lfloglow, lfloghigh); -	xfs_dir3_leaf_check(mp, bp); +	dp->d_ops->leaf_hdr_to_disk(leaf, &leafhdr); +	xfs_dir3_leaf_log_header(args, bp); +	xfs_dir3_leaf_log_ents(args, bp, lfloglow, lfloghigh); +	xfs_dir3_leaf_check(dp, bp);  	return 0;  }  #ifdef DEBUG  static void  xfs_dir2_free_hdr_check( -	struct xfs_mount *mp, +	struct xfs_inode *dp,  	struct xfs_buf	*bp,  	xfs_dir2_db_t	db)  {  	struct xfs_dir3_icfree_hdr hdr; -	xfs_dir3_free_hdr_from_disk(&hdr, bp->b_addr); +	dp->d_ops->free_hdr_from_disk(&hdr, bp->b_addr); -	ASSERT((hdr.firstdb % xfs_dir3_free_max_bests(mp)) == 0); +	ASSERT((hdr.firstdb % +		dp->d_ops->free_max_bests(dp->i_mount->m_dir_geo)) == 0);  	ASSERT(hdr.firstdb <= db);  	ASSERT(db < hdr.firstdb + hdr.nvalid);  }  #else -#define xfs_dir2_free_hdr_check(mp, dp, db) +#define xfs_dir2_free_hdr_check(dp, bp, db)  #endif	/* DEBUG */  /* @@ -530,6 +486,7 @@ xfs_dir2_free_hdr_check(   */  xfs_dahash_t					/* hash value */  xfs_dir2_leafn_lasthash( +	struct xfs_inode *dp,  	struct xfs_buf	*bp,			/* leaf buffer */  	int		*count)			/* count of entries in leaf */  { @@ -537,7 +494,7 @@ xfs_dir2_leafn_lasthash(  	struct xfs_dir2_leaf_entry *ents;  	struct xfs_dir3_icleaf_hdr leafhdr; -	xfs_dir3_leaf_hdr_from_disk(&leafhdr, leaf); +	dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf);  	ASSERT(leafhdr.magic == XFS_DIR2_LEAFN_MAGIC ||  	       leafhdr.magic == XFS_DIR3_LEAFN_MAGIC); @@ -547,7 +504,7 @@ xfs_dir2_leafn_lasthash(  	if (!leafhdr.count)  		return 0; -	ents = xfs_dir3_leaf_ents_p(leaf); +	ents = dp->d_ops->leaf_ents_p(leaf);  	return be32_to_cpu(ents[leafhdr.count - 1].hashval);  } @@ -584,10 +541,10 @@ xfs_dir2_leafn_lookup_for_addname(  	tp = args->trans;  	mp = dp->i_mount;  	leaf = bp->b_addr; -	xfs_dir3_leaf_hdr_from_disk(&leafhdr, leaf); -	ents = xfs_dir3_leaf_ents_p(leaf); +	dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf); +	ents = dp->d_ops->leaf_ents_p(leaf); -	xfs_dir3_leaf_check(mp, bp); +	xfs_dir3_leaf_check(dp, bp);  	ASSERT(leafhdr.count > 0);  	/* @@ -605,7 +562,7 @@ xfs_dir2_leafn_lookup_for_addname(  		ASSERT(free->hdr.magic == cpu_to_be32(XFS_DIR2_FREE_MAGIC) ||  		       free->hdr.magic == cpu_to_be32(XFS_DIR3_FREE_MAGIC));  	} -	length = xfs_dir3_data_entsize(mp, args->namelen); +	length = dp->d_ops->data_entsize(args->namelen);  	/*  	 * Loop over leaf entries with the right hash value.  	 */ @@ -620,7 +577,8 @@ xfs_dir2_leafn_lookup_for_addname(  		/*  		 * Pull the data block number from the entry.  		 */ -		newdb = xfs_dir2_dataptr_to_db(mp, be32_to_cpu(lep->address)); +		newdb = xfs_dir2_dataptr_to_db(args->geo, +					       be32_to_cpu(lep->address));  		/*  		 * For addname, we're looking for a place to put the new entry.  		 * We want to use a data block with an entry of equal @@ -637,7 +595,7 @@ xfs_dir2_leafn_lookup_for_addname(  			 * Convert the data block to the free block  			 * holding its freespace information.  			 */ -			newfdb = xfs_dir2_db_to_fdb(mp, newdb); +			newfdb = dp->d_ops->db_to_fdb(args->geo, newdb);  			/*  			 * If it's not the one we have in hand, read it in.  			 */ @@ -649,22 +607,23 @@ xfs_dir2_leafn_lookup_for_addname(  					xfs_trans_brelse(tp, curbp);  				error = xfs_dir2_free_read(tp, dp, -						xfs_dir2_db_to_da(mp, newfdb), +						xfs_dir2_db_to_da(args->geo, +								  newfdb),  						&curbp);  				if (error)  					return error;  				free = curbp->b_addr; -				xfs_dir2_free_hdr_check(mp, curbp, curdb); +				xfs_dir2_free_hdr_check(dp, curbp, curdb);  			}  			/*  			 * Get the index for our entry.  			 */ -			fi = xfs_dir2_db_to_fdindex(mp, curdb); +			fi = dp->d_ops->db_to_fdindex(args->geo, curdb);  			/*  			 * If it has room, return it.  			 */ -			bests = xfs_dir3_free_bests_p(mp, free); +			bests = dp->d_ops->free_bests_p(free);  			if (unlikely(bests[fi] == cpu_to_be16(NULLDATAOFF))) {  				XFS_ERROR_REPORT("xfs_dir2_leafn_lookup_int",  							XFS_ERRLEVEL_LOW, mp); @@ -734,10 +693,10 @@ xfs_dir2_leafn_lookup_for_entry(  	tp = args->trans;  	mp = dp->i_mount;  	leaf = bp->b_addr; -	xfs_dir3_leaf_hdr_from_disk(&leafhdr, leaf); -	ents = xfs_dir3_leaf_ents_p(leaf); +	dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf); +	ents = dp->d_ops->leaf_ents_p(leaf); -	xfs_dir3_leaf_check(mp, bp); +	xfs_dir3_leaf_check(dp, bp);  	ASSERT(leafhdr.count > 0);  	/* @@ -765,7 +724,8 @@ xfs_dir2_leafn_lookup_for_entry(  		/*  		 * Pull the data block number from the entry.  		 */ -		newdb = xfs_dir2_dataptr_to_db(mp, be32_to_cpu(lep->address)); +		newdb = xfs_dir2_dataptr_to_db(args->geo, +					       be32_to_cpu(lep->address));  		/*  		 * Not adding a new entry, so we really want to find  		 * the name given to us. @@ -790,7 +750,8 @@ xfs_dir2_leafn_lookup_for_entry(  				curbp = state->extrablk.bp;  			} else {  				error = xfs_dir3_data_read(tp, dp, -						xfs_dir2_db_to_da(mp, newdb), +						xfs_dir2_db_to_da(args->geo, +								  newdb),  						-1, &curbp);  				if (error)  					return error; @@ -802,7 +763,8 @@ xfs_dir2_leafn_lookup_for_entry(  		 * Point to the data entry.  		 */  		dep = (xfs_dir2_data_entry_t *)((char *)curbp->b_addr + -			xfs_dir2_dataptr_to_off(mp, be32_to_cpu(lep->address))); +			xfs_dir2_dataptr_to_off(args->geo, +						be32_to_cpu(lep->address)));  		/*  		 * Compare the entry and if it's an exact match, return  		 * EEXIST immediately. If it's the first case-insensitive @@ -816,7 +778,7 @@ xfs_dir2_leafn_lookup_for_entry(  				xfs_trans_brelse(tp, state->extrablk.bp);  			args->cmpresult = cmp;  			args->inumber = be64_to_cpu(dep->inumber); -			args->filetype = xfs_dir3_dirent_get_ftype(mp, dep); +			args->filetype = dp->d_ops->data_get_ftype(dep);  			*indexp = index;  			state->extravalid = 1;  			state->extrablk.bp = curbp; @@ -888,7 +850,6 @@ xfs_dir3_leafn_moveents(  	int				start_d,/* destination leaf index */  	int				count)	/* count of leaves to copy */  { -	struct xfs_trans		*tp = args->trans;  	int				stale;	/* count stale leaves copied */  	trace_xfs_dir2_leafn_moveents(args, start_s, start_d, count); @@ -907,7 +868,7 @@ xfs_dir3_leafn_moveents(  	if (start_d < dhdr->count) {  		memmove(&dents[start_d + count], &dents[start_d],  			(dhdr->count - start_d) * sizeof(xfs_dir2_leaf_entry_t)); -		xfs_dir3_leaf_log_ents(tp, bp_d, start_d + count, +		xfs_dir3_leaf_log_ents(args, bp_d, start_d + count,  				       count + dhdr->count - 1);  	}  	/* @@ -929,7 +890,7 @@ xfs_dir3_leafn_moveents(  	 */  	memcpy(&dents[start_d], &sents[start_s],  		count * sizeof(xfs_dir2_leaf_entry_t)); -	xfs_dir3_leaf_log_ents(tp, bp_d, start_d, start_d + count - 1); +	xfs_dir3_leaf_log_ents(args, bp_d, start_d, start_d + count - 1);  	/*  	 * If there are source entries after the ones we copied, @@ -938,7 +899,7 @@ xfs_dir3_leafn_moveents(  	if (start_s + count < shdr->count) {  		memmove(&sents[start_s], &sents[start_s + count],  			count * sizeof(xfs_dir2_leaf_entry_t)); -		xfs_dir3_leaf_log_ents(tp, bp_s, start_s, start_s + count - 1); +		xfs_dir3_leaf_log_ents(args, bp_s, start_s, start_s + count - 1);  	}  	/* @@ -956,6 +917,7 @@ xfs_dir3_leafn_moveents(   */  int						/* sort order */  xfs_dir2_leafn_order( +	struct xfs_inode	*dp,  	struct xfs_buf		*leaf1_bp,		/* leaf1 buffer */  	struct xfs_buf		*leaf2_bp)		/* leaf2 buffer */  { @@ -966,10 +928,10 @@ xfs_dir2_leafn_order(  	struct xfs_dir3_icleaf_hdr hdr1;  	struct xfs_dir3_icleaf_hdr hdr2; -	xfs_dir3_leaf_hdr_from_disk(&hdr1, leaf1); -	xfs_dir3_leaf_hdr_from_disk(&hdr2, leaf2); -	ents1 = xfs_dir3_leaf_ents_p(leaf1); -	ents2 = xfs_dir3_leaf_ents_p(leaf2); +	dp->d_ops->leaf_hdr_from_disk(&hdr1, leaf1); +	dp->d_ops->leaf_hdr_from_disk(&hdr2, leaf2); +	ents1 = dp->d_ops->leaf_ents_p(leaf1); +	ents2 = dp->d_ops->leaf_ents_p(leaf2);  	if (hdr1.count > 0 && hdr2.count > 0 &&  	    (be32_to_cpu(ents2[0].hashval) < be32_to_cpu(ents1[0].hashval) || @@ -1007,12 +969,13 @@ xfs_dir2_leafn_rebalance(  	struct xfs_dir2_leaf_entry *ents2;  	struct xfs_dir3_icleaf_hdr hdr1;  	struct xfs_dir3_icleaf_hdr hdr2; +	struct xfs_inode	*dp = state->args->dp;  	args = state->args;  	/*  	 * If the block order is wrong, swap the arguments.  	 */ -	if ((swap = xfs_dir2_leafn_order(blk1->bp, blk2->bp))) { +	if ((swap = xfs_dir2_leafn_order(dp, blk1->bp, blk2->bp))) {  		xfs_da_state_blk_t	*tmp;	/* temp for block swap */  		tmp = blk1; @@ -1021,10 +984,10 @@ xfs_dir2_leafn_rebalance(  	}  	leaf1 = blk1->bp->b_addr;  	leaf2 = blk2->bp->b_addr; -	xfs_dir3_leaf_hdr_from_disk(&hdr1, leaf1); -	xfs_dir3_leaf_hdr_from_disk(&hdr2, leaf2); -	ents1 = xfs_dir3_leaf_ents_p(leaf1); -	ents2 = xfs_dir3_leaf_ents_p(leaf2); +	dp->d_ops->leaf_hdr_from_disk(&hdr1, leaf1); +	dp->d_ops->leaf_hdr_from_disk(&hdr2, leaf2); +	ents1 = dp->d_ops->leaf_ents_p(leaf1); +	ents2 = dp->d_ops->leaf_ents_p(leaf2);  	oldsum = hdr1.count + hdr2.count;  #if defined(DEBUG) || defined(XFS_WARN) @@ -1070,13 +1033,13 @@ xfs_dir2_leafn_rebalance(  	ASSERT(hdr1.stale + hdr2.stale == oldstale);  	/* log the changes made when moving the entries */ -	xfs_dir3_leaf_hdr_to_disk(leaf1, &hdr1); -	xfs_dir3_leaf_hdr_to_disk(leaf2, &hdr2); -	xfs_dir3_leaf_log_header(args->trans, blk1->bp); -	xfs_dir3_leaf_log_header(args->trans, blk2->bp); +	dp->d_ops->leaf_hdr_to_disk(leaf1, &hdr1); +	dp->d_ops->leaf_hdr_to_disk(leaf2, &hdr2); +	xfs_dir3_leaf_log_header(args, blk1->bp); +	xfs_dir3_leaf_log_header(args, blk2->bp); -	xfs_dir3_leaf_check(args->dp->i_mount, blk1->bp); -	xfs_dir3_leaf_check(args->dp->i_mount, blk2->bp); +	xfs_dir3_leaf_check(dp, blk1->bp); +	xfs_dir3_leaf_check(dp, blk2->bp);  	/*  	 * Mark whether we're inserting into the old or new leaf. @@ -1097,11 +1060,11 @@ xfs_dir2_leafn_rebalance(  	 * Finally sanity check just to make sure we are not returning a  	 * negative index  	 */ -	if(blk2->index < 0) { +	if (blk2->index < 0) {  		state->inleaf = 1;  		blk2->index = 0; -		xfs_alert(args->dp->i_mount, -	"%s: picked the wrong leaf? reverting original leaf: blk1->index %d\n", +		xfs_alert(dp->i_mount, +	"%s: picked the wrong leaf? reverting original leaf: blk1->index %d",  			__func__, blk1->index);  	}  } @@ -1116,21 +1079,20 @@ xfs_dir3_data_block_free(  	struct xfs_buf		*fbp,  	int			longest)  { -	struct xfs_trans	*tp = args->trans;  	int			logfree = 0;  	__be16			*bests;  	struct xfs_dir3_icfree_hdr freehdr; +	struct xfs_inode	*dp = args->dp; -	xfs_dir3_free_hdr_from_disk(&freehdr, free); - -	bests = xfs_dir3_free_bests_p(tp->t_mountp, free); +	dp->d_ops->free_hdr_from_disk(&freehdr, free); +	bests = dp->d_ops->free_bests_p(free);  	if (hdr) {  		/*  		 * Data block is not empty, just set the free entry to the new  		 * value.  		 */  		bests[findex] = cpu_to_be16(longest); -		xfs_dir2_free_log_bests(tp, fbp, findex, findex); +		xfs_dir2_free_log_bests(args, fbp, findex, findex);  		return 0;  	} @@ -1157,8 +1119,8 @@ xfs_dir3_data_block_free(  		logfree = 1;  	} -	xfs_dir3_free_hdr_to_disk(free, &freehdr); -	xfs_dir2_free_log_header(tp, fbp); +	dp->d_ops->free_hdr_to_disk(free, &freehdr); +	xfs_dir2_free_log_header(args, fbp);  	/*  	 * If there are no useful entries left in the block, get rid of the @@ -1182,7 +1144,7 @@ xfs_dir3_data_block_free(  	/* Log the free entry that changed, unless we got rid of it.  */  	if (logfree) -		xfs_dir2_free_log_bests(tp, fbp, findex, findex); +		xfs_dir2_free_log_bests(args, fbp, findex, findex);  	return 0;  } @@ -1222,8 +1184,8 @@ xfs_dir2_leafn_remove(  	tp = args->trans;  	mp = dp->i_mount;  	leaf = bp->b_addr; -	xfs_dir3_leaf_hdr_from_disk(&leafhdr, leaf); -	ents = xfs_dir3_leaf_ents_p(leaf); +	dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf); +	ents = dp->d_ops->leaf_ents_p(leaf);  	/*  	 * Point to the entry we're removing. @@ -1233,9 +1195,9 @@ xfs_dir2_leafn_remove(  	/*  	 * Extract the data block and offset from the entry.  	 */ -	db = xfs_dir2_dataptr_to_db(mp, be32_to_cpu(lep->address)); +	db = xfs_dir2_dataptr_to_db(args->geo, be32_to_cpu(lep->address));  	ASSERT(dblk->blkno == db); -	off = xfs_dir2_dataptr_to_off(mp, be32_to_cpu(lep->address)); +	off = xfs_dir2_dataptr_to_off(args->geo, be32_to_cpu(lep->address));  	ASSERT(dblk->index == off);  	/* @@ -1243,11 +1205,11 @@ xfs_dir2_leafn_remove(  	 * Log the leaf block changes.  	 */  	leafhdr.stale++; -	xfs_dir3_leaf_hdr_to_disk(leaf, &leafhdr); -	xfs_dir3_leaf_log_header(tp, bp); +	dp->d_ops->leaf_hdr_to_disk(leaf, &leafhdr); +	xfs_dir3_leaf_log_header(args, bp);  	lep->address = cpu_to_be32(XFS_DIR2_NULL_DATAPTR); -	xfs_dir3_leaf_log_ents(tp, bp, index, index); +	xfs_dir3_leaf_log_ents(args, bp, index, index);  	/*  	 * Make the data entry free.  Keep track of the longest freespace @@ -1256,19 +1218,19 @@ xfs_dir2_leafn_remove(  	dbp = dblk->bp;  	hdr = dbp->b_addr;  	dep = (xfs_dir2_data_entry_t *)((char *)hdr + off); -	bf = xfs_dir3_data_bestfree_p(hdr); +	bf = dp->d_ops->data_bestfree_p(hdr);  	longest = be16_to_cpu(bf[0].length);  	needlog = needscan = 0; -	xfs_dir2_data_make_free(tp, dbp, off, -		xfs_dir3_data_entsize(mp, dep->namelen), &needlog, &needscan); +	xfs_dir2_data_make_free(args, dbp, off, +		dp->d_ops->data_entsize(dep->namelen), &needlog, &needscan);  	/*  	 * Rescan the data block freespaces for bestfree.  	 * Log the data block header if needed.  	 */  	if (needscan) -		xfs_dir2_data_freescan(mp, hdr, &needlog); +		xfs_dir2_data_freescan(dp, hdr, &needlog);  	if (needlog) -		xfs_dir2_data_log_header(tp, dbp); +		xfs_dir2_data_log_header(args, dbp);  	xfs_dir3_data_check(dp, dbp);  	/*  	 * If the longest data block freespace changes, need to update @@ -1285,8 +1247,9 @@ xfs_dir2_leafn_remove(  		 * Convert the data block number to a free block,  		 * read in the free block.  		 */ -		fdb = xfs_dir2_db_to_fdb(mp, db); -		error = xfs_dir2_free_read(tp, dp, xfs_dir2_db_to_da(mp, fdb), +		fdb = dp->d_ops->db_to_fdb(args->geo, db); +		error = xfs_dir2_free_read(tp, dp, +					   xfs_dir2_db_to_da(args->geo, fdb),  					   &fbp);  		if (error)  			return error; @@ -1294,22 +1257,23 @@ xfs_dir2_leafn_remove(  #ifdef DEBUG  	{  		struct xfs_dir3_icfree_hdr freehdr; -		xfs_dir3_free_hdr_from_disk(&freehdr, free); -		ASSERT(freehdr.firstdb == xfs_dir3_free_max_bests(mp) * -					  (fdb - XFS_DIR2_FREE_FIRSTDB(mp))); +		dp->d_ops->free_hdr_from_disk(&freehdr, free); +		ASSERT(freehdr.firstdb == dp->d_ops->free_max_bests(args->geo) * +			(fdb - xfs_dir2_byte_to_db(args->geo, +						   XFS_DIR2_FREE_OFFSET)));  	}  #endif  		/*  		 * Calculate which entry we need to fix.  		 */ -		findex = xfs_dir2_db_to_fdindex(mp, db); +		findex = dp->d_ops->db_to_fdindex(args->geo, db);  		longest = be16_to_cpu(bf[0].length);  		/*  		 * If the data block is now empty we can get rid of it  		 * (usually).  		 */ -		if (longest == mp->m_dirblksize - -			       xfs_dir3_data_entry_offset(hdr)) { +		if (longest == args->geo->blksize - +			       dp->d_ops->data_entry_offset) {  			/*  			 * Try to punch out the data block.  			 */ @@ -1336,14 +1300,14 @@ xfs_dir2_leafn_remove(  			return error;  	} -	xfs_dir3_leaf_check(mp, bp); +	xfs_dir3_leaf_check(dp, bp);  	/*  	 * Return indication of whether this leaf block is empty enough  	 * to justify trying to join it with a neighbor.  	 */ -	*rval = (xfs_dir3_leaf_hdr_size(leaf) + +	*rval = (dp->d_ops->leaf_hdr_size +  		 (uint)sizeof(ents[0]) * (leafhdr.count - leafhdr.stale)) < -		mp->m_dir_magicpct; +		args->geo->magicpct;  	return 0;  } @@ -1360,13 +1324,14 @@ xfs_dir2_leafn_split(  	xfs_dablk_t		blkno;		/* new leaf block number */  	int			error;		/* error return value */  	xfs_mount_t		*mp;		/* filesystem mount point */ +	struct xfs_inode	*dp;  	/*  	 * Allocate space for a new leaf node.  	 */  	args = state->args; -	mp = args->dp->i_mount; -	ASSERT(args != NULL); +	dp = args->dp; +	mp = dp->i_mount;  	ASSERT(oldblk->magic == XFS_DIR2_LEAFN_MAGIC);  	error = xfs_da_grow_inode(args, &blkno);  	if (error) { @@ -1375,7 +1340,7 @@ xfs_dir2_leafn_split(  	/*  	 * Initialize the new leaf block.  	 */ -	error = xfs_dir3_leaf_get_buf(args, xfs_dir2_da_to_db(mp, blkno), +	error = xfs_dir3_leaf_get_buf(args, xfs_dir2_da_to_db(args->geo, blkno),  				      &newblk->bp, XFS_DIR2_LEAFN_MAGIC);  	if (error)  		return error; @@ -1401,10 +1366,10 @@ xfs_dir2_leafn_split(  	/*  	 * Update last hashval in each block since we added the name.  	 */ -	oldblk->hashval = xfs_dir2_leafn_lasthash(oldblk->bp, NULL); -	newblk->hashval = xfs_dir2_leafn_lasthash(newblk->bp, NULL); -	xfs_dir3_leaf_check(mp, oldblk->bp); -	xfs_dir3_leaf_check(mp, newblk->bp); +	oldblk->hashval = xfs_dir2_leafn_lasthash(dp, oldblk->bp, NULL); +	newblk->hashval = xfs_dir2_leafn_lasthash(dp, newblk->bp, NULL); +	xfs_dir3_leaf_check(dp, oldblk->bp); +	xfs_dir3_leaf_check(dp, newblk->bp);  	return error;  } @@ -1434,6 +1399,7 @@ xfs_dir2_leafn_toosmall(  	int			rval;		/* result from path_shift */  	struct xfs_dir3_icleaf_hdr leafhdr;  	struct xfs_dir2_leaf_entry *ents; +	struct xfs_inode	*dp = state->args->dp;  	/*  	 * Check for the degenerate case of the block being over 50% full. @@ -1442,13 +1408,13 @@ xfs_dir2_leafn_toosmall(  	 */  	blk = &state->path.blk[state->path.active - 1];  	leaf = blk->bp->b_addr; -	xfs_dir3_leaf_hdr_from_disk(&leafhdr, leaf); -	ents = xfs_dir3_leaf_ents_p(leaf); -	xfs_dir3_leaf_check(state->args->dp->i_mount, blk->bp); +	dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf); +	ents = dp->d_ops->leaf_ents_p(leaf); +	xfs_dir3_leaf_check(dp, blk->bp);  	count = leafhdr.count - leafhdr.stale; -	bytes = xfs_dir3_leaf_hdr_size(leaf) + count * sizeof(ents[0]); -	if (bytes > (state->blocksize >> 1)) { +	bytes = dp->d_ops->leaf_hdr_size + count * sizeof(ents[0]); +	if (bytes > (state->args->geo->blksize >> 1)) {  		/*  		 * Blk over 50%, don't try to join.  		 */ @@ -1492,7 +1458,7 @@ xfs_dir2_leafn_toosmall(  		/*  		 * Read the sibling leaf block.  		 */ -		error = xfs_dir3_leafn_read(state->args->trans, state->args->dp, +		error = xfs_dir3_leafn_read(state->args->trans, dp,  					    blkno, -1, &bp);  		if (error)  			return error; @@ -1501,11 +1467,12 @@ xfs_dir2_leafn_toosmall(  		 * Count bytes in the two blocks combined.  		 */  		count = leafhdr.count - leafhdr.stale; -		bytes = state->blocksize - (state->blocksize >> 2); +		bytes = state->args->geo->blksize - +			(state->args->geo->blksize >> 2);  		leaf = bp->b_addr; -		xfs_dir3_leaf_hdr_from_disk(&hdr2, leaf); -		ents = xfs_dir3_leaf_ents_p(leaf); +		dp->d_ops->leaf_hdr_from_disk(&hdr2, leaf); +		ents = dp->d_ops->leaf_ents_p(leaf);  		count += hdr2.count - hdr2.stale;  		bytes -= count * sizeof(ents[0]); @@ -1559,6 +1526,7 @@ xfs_dir2_leafn_unbalance(  	struct xfs_dir3_icleaf_hdr drophdr;  	struct xfs_dir2_leaf_entry *sents;  	struct xfs_dir2_leaf_entry *dents; +	struct xfs_inode	*dp = state->args->dp;  	args = state->args;  	ASSERT(drop_blk->magic == XFS_DIR2_LEAFN_MAGIC); @@ -1566,10 +1534,10 @@ xfs_dir2_leafn_unbalance(  	drop_leaf = drop_blk->bp->b_addr;  	save_leaf = save_blk->bp->b_addr; -	xfs_dir3_leaf_hdr_from_disk(&savehdr, save_leaf); -	xfs_dir3_leaf_hdr_from_disk(&drophdr, drop_leaf); -	sents = xfs_dir3_leaf_ents_p(save_leaf); -	dents = xfs_dir3_leaf_ents_p(drop_leaf); +	dp->d_ops->leaf_hdr_from_disk(&savehdr, save_leaf); +	dp->d_ops->leaf_hdr_from_disk(&drophdr, drop_leaf); +	sents = dp->d_ops->leaf_ents_p(save_leaf); +	dents = dp->d_ops->leaf_ents_p(drop_leaf);  	/*  	 * If there are any stale leaf entries, take this opportunity @@ -1584,7 +1552,7 @@ xfs_dir2_leafn_unbalance(  	 * Move the entries from drop to the appropriate end of save.  	 */  	drop_blk->hashval = be32_to_cpu(dents[drophdr.count - 1].hashval); -	if (xfs_dir2_leafn_order(save_blk->bp, drop_blk->bp)) +	if (xfs_dir2_leafn_order(dp, save_blk->bp, drop_blk->bp))  		xfs_dir3_leafn_moveents(args, drop_blk->bp, &drophdr, dents, 0,  					save_blk->bp, &savehdr, sents, 0,  					drophdr.count); @@ -1595,13 +1563,13 @@ xfs_dir2_leafn_unbalance(  	save_blk->hashval = be32_to_cpu(sents[savehdr.count - 1].hashval);  	/* log the changes made when moving the entries */ -	xfs_dir3_leaf_hdr_to_disk(save_leaf, &savehdr); -	xfs_dir3_leaf_hdr_to_disk(drop_leaf, &drophdr); -	xfs_dir3_leaf_log_header(args->trans, save_blk->bp); -	xfs_dir3_leaf_log_header(args->trans, drop_blk->bp); +	dp->d_ops->leaf_hdr_to_disk(save_leaf, &savehdr); +	dp->d_ops->leaf_hdr_to_disk(drop_leaf, &drophdr); +	xfs_dir3_leaf_log_header(args, save_blk->bp); +	xfs_dir3_leaf_log_header(args, drop_blk->bp); -	xfs_dir3_leaf_check(args->dp->i_mount, save_blk->bp); -	xfs_dir3_leaf_check(args->dp->i_mount, drop_blk->bp); +	xfs_dir3_leaf_check(dp, save_blk->bp); +	xfs_dir3_leaf_check(dp, drop_blk->bp);  }  /* @@ -1624,8 +1592,6 @@ xfs_dir2_node_addname(  	state = xfs_da_state_alloc();  	state->args = args;  	state->mp = args->dp->i_mount; -	state->blocksize = state->mp->m_dirblksize; -	state->node_ents = state->mp->m_dir_node_ents;  	/*  	 * Look up the name.  We're not supposed to find it, but  	 * this gives us the insertion point. @@ -1712,7 +1678,7 @@ xfs_dir2_node_addname_int(  	dp = args->dp;  	mp = dp->i_mount;  	tp = args->trans; -	length = xfs_dir3_data_entsize(mp, args->namelen); +	length = dp->d_ops->data_entsize(args->namelen);  	/*  	 * If we came in with a freespace block that means that lookup  	 * found an entry with our hash value.  This is the freespace @@ -1726,8 +1692,8 @@ xfs_dir2_node_addname_int(  		ifbno = fblk->blkno;  		free = fbp->b_addr;  		findex = fblk->index; -		bests = xfs_dir3_free_bests_p(mp, free); -		xfs_dir3_free_hdr_from_disk(&freehdr, free); +		bests = dp->d_ops->free_bests_p(free); +		dp->d_ops->free_hdr_from_disk(&freehdr, free);  		/*  		 * This means the free entry showed that the data block had @@ -1764,9 +1730,9 @@ xfs_dir2_node_addname_int(  	if (dbno == -1) {  		xfs_fileoff_t	fo;		/* freespace block number */ -		if ((error = xfs_bmap_last_offset(tp, dp, &fo, XFS_DATA_FORK))) +		if ((error = xfs_bmap_last_offset(dp, &fo, XFS_DATA_FORK)))  			return error; -		lastfbno = xfs_dir2_da_to_db(mp, (xfs_dablk_t)fo); +		lastfbno = xfs_dir2_da_to_db(args->geo, (xfs_dablk_t)fo);  		fbno = ifbno;  	}  	/* @@ -1784,7 +1750,8 @@ xfs_dir2_node_addname_int(  			 * us a freespace block to start with.  			 */  			if (++fbno == 0) -				fbno = XFS_DIR2_FREE_FIRSTDB(mp); +				fbno = xfs_dir2_byte_to_db(args->geo, +							XFS_DIR2_FREE_OFFSET);  			/*  			 * If it's ifbno we already looked at it.  			 */ @@ -1802,8 +1769,8 @@ xfs_dir2_node_addname_int(  			 * to avoid it.  			 */  			error = xfs_dir2_free_try_read(tp, dp, -						xfs_dir2_db_to_da(mp, fbno), -						&fbp); +					xfs_dir2_db_to_da(args->geo, fbno), +					&fbp);  			if (error)  				return error;  			if (!fbp) @@ -1819,8 +1786,8 @@ xfs_dir2_node_addname_int(  		 * and the freehdr are actually initialised if they are placed  		 * there, so we have to do it here to avoid warnings. Blech.  		 */ -		bests = xfs_dir3_free_bests_p(mp, free); -		xfs_dir3_free_hdr_from_disk(&freehdr, free); +		bests = dp->d_ops->free_bests_p(free); +		dp->d_ops->free_hdr_from_disk(&freehdr, free);  		if (be16_to_cpu(bests[findex]) != NULLDATAOFF &&  		    be16_to_cpu(bests[findex]) >= length)  			dbno = freehdr.firstdb + findex; @@ -1871,10 +1838,10 @@ xfs_dir2_node_addname_int(  		 * Get the freespace block corresponding to the data block  		 * that was just allocated.  		 */ -		fbno = xfs_dir2_db_to_fdb(mp, dbno); +		fbno = dp->d_ops->db_to_fdb(args->geo, dbno);  		error = xfs_dir2_free_try_read(tp, dp, -					       xfs_dir2_db_to_da(mp, fbno), -					       &fbp); +				       xfs_dir2_db_to_da(args->geo, fbno), +				       &fbp);  		if (error)  			return error; @@ -1888,12 +1855,13 @@ xfs_dir2_node_addname_int(  			if (error)  				return error; -			if (unlikely(xfs_dir2_db_to_fdb(mp, dbno) != fbno)) { +			if (dp->d_ops->db_to_fdb(args->geo, dbno) != fbno) {  				xfs_alert(mp,  			"%s: dir ino %llu needed freesp block %lld for\n"  			"  data block %lld, got %lld ifbno %llu lastfbno %d",  					__func__, (unsigned long long)dp->i_ino, -					(long long)xfs_dir2_db_to_fdb(mp, dbno), +					(long long)dp->d_ops->db_to_fdb( +								args->geo, dbno),  					(long long)dbno, (long long)fbno,  					(unsigned long long)ifbno, lastfbno);  				if (fblk) { @@ -1914,34 +1882,36 @@ xfs_dir2_node_addname_int(  			/*  			 * Get a buffer for the new block.  			 */ -			error = xfs_dir3_free_get_buf(tp, dp, fbno, &fbp); +			error = xfs_dir3_free_get_buf(args, fbno, &fbp);  			if (error)  				return error;  			free = fbp->b_addr; -			bests = xfs_dir3_free_bests_p(mp, free); -			xfs_dir3_free_hdr_from_disk(&freehdr, free); +			bests = dp->d_ops->free_bests_p(free); +			dp->d_ops->free_hdr_from_disk(&freehdr, free);  			/*  			 * Remember the first slot as our empty slot.  			 */ -			freehdr.firstdb = (fbno - XFS_DIR2_FREE_FIRSTDB(mp)) * -					xfs_dir3_free_max_bests(mp); +			freehdr.firstdb = +				(fbno - xfs_dir2_byte_to_db(args->geo, +							XFS_DIR2_FREE_OFFSET)) * +					dp->d_ops->free_max_bests(args->geo);  		} else {  			free = fbp->b_addr; -			bests = xfs_dir3_free_bests_p(mp, free); -			xfs_dir3_free_hdr_from_disk(&freehdr, free); +			bests = dp->d_ops->free_bests_p(free); +			dp->d_ops->free_hdr_from_disk(&freehdr, free);  		}  		/*  		 * Set the freespace block index from the data block number.  		 */ -		findex = xfs_dir2_db_to_fdindex(mp, dbno); +		findex = dp->d_ops->db_to_fdindex(args->geo, dbno);  		/*  		 * If it's after the end of the current entries in the  		 * freespace block, extend that table.  		 */  		if (findex >= freehdr.nvalid) { -			ASSERT(findex < xfs_dir3_free_max_bests(mp)); +			ASSERT(findex < dp->d_ops->free_max_bests(args->geo));  			freehdr.nvalid = findex + 1;  			/*  			 * Tag new entry so nused will go up. @@ -1954,8 +1924,8 @@ xfs_dir2_node_addname_int(  		 */  		if (bests[findex] == cpu_to_be16(NULLDATAOFF)) {  			freehdr.nused++; -			xfs_dir3_free_hdr_to_disk(fbp->b_addr, &freehdr); -			xfs_dir2_free_log_header(tp, fbp); +			dp->d_ops->free_hdr_to_disk(fbp->b_addr, &freehdr); +			xfs_dir2_free_log_header(args, fbp);  		}  		/*  		 * Update the real value in the table. @@ -1963,7 +1933,7 @@ xfs_dir2_node_addname_int(  		 * change again.  		 */  		hdr = dbp->b_addr; -		bf = xfs_dir3_data_bestfree_p(hdr); +		bf = dp->d_ops->data_bestfree_p(hdr);  		bests[findex] = bf[0].length;  		logfree = 1;  	} @@ -1980,12 +1950,13 @@ xfs_dir2_node_addname_int(  		/*  		 * Read the data block in.  		 */ -		error = xfs_dir3_data_read(tp, dp, xfs_dir2_db_to_da(mp, dbno), +		error = xfs_dir3_data_read(tp, dp, +					   xfs_dir2_db_to_da(args->geo, dbno),  					   -1, &dbp);  		if (error)  			return error;  		hdr = dbp->b_addr; -		bf = xfs_dir3_data_bestfree_p(hdr); +		bf = dp->d_ops->data_bestfree_p(hdr);  		logfree = 0;  	}  	ASSERT(be16_to_cpu(bf[0].length) >= length); @@ -1998,7 +1969,7 @@ xfs_dir2_node_addname_int(  	/*  	 * Mark the first part of the unused space, inuse for us.  	 */ -	xfs_dir2_data_use_free(tp, dbp, dup, +	xfs_dir2_data_use_free(args, dbp, dup,  		(xfs_dir2_data_aoff_t)((char *)dup - (char *)hdr), length,  		&needlog, &needscan);  	/* @@ -2008,24 +1979,24 @@ xfs_dir2_node_addname_int(  	dep->inumber = cpu_to_be64(args->inumber);  	dep->namelen = args->namelen;  	memcpy(dep->name, args->name, dep->namelen); -	xfs_dir3_dirent_put_ftype(mp, dep, args->filetype); -	tagp = xfs_dir3_data_entry_tag_p(mp, dep); +	dp->d_ops->data_put_ftype(dep, args->filetype); +	tagp = dp->d_ops->data_entry_tag_p(dep);  	*tagp = cpu_to_be16((char *)dep - (char *)hdr); -	xfs_dir2_data_log_entry(tp, dbp, dep); +	xfs_dir2_data_log_entry(args, dbp, dep);  	/*  	 * Rescan the block for bestfree if needed.  	 */  	if (needscan) -		xfs_dir2_data_freescan(mp, hdr, &needlog); +		xfs_dir2_data_freescan(dp, hdr, &needlog);  	/*  	 * Log the data block header if needed.  	 */  	if (needlog) -		xfs_dir2_data_log_header(tp, dbp); +		xfs_dir2_data_log_header(args, dbp);  	/*  	 * If the freespace entry is now wrong, update it.  	 */ -	bests = xfs_dir3_free_bests_p(mp, free); /* gcc is so stupid */ +	bests = dp->d_ops->free_bests_p(free); /* gcc is so stupid */  	if (be16_to_cpu(bests[findex]) != be16_to_cpu(bf[0].length)) {  		bests[findex] = bf[0].length;  		logfree = 1; @@ -2034,7 +2005,7 @@ xfs_dir2_node_addname_int(  	 * Log the freespace entry if needed.  	 */  	if (logfree) -		xfs_dir2_free_log_bests(tp, fbp, findex, findex); +		xfs_dir2_free_log_bests(args, fbp, findex, findex);  	/*  	 * Return the data block and offset in args, then drop the data block.  	 */ @@ -2065,8 +2036,6 @@ xfs_dir2_node_lookup(  	state = xfs_da_state_alloc();  	state->args = args;  	state->mp = args->dp->i_mount; -	state->blocksize = state->mp->m_dirblksize; -	state->node_ents = state->mp->m_dir_node_ents;  	/*  	 * Fill in the path to the entry in the cursor.  	 */ @@ -2105,12 +2074,12 @@ xfs_dir2_node_lookup(   */  int						/* error */  xfs_dir2_node_removename( -	xfs_da_args_t		*args)		/* operation arguments */ +	struct xfs_da_args	*args)		/* operation arguments */  { -	xfs_da_state_blk_t	*blk;		/* leaf block */ +	struct xfs_da_state_blk	*blk;		/* leaf block */  	int			error;		/* error return value */  	int			rval;		/* operation return value */ -	xfs_da_state_t		*state;		/* btree cursor */ +	struct xfs_da_state	*state;		/* btree cursor */  	trace_xfs_dir2_node_removename(args); @@ -2120,21 +2089,18 @@ xfs_dir2_node_removename(  	state = xfs_da_state_alloc();  	state->args = args;  	state->mp = args->dp->i_mount; -	state->blocksize = state->mp->m_dirblksize; -	state->node_ents = state->mp->m_dir_node_ents; -	/* -	 * Look up the entry we're deleting, set up the cursor. -	 */ + +	/* Look up the entry we're deleting, set up the cursor. */  	error = xfs_da3_node_lookup_int(state, &rval);  	if (error) -		rval = error; -	/* -	 * Didn't find it, upper layer screwed up. -	 */ +		goto out_free; + +	/* Didn't find it, upper layer screwed up. */  	if (rval != EEXIST) { -		xfs_da_state_free(state); -		return rval; +		error = rval; +		goto out_free;  	} +  	blk = &state->path.blk[state->path.active - 1];  	ASSERT(blk->magic == XFS_DIR2_LEAFN_MAGIC);  	ASSERT(state->extravalid); @@ -2145,7 +2111,7 @@ xfs_dir2_node_removename(  	error = xfs_dir2_leafn_remove(args, blk->bp, blk->index,  		&state->extrablk, &rval);  	if (error) -		return error; +		goto out_free;  	/*  	 * Fix the hash values up the btree.  	 */ @@ -2160,6 +2126,7 @@ xfs_dir2_node_removename(  	 */  	if (!error)  		error = xfs_dir2_node_to_leaf(state); +out_free:  	xfs_da_state_free(state);  	return error;  } @@ -2190,8 +2157,6 @@ xfs_dir2_node_replace(  	state = xfs_da_state_alloc();  	state->args = args;  	state->mp = args->dp->i_mount; -	state->blocksize = state->mp->m_dirblksize; -	state->node_ents = state->mp->m_dir_node_ents;  	inum = args->inumber;  	/*  	 * Lookup the entry to change in the btree. @@ -2212,7 +2177,7 @@ xfs_dir2_node_replace(  		blk = &state->path.blk[state->path.active - 1];  		ASSERT(blk->magic == XFS_DIR2_LEAFN_MAGIC);  		leaf = blk->bp->b_addr; -		ents = xfs_dir3_leaf_ents_p(leaf); +		ents = args->dp->d_ops->leaf_ents_p(leaf);  		lep = &ents[blk->index];  		ASSERT(state->extravalid);  		/* @@ -2223,14 +2188,15 @@ xfs_dir2_node_replace(  		       hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC));  		dep = (xfs_dir2_data_entry_t *)  		      ((char *)hdr + -		       xfs_dir2_dataptr_to_off(state->mp, be32_to_cpu(lep->address))); +		       xfs_dir2_dataptr_to_off(args->geo, +					       be32_to_cpu(lep->address)));  		ASSERT(inum != be64_to_cpu(dep->inumber));  		/*  		 * Fill in the new inode number and log the entry.  		 */  		dep->inumber = cpu_to_be64(inum); -		xfs_dir3_dirent_put_ftype(state->mp, dep, args->filetype); -		xfs_dir2_data_log_entry(args->trans, state->extrablk.bp, dep); +		args->dp->d_ops->data_put_ftype(dep, args->filetype); +		xfs_dir2_data_log_entry(args, state->extrablk.bp, dep);  		rval = 0;  	}  	/* @@ -2285,7 +2251,7 @@ xfs_dir2_node_trim_free(  	if (!bp)  		return 0;  	free = bp->b_addr; -	xfs_dir3_free_hdr_from_disk(&freehdr, free); +	dp->d_ops->free_hdr_from_disk(&freehdr, free);  	/*  	 * If there are used entries, there's nothing to do. @@ -2298,9 +2264,9 @@ xfs_dir2_node_trim_free(  	/*  	 * Blow the block away.  	 */ -	if ((error = -	    xfs_dir2_shrink_inode(args, xfs_dir2_da_to_db(mp, (xfs_dablk_t)fo), -		    bp))) { +	error = xfs_dir2_shrink_inode(args, +			xfs_dir2_da_to_db(args->geo, (xfs_dablk_t)fo), bp); +	if (error) {  		/*  		 * Can't fail with ENOSPC since that only happens with no  		 * space reservation, when breaking up an extent into two  | 
