diff options
Diffstat (limited to 'fs')
71 files changed, 285 insertions, 4595 deletions
diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c index c5ea26d73be..3e807b828e2 100644 --- a/fs/xfs/linux-2.6/xfs_aops.c +++ b/fs/xfs/linux-2.6/xfs_aops.c @@ -21,7 +21,6 @@  #include "xfs_inum.h"  #include "xfs_sb.h"  #include "xfs_ag.h" -#include "xfs_dir.h"  #include "xfs_dir2.h"  #include "xfs_trans.h"  #include "xfs_dmapi.h" @@ -29,7 +28,6 @@  #include "xfs_bmap_btree.h"  #include "xfs_alloc_btree.h"  #include "xfs_ialloc_btree.h" -#include "xfs_dir_sf.h"  #include "xfs_dir2_sf.h"  #include "xfs_attr_sf.h"  #include "xfs_dinode.h" diff --git a/fs/xfs/linux-2.6/xfs_export.c b/fs/xfs/linux-2.6/xfs_export.c index d32a9edc43a..5fb75d9151f 100644 --- a/fs/xfs/linux-2.6/xfs_export.c +++ b/fs/xfs/linux-2.6/xfs_export.c @@ -21,7 +21,6 @@  #include "xfs_log.h"  #include "xfs_trans.h"  #include "xfs_sb.h" -#include "xfs_dir.h"  #include "xfs_mount.h"  #include "xfs_export.h" diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c index cf65a8364d5..70662371bb1 100644 --- a/fs/xfs/linux-2.6/xfs_file.c +++ b/fs/xfs/linux-2.6/xfs_file.c @@ -21,7 +21,6 @@  #include "xfs_inum.h"  #include "xfs_sb.h"  #include "xfs_ag.h" -#include "xfs_dir.h"  #include "xfs_dir2.h"  #include "xfs_trans.h"  #include "xfs_dmapi.h" @@ -32,7 +31,6 @@  #include "xfs_alloc.h"  #include "xfs_btree.h"  #include "xfs_attr_sf.h" -#include "xfs_dir_sf.h"  #include "xfs_dir2_sf.h"  #include "xfs_dinode.h"  #include "xfs_inode.h" diff --git a/fs/xfs/linux-2.6/xfs_ioctl.c b/fs/xfs/linux-2.6/xfs_ioctl.c index a0e247c7132..6e52a5dd38d 100644 --- a/fs/xfs/linux-2.6/xfs_ioctl.c +++ b/fs/xfs/linux-2.6/xfs_ioctl.c @@ -23,7 +23,6 @@  #include "xfs_trans.h"  #include "xfs_sb.h"  #include "xfs_ag.h" -#include "xfs_dir.h"  #include "xfs_dir2.h"  #include "xfs_alloc.h"  #include "xfs_dmapi.h" @@ -31,7 +30,6 @@  #include "xfs_bmap_btree.h"  #include "xfs_alloc_btree.h"  #include "xfs_ialloc_btree.h" -#include "xfs_dir_sf.h"  #include "xfs_attr_sf.h"  #include "xfs_dir2_sf.h"  #include "xfs_dinode.h" diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c index 484daef91d7..12810baeb5d 100644 --- a/fs/xfs/linux-2.6/xfs_iops.c +++ b/fs/xfs/linux-2.6/xfs_iops.c @@ -23,7 +23,6 @@  #include "xfs_trans.h"  #include "xfs_sb.h"  #include "xfs_ag.h" -#include "xfs_dir.h"  #include "xfs_dir2.h"  #include "xfs_alloc.h"  #include "xfs_dmapi.h" @@ -32,7 +31,6 @@  #include "xfs_bmap_btree.h"  #include "xfs_alloc_btree.h"  #include "xfs_ialloc_btree.h" -#include "xfs_dir_sf.h"  #include "xfs_dir2_sf.h"  #include "xfs_attr_sf.h"  #include "xfs_dinode.h" diff --git a/fs/xfs/linux-2.6/xfs_lrw.c b/fs/xfs/linux-2.6/xfs_lrw.c index 8e546870481..5d9cfd91ad0 100644 --- a/fs/xfs/linux-2.6/xfs_lrw.c +++ b/fs/xfs/linux-2.6/xfs_lrw.c @@ -23,7 +23,6 @@  #include "xfs_trans.h"  #include "xfs_sb.h"  #include "xfs_ag.h" -#include "xfs_dir.h"  #include "xfs_dir2.h"  #include "xfs_alloc.h"  #include "xfs_dmapi.h" @@ -32,7 +31,6 @@  #include "xfs_bmap_btree.h"  #include "xfs_alloc_btree.h"  #include "xfs_ialloc_btree.h" -#include "xfs_dir_sf.h"  #include "xfs_dir2_sf.h"  #include "xfs_attr_sf.h"  #include "xfs_dinode.h" diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c index 7fae922d54d..f2a0778536f 100644 --- a/fs/xfs/linux-2.6/xfs_super.c +++ b/fs/xfs/linux-2.6/xfs_super.c @@ -23,7 +23,6 @@  #include "xfs_trans.h"  #include "xfs_sb.h"  #include "xfs_ag.h" -#include "xfs_dir.h"  #include "xfs_dir2.h"  #include "xfs_alloc.h"  #include "xfs_dmapi.h" @@ -32,7 +31,6 @@  #include "xfs_bmap_btree.h"  #include "xfs_alloc_btree.h"  #include "xfs_ialloc_btree.h" -#include "xfs_dir_sf.h"  #include "xfs_dir2_sf.h"  #include "xfs_attr_sf.h"  #include "xfs_dinode.h" diff --git a/fs/xfs/linux-2.6/xfs_vfs.c b/fs/xfs/linux-2.6/xfs_vfs.c index 4fc884bcb4f..6145e8bd0be 100644 --- a/fs/xfs/linux-2.6/xfs_vfs.c +++ b/fs/xfs/linux-2.6/xfs_vfs.c @@ -23,7 +23,6 @@  #include "xfs_trans.h"  #include "xfs_sb.h"  #include "xfs_ag.h" -#include "xfs_dir.h"  #include "xfs_dir2.h"  #include "xfs_imap.h"  #include "xfs_alloc.h" diff --git a/fs/xfs/quota/xfs_dquot.c b/fs/xfs/quota/xfs_dquot.c index 46bec66bb4d..3aa77153185 100644 --- a/fs/xfs/quota/xfs_dquot.c +++ b/fs/xfs/quota/xfs_dquot.c @@ -23,7 +23,6 @@  #include "xfs_trans.h"  #include "xfs_sb.h"  #include "xfs_ag.h" -#include "xfs_dir.h"  #include "xfs_dir2.h"  #include "xfs_alloc.h"  #include "xfs_dmapi.h" @@ -32,7 +31,6 @@  #include "xfs_bmap_btree.h"  #include "xfs_alloc_btree.h"  #include "xfs_ialloc_btree.h" -#include "xfs_dir_sf.h"  #include "xfs_dir2_sf.h"  #include "xfs_attr_sf.h"  #include "xfs_dinode.h" diff --git a/fs/xfs/quota/xfs_dquot_item.c b/fs/xfs/quota/xfs_dquot_item.c index 21ad5a55e01..5b2dcc58b24 100644 --- a/fs/xfs/quota/xfs_dquot_item.c +++ b/fs/xfs/quota/xfs_dquot_item.c @@ -23,7 +23,6 @@  #include "xfs_trans.h"  #include "xfs_sb.h"  #include "xfs_ag.h" -#include "xfs_dir.h"  #include "xfs_dir2.h"  #include "xfs_alloc.h"  #include "xfs_dmapi.h" @@ -32,7 +31,6 @@  #include "xfs_bmap_btree.h"  #include "xfs_alloc_btree.h"  #include "xfs_ialloc_btree.h" -#include "xfs_dir_sf.h"  #include "xfs_dir2_sf.h"  #include "xfs_attr_sf.h"  #include "xfs_dinode.h" diff --git a/fs/xfs/quota/xfs_qm.c b/fs/xfs/quota/xfs_qm.c index 00fb54d4899..e23e45535c4 100644 --- a/fs/xfs/quota/xfs_qm.c +++ b/fs/xfs/quota/xfs_qm.c @@ -24,7 +24,6 @@  #include "xfs_trans.h"  #include "xfs_sb.h"  #include "xfs_ag.h" -#include "xfs_dir.h"  #include "xfs_dir2.h"  #include "xfs_alloc.h"  #include "xfs_dmapi.h" @@ -33,7 +32,6 @@  #include "xfs_bmap_btree.h"  #include "xfs_alloc_btree.h"  #include "xfs_ialloc_btree.h" -#include "xfs_dir_sf.h"  #include "xfs_dir2_sf.h"  #include "xfs_attr_sf.h"  #include "xfs_dinode.h" diff --git a/fs/xfs/quota/xfs_qm_bhv.c b/fs/xfs/quota/xfs_qm_bhv.c index d93d3a1064e..e95e99f7168 100644 --- a/fs/xfs/quota/xfs_qm_bhv.c +++ b/fs/xfs/quota/xfs_qm_bhv.c @@ -24,7 +24,6 @@  #include "xfs_trans.h"  #include "xfs_sb.h"  #include "xfs_ag.h" -#include "xfs_dir.h"  #include "xfs_dir2.h"  #include "xfs_alloc.h"  #include "xfs_dmapi.h" @@ -33,7 +32,6 @@  #include "xfs_bmap_btree.h"  #include "xfs_alloc_btree.h"  #include "xfs_ialloc_btree.h" -#include "xfs_dir_sf.h"  #include "xfs_dir2_sf.h"  #include "xfs_attr_sf.h"  #include "xfs_dinode.h" diff --git a/fs/xfs/quota/xfs_qm_stats.c b/fs/xfs/quota/xfs_qm_stats.c index 0570f773355..6f858fb81a3 100644 --- a/fs/xfs/quota/xfs_qm_stats.c +++ b/fs/xfs/quota/xfs_qm_stats.c @@ -23,7 +23,6 @@  #include "xfs_trans.h"  #include "xfs_sb.h"  #include "xfs_ag.h" -#include "xfs_dir.h"  #include "xfs_dir2.h"  #include "xfs_alloc.h"  #include "xfs_dmapi.h" @@ -32,7 +31,6 @@  #include "xfs_bmap_btree.h"  #include "xfs_alloc_btree.h"  #include "xfs_ialloc_btree.h" -#include "xfs_dir_sf.h"  #include "xfs_dir2_sf.h"  #include "xfs_attr_sf.h"  #include "xfs_dinode.h" diff --git a/fs/xfs/quota/xfs_qm_syscalls.c b/fs/xfs/quota/xfs_qm_syscalls.c index c93072be679..ed620c4d159 100644 --- a/fs/xfs/quota/xfs_qm_syscalls.c +++ b/fs/xfs/quota/xfs_qm_syscalls.c @@ -26,7 +26,6 @@  #include "xfs_trans.h"  #include "xfs_sb.h"  #include "xfs_ag.h" -#include "xfs_dir.h"  #include "xfs_dir2.h"  #include "xfs_alloc.h"  #include "xfs_dmapi.h" @@ -35,7 +34,6 @@  #include "xfs_bmap_btree.h"  #include "xfs_alloc_btree.h"  #include "xfs_ialloc_btree.h" -#include "xfs_dir_sf.h"  #include "xfs_dir2_sf.h"  #include "xfs_attr_sf.h"  #include "xfs_dinode.h" diff --git a/fs/xfs/quota/xfs_trans_dquot.c b/fs/xfs/quota/xfs_trans_dquot.c index 9168918db25..0242e9666e8 100644 --- a/fs/xfs/quota/xfs_trans_dquot.c +++ b/fs/xfs/quota/xfs_trans_dquot.c @@ -23,7 +23,6 @@  #include "xfs_trans.h"  #include "xfs_sb.h"  #include "xfs_ag.h" -#include "xfs_dir.h"  #include "xfs_dir2.h"  #include "xfs_alloc.h"  #include "xfs_dmapi.h" @@ -33,7 +32,6 @@  #include "xfs_alloc_btree.h"  #include "xfs_ialloc_btree.h"  #include "xfs_attr_sf.h" -#include "xfs_dir_sf.h"  #include "xfs_dir2_sf.h"  #include "xfs_dinode.h"  #include "xfs_inode.h" diff --git a/fs/xfs/xfs_acl.c b/fs/xfs/xfs_acl.c index e1074955386..4b0cb474be4 100644 --- a/fs/xfs/xfs_acl.c +++ b/fs/xfs/xfs_acl.c @@ -21,12 +21,10 @@  #include "xfs_bit.h"  #include "xfs_inum.h"  #include "xfs_ag.h" -#include "xfs_dir.h"  #include "xfs_dir2.h"  #include "xfs_bmap_btree.h"  #include "xfs_alloc_btree.h"  #include "xfs_ialloc_btree.h" -#include "xfs_dir_sf.h"  #include "xfs_dir2_sf.h"  #include "xfs_attr_sf.h"  #include "xfs_dinode.h" diff --git a/fs/xfs/xfs_alloc.c b/fs/xfs/xfs_alloc.c index 22af489d3f3..eef6763f3a6 100644 --- a/fs/xfs/xfs_alloc.c +++ b/fs/xfs/xfs_alloc.c @@ -24,14 +24,12 @@  #include "xfs_trans.h"  #include "xfs_sb.h"  #include "xfs_ag.h" -#include "xfs_dir.h"  #include "xfs_dir2.h"  #include "xfs_dmapi.h"  #include "xfs_mount.h"  #include "xfs_bmap_btree.h"  #include "xfs_alloc_btree.h"  #include "xfs_ialloc_btree.h" -#include "xfs_dir_sf.h"  #include "xfs_dir2_sf.h"  #include "xfs_attr_sf.h"  #include "xfs_dinode.h" diff --git a/fs/xfs/xfs_alloc_btree.c b/fs/xfs/xfs_alloc_btree.c index a1d92da86cc..7446556e802 100644 --- a/fs/xfs/xfs_alloc_btree.c +++ b/fs/xfs/xfs_alloc_btree.c @@ -24,14 +24,12 @@  #include "xfs_trans.h"  #include "xfs_sb.h"  #include "xfs_ag.h" -#include "xfs_dir.h"  #include "xfs_dir2.h"  #include "xfs_dmapi.h"  #include "xfs_mount.h"  #include "xfs_bmap_btree.h"  #include "xfs_alloc_btree.h"  #include "xfs_ialloc_btree.h" -#include "xfs_dir_sf.h"  #include "xfs_dir2_sf.h"  #include "xfs_attr_sf.h"  #include "xfs_dinode.h" diff --git a/fs/xfs/xfs_attr.c b/fs/xfs/xfs_attr.c index 4dcef8d1c32..1a210104327 100644 --- a/fs/xfs/xfs_attr.c +++ b/fs/xfs/xfs_attr.c @@ -27,7 +27,6 @@  #include "xfs_trans.h"  #include "xfs_sb.h"  #include "xfs_ag.h" -#include "xfs_dir.h"  #include "xfs_dir2.h"  #include "xfs_dmapi.h"  #include "xfs_mount.h" @@ -35,7 +34,6 @@  #include "xfs_bmap_btree.h"  #include "xfs_alloc_btree.h"  #include "xfs_ialloc_btree.h" -#include "xfs_dir_sf.h"  #include "xfs_dir2_sf.h"  #include "xfs_attr_sf.h"  #include "xfs_dinode.h" diff --git a/fs/xfs/xfs_attr_leaf.c b/fs/xfs/xfs_attr_leaf.c index 5c44343d4a3..9455051f012 100644 --- a/fs/xfs/xfs_attr_leaf.c +++ b/fs/xfs/xfs_attr_leaf.c @@ -24,7 +24,6 @@  #include "xfs_trans.h"  #include "xfs_sb.h"  #include "xfs_ag.h" -#include "xfs_dir.h"  #include "xfs_dir2.h"  #include "xfs_dmapi.h"  #include "xfs_mount.h" @@ -34,7 +33,6 @@  #include "xfs_ialloc_btree.h"  #include "xfs_alloc.h"  #include "xfs_btree.h" -#include "xfs_dir_sf.h"  #include "xfs_dir2_sf.h"  #include "xfs_attr_sf.h"  #include "xfs_dinode.h" diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c index 4d0ca14039a..3a613753906 100644 --- a/fs/xfs/xfs_bmap.c +++ b/fs/xfs/xfs_bmap.c @@ -24,13 +24,11 @@  #include "xfs_trans.h"  #include "xfs_sb.h"  #include "xfs_ag.h" -#include "xfs_dir.h"  #include "xfs_dir2.h"  #include "xfs_da_btree.h"  #include "xfs_bmap_btree.h"  #include "xfs_alloc_btree.h"  #include "xfs_ialloc_btree.h" -#include "xfs_dir_sf.h"  #include "xfs_dir2_sf.h"  #include "xfs_attr_sf.h"  #include "xfs_dinode.h" @@ -40,13 +38,15 @@  #include "xfs_mount.h"  #include "xfs_ialloc.h"  #include "xfs_itable.h" +#include "xfs_dir2_data.h" +#include "xfs_dir2_leaf.h" +#include "xfs_dir2_block.h"  #include "xfs_inode_item.h"  #include "xfs_extfree_item.h"  #include "xfs_alloc.h"  #include "xfs_bmap.h"  #include "xfs_rtalloc.h"  #include "xfs_error.h" -#include "xfs_dir_leaf.h"  #include "xfs_attr_leaf.h"  #include "xfs_rw.h"  #include "xfs_quota.h" @@ -516,7 +516,7 @@ xfs_bmap_add_attrfork_local(  		dargs.total = mp->m_dirblkfsbs;  		dargs.whichfork = XFS_DATA_FORK;  		dargs.trans = tp; -		error = XFS_DIR_SHORTFORM_TO_SINGLE(mp, &dargs); +		error = xfs_dir2_sf_to_block(&dargs);  	} else  		error = xfs_bmap_local_to_extents(tp, ip, firstblock, 1, flags,  			XFS_DATA_FORK); diff --git a/fs/xfs/xfs_bmap_btree.c b/fs/xfs/xfs_bmap_btree.c index 3b6dfc9b53a..18fb7385d71 100644 --- a/fs/xfs/xfs_bmap_btree.c +++ b/fs/xfs/xfs_bmap_btree.c @@ -24,14 +24,12 @@  #include "xfs_trans.h"  #include "xfs_sb.h"  #include "xfs_ag.h" -#include "xfs_dir.h"  #include "xfs_dir2.h"  #include "xfs_dmapi.h"  #include "xfs_mount.h"  #include "xfs_bmap_btree.h"  #include "xfs_alloc_btree.h"  #include "xfs_ialloc_btree.h" -#include "xfs_dir_sf.h"  #include "xfs_dir2_sf.h"  #include "xfs_attr_sf.h"  #include "xfs_dinode.h" diff --git a/fs/xfs/xfs_btree.c b/fs/xfs/xfs_btree.c index 52d5d095fc3..ee2255bd656 100644 --- a/fs/xfs/xfs_btree.c +++ b/fs/xfs/xfs_btree.c @@ -24,14 +24,12 @@  #include "xfs_trans.h"  #include "xfs_sb.h"  #include "xfs_ag.h" -#include "xfs_dir.h"  #include "xfs_dir2.h"  #include "xfs_dmapi.h"  #include "xfs_mount.h"  #include "xfs_bmap_btree.h"  #include "xfs_alloc_btree.h"  #include "xfs_ialloc_btree.h" -#include "xfs_dir_sf.h"  #include "xfs_dir2_sf.h"  #include "xfs_attr_sf.h"  #include "xfs_dinode.h" diff --git a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c index 290912cbff6..a4aa53974f7 100644 --- a/fs/xfs/xfs_buf_item.c +++ b/fs/xfs/xfs_buf_item.c @@ -23,7 +23,6 @@  #include "xfs_inum.h"  #include "xfs_trans.h"  #include "xfs_sb.h" -#include "xfs_dir.h"  #include "xfs_dmapi.h"  #include "xfs_mount.h"  #include "xfs_buf_item.h" diff --git a/fs/xfs/xfs_da_btree.c b/fs/xfs/xfs_da_btree.c index 260c3d770c0..32ab61d17ac 100644 --- a/fs/xfs/xfs_da_btree.c +++ b/fs/xfs/xfs_da_btree.c @@ -24,7 +24,6 @@  #include "xfs_trans.h"  #include "xfs_sb.h"  #include "xfs_ag.h" -#include "xfs_dir.h"  #include "xfs_dir2.h"  #include "xfs_dmapi.h"  #include "xfs_mount.h" @@ -32,7 +31,6 @@  #include "xfs_bmap_btree.h"  #include "xfs_alloc_btree.h"  #include "xfs_ialloc_btree.h" -#include "xfs_dir_sf.h"  #include "xfs_dir2_sf.h"  #include "xfs_attr_sf.h"  #include "xfs_dinode.h" @@ -43,7 +41,6 @@  #include "xfs_bmap.h"  #include "xfs_attr.h"  #include "xfs_attr_leaf.h" -#include "xfs_dir_leaf.h"  #include "xfs_dir2_data.h"  #include "xfs_dir2_leaf.h"  #include "xfs_dir2_block.h" @@ -159,7 +156,7 @@ xfs_da_split(xfs_da_state_t *state)  	max = state->path.active - 1;  	ASSERT((max >= 0) && (max < XFS_DA_NODE_MAXDEPTH));  	ASSERT(state->path.blk[max].magic == XFS_ATTR_LEAF_MAGIC || -	       state->path.blk[max].magic == XFS_DIRX_LEAF_MAGIC(state->mp)); +	       state->path.blk[max].magic == XFS_DIR2_LEAFN_MAGIC);  	addblk = &state->path.blk[max];		/* initial dummy value */  	for (i = max; (i >= 0) && addblk; state->path.active--, i--) { @@ -199,38 +196,7 @@ xfs_da_split(xfs_da_state_t *state)  				return(error);	/* GROT: attr inconsistent */  			addblk = newblk;  			break; -		case XFS_DIR_LEAF_MAGIC: -			ASSERT(XFS_DIR_IS_V1(state->mp)); -			error = xfs_dir_leaf_split(state, oldblk, newblk); -			if ((error != 0) && (error != ENOSPC)) { -				return(error);	/* GROT: dir is inconsistent */ -			} -			if (!error) { -				addblk = newblk; -				break; -			} -			/* -			 * Entry wouldn't fit, split the leaf again. -			 */ -			state->extravalid = 1; -			if (state->inleaf) { -				state->extraafter = 0;	/* before newblk */ -				error = xfs_dir_leaf_split(state, oldblk, -							   &state->extrablk); -				if (error) -					return(error);	/* GROT: dir incon. */ -				addblk = newblk; -			} else { -				state->extraafter = 1;	/* after newblk */ -				error = xfs_dir_leaf_split(state, newblk, -							   &state->extrablk); -				if (error) -					return(error);	/* GROT: dir incon. */ -				addblk = newblk; -			} -			break;  		case XFS_DIR2_LEAFN_MAGIC: -			ASSERT(XFS_DIR_IS_V2(state->mp));  			error = xfs_dir2_leafn_split(state, oldblk, newblk);  			if (error)  				return error; @@ -363,7 +329,6 @@ xfs_da_root_split(xfs_da_state_t *state, xfs_da_state_blk_t *blk1,  		size = (int)((char *)&oldroot->btree[be16_to_cpu(oldroot->hdr.count)] -  			     (char *)oldroot);  	} else { -		ASSERT(XFS_DIR_IS_V2(mp));  		ASSERT(be16_to_cpu(oldroot->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC);  		leaf = (xfs_dir2_leaf_t *)oldroot;  		size = (int)((char *)&leaf->ents[be16_to_cpu(leaf->hdr.count)] - @@ -379,8 +344,7 @@ xfs_da_root_split(xfs_da_state_t *state, xfs_da_state_blk_t *blk1,  	 * Set up the new root node.  	 */  	error = xfs_da_node_create(args, -		args->whichfork == XFS_DATA_FORK && -		XFS_DIR_IS_V2(mp) ? mp->m_dirleafblk : 0, +		(args->whichfork == XFS_DATA_FORK) ? mp->m_dirleafblk : 0,  		be16_to_cpu(node->hdr.level) + 1, &bp, args->whichfork);  	if (error)  		return(error); @@ -427,10 +391,9 @@ xfs_da_node_split(xfs_da_state_t *state, xfs_da_state_blk_t *oldblk,  	ASSERT(be16_to_cpu(node->hdr.info.magic) == XFS_DA_NODE_MAGIC);  	/* -	 * With V2 the extra block is data or freespace. +	 * With V2 dirs the extra block is data or freespace.  	 */ -	useextra = state->extravalid && (XFS_DIR_IS_V1(state->mp) || -			state->args->whichfork == XFS_ATTR_FORK); +	useextra = state->extravalid && state->args->whichfork == XFS_ATTR_FORK;  	newcount = 1 + useextra;  	/*  	 * Do we have to split the node? @@ -624,7 +587,7 @@ xfs_da_node_add(xfs_da_state_t *state, xfs_da_state_blk_t *oldblk,  	ASSERT(be16_to_cpu(node->hdr.info.magic) == XFS_DA_NODE_MAGIC);  	ASSERT((oldblk->index >= 0) && (oldblk->index <= be16_to_cpu(node->hdr.count)));  	ASSERT(newblk->blkno != 0); -	if (state->args->whichfork == XFS_DATA_FORK && XFS_DIR_IS_V2(mp)) +	if (state->args->whichfork == XFS_DATA_FORK)  		ASSERT(newblk->blkno >= mp->m_dirleafblk &&  		       newblk->blkno < mp->m_dirfreeblk); @@ -670,7 +633,7 @@ xfs_da_join(xfs_da_state_t *state)  	save_blk = &state->altpath.blk[ state->path.active-1 ];  	ASSERT(state->path.blk[0].magic == XFS_DA_NODE_MAGIC);  	ASSERT(drop_blk->magic == XFS_ATTR_LEAF_MAGIC || -	       drop_blk->magic == XFS_DIRX_LEAF_MAGIC(state->mp)); +	       drop_blk->magic == XFS_DIR2_LEAFN_MAGIC);  	/*  	 * Walk back up the tree joining/deallocating as necessary. @@ -693,17 +656,7 @@ xfs_da_join(xfs_da_state_t *state)  				return(0);  			xfs_attr_leaf_unbalance(state, drop_blk, save_blk);  			break; -		case XFS_DIR_LEAF_MAGIC: -			ASSERT(XFS_DIR_IS_V1(state->mp)); -			error = xfs_dir_leaf_toosmall(state, &action); -			if (error) -				return(error); -			if (action == 0) -				return(0); -			xfs_dir_leaf_unbalance(state, drop_blk, save_blk); -			break;  		case XFS_DIR2_LEAFN_MAGIC: -			ASSERT(XFS_DIR_IS_V2(state->mp));  			error = xfs_dir2_leafn_toosmall(state, &action);  			if (error)  				return error; @@ -790,7 +743,7 @@ xfs_da_root_join(xfs_da_state_t *state, xfs_da_state_blk_t *root_blk)  	ASSERT(bp != NULL);  	blkinfo = bp->data;  	if (be16_to_cpu(oldroot->hdr.level) == 1) { -		ASSERT(be16_to_cpu(blkinfo->magic) == XFS_DIRX_LEAF_MAGIC(state->mp) || +		ASSERT(be16_to_cpu(blkinfo->magic) == XFS_DIR2_LEAFN_MAGIC ||  		       be16_to_cpu(blkinfo->magic) == XFS_ATTR_LEAF_MAGIC);  	} else {  		ASSERT(be16_to_cpu(blkinfo->magic) == XFS_DA_NODE_MAGIC); @@ -951,14 +904,7 @@ xfs_da_fixhashpath(xfs_da_state_t *state, xfs_da_state_path_t *path)  		if (count == 0)  			return;  		break; -	case XFS_DIR_LEAF_MAGIC: -		ASSERT(XFS_DIR_IS_V1(state->mp)); -		lasthash = xfs_dir_leaf_lasthash(blk->bp, &count); -		if (count == 0) -			return; -		break;  	case XFS_DIR2_LEAFN_MAGIC: -		ASSERT(XFS_DIR_IS_V2(state->mp));  		lasthash = xfs_dir2_leafn_lasthash(blk->bp, &count);  		if (count == 0)  			return; @@ -1117,10 +1063,7 @@ xfs_da_node_lookup_int(xfs_da_state_t *state, int *result)  	 * Descend thru the B-tree searching each level for the right  	 * node to use, until the right hashval is found.  	 */ -	if (args->whichfork == XFS_DATA_FORK && XFS_DIR_IS_V2(state->mp)) -		blkno = state->mp->m_dirleafblk; -	else -		blkno = 0; +	blkno = (args->whichfork == XFS_DATA_FORK)? state->mp->m_dirleafblk : 0;  	for (blk = &state->path.blk[0], state->path.active = 1;  			 state->path.active <= XFS_DA_NODE_MAXDEPTH;  			 blk++, state->path.active++) { @@ -1137,7 +1080,7 @@ xfs_da_node_lookup_int(xfs_da_state_t *state, int *result)  		}  		curr = blk->bp->data;  		ASSERT(be16_to_cpu(curr->magic) == XFS_DA_NODE_MAGIC || -		       be16_to_cpu(curr->magic) == XFS_DIRX_LEAF_MAGIC(state->mp) || +		       be16_to_cpu(curr->magic) == XFS_DIR2_LEAFN_MAGIC ||  		       be16_to_cpu(curr->magic) == XFS_ATTR_LEAF_MAGIC);  		/* @@ -1190,16 +1133,10 @@ xfs_da_node_lookup_int(xfs_da_state_t *state, int *result)  				blk->index = probe;  				blkno = be32_to_cpu(btree->before);  			} -		} -		else if (be16_to_cpu(curr->magic) == XFS_ATTR_LEAF_MAGIC) { +		} else if (be16_to_cpu(curr->magic) == XFS_ATTR_LEAF_MAGIC) {  			blk->hashval = xfs_attr_leaf_lasthash(blk->bp, NULL);  			break; -		} -		else if (be16_to_cpu(curr->magic) == XFS_DIR_LEAF_MAGIC) { -			blk->hashval = xfs_dir_leaf_lasthash(blk->bp, NULL); -			break; -		} -		else if (be16_to_cpu(curr->magic) == XFS_DIR2_LEAFN_MAGIC) { +		} else if (be16_to_cpu(curr->magic) == XFS_DIR2_LEAFN_MAGIC) {  			blk->hashval = xfs_dir2_leafn_lasthash(blk->bp, NULL);  			break;  		} @@ -1212,12 +1149,7 @@ xfs_da_node_lookup_int(xfs_da_state_t *state, int *result)  	 * next leaf and keep searching.  	 */  	for (;;) { -		if (blk->magic == XFS_DIR_LEAF_MAGIC) { -			ASSERT(XFS_DIR_IS_V1(state->mp)); -			retval = xfs_dir_leaf_lookup_int(blk->bp, args, -								  &blk->index); -		} else if (blk->magic == XFS_DIR2_LEAFN_MAGIC) { -			ASSERT(XFS_DIR_IS_V2(state->mp)); +		if (blk->magic == XFS_DIR2_LEAFN_MAGIC) {  			retval = xfs_dir2_leafn_lookup_int(blk->bp, args,  							&blk->index, state);  		} @@ -1270,7 +1202,7 @@ xfs_da_blk_link(xfs_da_state_t *state, xfs_da_state_blk_t *old_blk,  	old_info = old_blk->bp->data;  	new_info = new_blk->bp->data;  	ASSERT(old_blk->magic == XFS_DA_NODE_MAGIC || -	       old_blk->magic == XFS_DIRX_LEAF_MAGIC(state->mp) || +	       old_blk->magic == XFS_DIR2_LEAFN_MAGIC ||  	       old_blk->magic == XFS_ATTR_LEAF_MAGIC);  	ASSERT(old_blk->magic == be16_to_cpu(old_info->magic));  	ASSERT(new_blk->magic == be16_to_cpu(new_info->magic)); @@ -1280,12 +1212,7 @@ xfs_da_blk_link(xfs_da_state_t *state, xfs_da_state_blk_t *old_blk,  	case XFS_ATTR_LEAF_MAGIC:  		before = xfs_attr_leaf_order(old_blk->bp, new_blk->bp);  		break; -	case XFS_DIR_LEAF_MAGIC: -		ASSERT(XFS_DIR_IS_V1(state->mp)); -		before = xfs_dir_leaf_order(old_blk->bp, new_blk->bp); -		break;  	case XFS_DIR2_LEAFN_MAGIC: -		ASSERT(XFS_DIR_IS_V2(state->mp));  		before = xfs_dir2_leafn_order(old_blk->bp, new_blk->bp);  		break;  	case XFS_DA_NODE_MAGIC: @@ -1404,7 +1331,7 @@ xfs_da_blk_unlink(xfs_da_state_t *state, xfs_da_state_blk_t *drop_blk,  	save_info = save_blk->bp->data;  	drop_info = drop_blk->bp->data;  	ASSERT(save_blk->magic == XFS_DA_NODE_MAGIC || -	       save_blk->magic == XFS_DIRX_LEAF_MAGIC(state->mp) || +	       save_blk->magic == XFS_DIR2_LEAFN_MAGIC ||  	       save_blk->magic == XFS_ATTR_LEAF_MAGIC);  	ASSERT(save_blk->magic == be16_to_cpu(save_info->magic));  	ASSERT(drop_blk->magic == be16_to_cpu(drop_info->magic)); @@ -1529,7 +1456,7 @@ xfs_da_path_shift(xfs_da_state_t *state, xfs_da_state_path_t *path,  		ASSERT(blk->bp != NULL);  		info = blk->bp->data;  		ASSERT(be16_to_cpu(info->magic) == XFS_DA_NODE_MAGIC || -		       be16_to_cpu(info->magic) == XFS_DIRX_LEAF_MAGIC(state->mp) || +		       be16_to_cpu(info->magic) == XFS_DIR2_LEAFN_MAGIC ||  		       be16_to_cpu(info->magic) == XFS_ATTR_LEAF_MAGIC);  		blk->magic = be16_to_cpu(info->magic);  		if (blk->magic == XFS_DA_NODE_MAGIC) { @@ -1548,20 +1475,13 @@ xfs_da_path_shift(xfs_da_state_t *state, xfs_da_state_path_t *path,  				blk->hashval = xfs_attr_leaf_lasthash(blk->bp,  								      NULL);  				break; -			case XFS_DIR_LEAF_MAGIC: -				ASSERT(XFS_DIR_IS_V1(state->mp)); -				blk->hashval = xfs_dir_leaf_lasthash(blk->bp, -								     NULL); -				break;  			case XFS_DIR2_LEAFN_MAGIC: -				ASSERT(XFS_DIR_IS_V2(state->mp));  				blk->hashval = xfs_dir2_leafn_lasthash(blk->bp,  								       NULL);  				break;  			default:  				ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC || -				       blk->magic == -				       XFS_DIRX_LEAF_MAGIC(state->mp)); +				       blk->magic == XFS_DIR2_LEAFN_MAGIC);  				break;  			}  		} @@ -1620,7 +1540,6 @@ xfs_da_grow_inode(xfs_da_args_t *args, xfs_dablk_t *new_blkno)  	xfs_bmbt_irec_t	*mapp;  	xfs_inode_t *dp;  	int nmap, error, w, count, c, got, i, mapi; -	xfs_fsize_t size;  	xfs_trans_t *tp;  	xfs_mount_t *mp; @@ -1631,7 +1550,7 @@ xfs_da_grow_inode(xfs_da_args_t *args, xfs_dablk_t *new_blkno)  	/*  	 * For new directories adjust the file offset and block count.  	 */ -	if (w == XFS_DATA_FORK && XFS_DIR_IS_V2(mp)) { +	if (w == XFS_DATA_FORK) {  		bno = mp->m_dirleafblk;  		count = mp->m_dirblkfsbs;  	} else { @@ -1641,10 +1560,9 @@ xfs_da_grow_inode(xfs_da_args_t *args, xfs_dablk_t *new_blkno)  	/*  	 * Find a spot in the file space to put the new block.  	 */ -	if ((error = xfs_bmap_first_unused(tp, dp, count, &bno, w))) { +	if ((error = xfs_bmap_first_unused(tp, dp, count, &bno, w)))  		return error; -	} -	if (w == XFS_DATA_FORK && XFS_DIR_IS_V2(mp)) +	if (w == XFS_DATA_FORK)  		ASSERT(bno >= mp->m_dirleafblk && bno < mp->m_dirfreeblk);  	/*  	 * Try mapping it in one filesystem block. @@ -1706,19 +1624,6 @@ xfs_da_grow_inode(xfs_da_args_t *args, xfs_dablk_t *new_blkno)  	if (mapp != &map)  		kmem_free(mapp, sizeof(*mapp) * count);  	*new_blkno = (xfs_dablk_t)bno; -	/* -	 * For version 1 directories, adjust the file size if it changed. -	 */ -	if (w == XFS_DATA_FORK && XFS_DIR_IS_V1(mp)) { -		ASSERT(mapi == 1); -		if ((error = xfs_bmap_last_offset(tp, dp, &bno, w))) -			return error; -		size = XFS_FSB_TO_B(mp, bno); -		if (size != dp->i_d.di_size) { -			dp->i_d.di_size = size; -			xfs_trans_log_inode(tp, dp, XFS_ILOG_CORE); -		} -	}  	return 0;  } @@ -1743,7 +1648,6 @@ xfs_da_swap_lastblock(xfs_da_args_t *args, xfs_dablk_t *dead_blknop,  	int error, w, entno, level, dead_level;  	xfs_da_blkinfo_t *dead_info, *sib_info;  	xfs_da_intnode_t *par_node, *dead_node; -	xfs_dir_leafblock_t *dead_leaf;  	xfs_dir2_leaf_t *dead_leaf2;  	xfs_dahash_t dead_hash; @@ -1754,11 +1658,8 @@ xfs_da_swap_lastblock(xfs_da_args_t *args, xfs_dablk_t *dead_blknop,  	w = args->whichfork;  	ASSERT(w == XFS_DATA_FORK);  	mp = ip->i_mount; -	if (XFS_DIR_IS_V2(mp)) { -		lastoff = mp->m_dirfreeblk; -		error = xfs_bmap_last_before(tp, ip, &lastoff, w); -	} else -		error = xfs_bmap_last_offset(tp, ip, &lastoff, w); +	lastoff = mp->m_dirfreeblk; +	error = xfs_bmap_last_before(tp, ip, &lastoff, w);  	if (error)  		return error;  	if (unlikely(lastoff == 0)) { @@ -1781,14 +1682,7 @@ xfs_da_swap_lastblock(xfs_da_args_t *args, xfs_dablk_t *dead_blknop,  	/*  	 * Get values from the moved block.  	 */ -	if (be16_to_cpu(dead_info->magic) == XFS_DIR_LEAF_MAGIC) { -		ASSERT(XFS_DIR_IS_V1(mp)); -		dead_leaf = (xfs_dir_leafblock_t *)dead_info; -		dead_level = 0; -		dead_hash = be32_to_cpu(dead_leaf->entries[ -				be16_to_cpu(dead_leaf->hdr.count) - 1].hashval); -	} else if (be16_to_cpu(dead_info->magic) == XFS_DIR2_LEAFN_MAGIC) { -		ASSERT(XFS_DIR_IS_V2(mp)); +	if (be16_to_cpu(dead_info->magic) == XFS_DIR2_LEAFN_MAGIC) {  		dead_leaf2 = (xfs_dir2_leaf_t *)dead_info;  		dead_level = 0;  		dead_hash = be32_to_cpu(dead_leaf2->ents[be16_to_cpu(dead_leaf2->hdr.count) - 1].hashval); @@ -1843,7 +1737,7 @@ xfs_da_swap_lastblock(xfs_da_args_t *args, xfs_dablk_t *dead_blknop,  		xfs_da_buf_done(sib_buf);  		sib_buf = NULL;  	} -	par_blkno = XFS_DIR_IS_V1(mp) ? 0 : mp->m_dirleafblk; +	par_blkno = mp->m_dirleafblk;  	level = -1;  	/*  	 * Walk down the tree looking for the parent of the moved block. @@ -1942,8 +1836,6 @@ xfs_da_shrink_inode(xfs_da_args_t *args, xfs_dablk_t dead_blkno,  {  	xfs_inode_t *dp;  	int done, error, w, count; -	xfs_fileoff_t bno; -	xfs_fsize_t size;  	xfs_trans_t *tp;  	xfs_mount_t *mp; @@ -1951,7 +1843,7 @@ xfs_da_shrink_inode(xfs_da_args_t *args, xfs_dablk_t dead_blkno,  	w = args->whichfork;  	tp = args->trans;  	mp = dp->i_mount; -	if (w == XFS_DATA_FORK && XFS_DIR_IS_V2(mp)) +	if (w == XFS_DATA_FORK)  		count = mp->m_dirblkfsbs;  	else  		count = 1; @@ -1965,31 +1857,14 @@ xfs_da_shrink_inode(xfs_da_args_t *args, xfs_dablk_t dead_blkno,  				0, args->firstblock, args->flist, NULL,  				&done)) == ENOSPC) {  			if (w != XFS_DATA_FORK) -				goto done; +				break;  			if ((error = xfs_da_swap_lastblock(args, &dead_blkno,  					&dead_buf))) -				goto done; -		} else if (error) -			goto done; -		else +				break; +		} else {  			break; -	} -	ASSERT(done); -	xfs_da_binval(tp, dead_buf); -	/* -	 * Adjust the directory size for version 1. -	 */ -	if (w == XFS_DATA_FORK && XFS_DIR_IS_V1(mp)) { -		if ((error = xfs_bmap_last_offset(tp, dp, &bno, w))) -			return error; -		size = XFS_FSB_TO_B(dp->i_mount, bno); -		if (size != dp->i_d.di_size) { -			dp->i_d.di_size = size; -			xfs_trans_log_inode(tp, dp, XFS_ILOG_CORE);  		}  	} -	return 0; -done:  	xfs_da_binval(tp, dead_buf);  	return error;  } @@ -2050,10 +1925,7 @@ xfs_da_do_buf(  	xfs_dabuf_t	*rbp;  	mp = dp->i_mount; -	if (whichfork == XFS_DATA_FORK && XFS_DIR_IS_V2(mp)) -		nfsb = mp->m_dirblkfsbs; -	else -		nfsb = 1; +	nfsb = (whichfork == XFS_DATA_FORK) ? mp->m_dirblkfsbs : 1;  	mappedbno = *mappedbnop;  	/*  	 * Caller doesn't have a mapping.  -2 means don't complain @@ -2199,7 +2071,6 @@ xfs_da_do_buf(  		magic1 = be32_to_cpu(data->hdr.magic);  		if (unlikely(  		    XFS_TEST_ERROR((magic != XFS_DA_NODE_MAGIC) && -				   (magic != XFS_DIR_LEAF_MAGIC) &&  				   (magic != XFS_ATTR_LEAF_MAGIC) &&  				   (magic != XFS_DIR2_LEAF1_MAGIC) &&  				   (magic != XFS_DIR2_LEAFN_MAGIC) && diff --git a/fs/xfs/xfs_da_btree.h b/fs/xfs/xfs_da_btree.h index 243a730d5ec..4ab865ec8b8 100644 --- a/fs/xfs/xfs_da_btree.h +++ b/fs/xfs/xfs_da_btree.h @@ -36,14 +36,10 @@ struct zone;   * level in the Btree, and to identify which type of block this is.   */  #define XFS_DA_NODE_MAGIC	0xfebe	/* magic number: non-leaf blocks */ -#define XFS_DIR_LEAF_MAGIC	0xfeeb	/* magic number: directory leaf blks */  #define XFS_ATTR_LEAF_MAGIC	0xfbee	/* magic number: attribute leaf blks */  #define	XFS_DIR2_LEAF1_MAGIC	0xd2f1	/* magic number: v2 dirlf single blks */  #define	XFS_DIR2_LEAFN_MAGIC	0xd2ff	/* magic number: v2 dirlf multi blks */ -#define	XFS_DIRX_LEAF_MAGIC(mp)	\ -	(XFS_DIR_IS_V1(mp) ? XFS_DIR_LEAF_MAGIC : XFS_DIR2_LEAFN_MAGIC) -  typedef struct xfs_da_blkinfo {  	__be32		forw;			/* previous block in list */  	__be32		back;			/* following block in list */ diff --git a/fs/xfs/xfs_dfrag.c b/fs/xfs/xfs_dfrag.c index 29a6c866f2c..80562b60fb9 100644 --- a/fs/xfs/xfs_dfrag.c +++ b/fs/xfs/xfs_dfrag.c @@ -24,14 +24,12 @@  #include "xfs_trans.h"  #include "xfs_sb.h"  #include "xfs_ag.h" -#include "xfs_dir.h"  #include "xfs_dir2.h"  #include "xfs_dmapi.h"  #include "xfs_mount.h"  #include "xfs_bmap_btree.h"  #include "xfs_alloc_btree.h"  #include "xfs_ialloc_btree.h" -#include "xfs_dir_sf.h"  #include "xfs_dir2_sf.h"  #include "xfs_attr_sf.h"  #include "xfs_dinode.h" diff --git a/fs/xfs/xfs_dinode.h b/fs/xfs/xfs_dinode.h index 77d53778258..b33826961c4 100644 --- a/fs/xfs/xfs_dinode.h +++ b/fs/xfs/xfs_dinode.h @@ -85,7 +85,6 @@ typedef struct xfs_dinode  	union {  		xfs_bmdr_block_t di_bmbt;	/* btree root block */  		xfs_bmbt_rec_32_t di_bmx[1];	/* extent list */ -		xfs_dir_shortform_t di_dirsf;	/* shortform directory */  		xfs_dir2_sf_t	di_dir2sf;	/* shortform directory v2 */  		char		di_c[1];	/* local contents */  		xfs_dev_t	di_dev;		/* device for S_IFCHR/S_IFBLK */ diff --git a/fs/xfs/xfs_dir.c b/fs/xfs/xfs_dir.c index 3cd8657a81f..e69de29bb2d 100644 --- a/fs/xfs/xfs_dir.c +++ b/fs/xfs/xfs_dir.c @@ -1,1213 +0,0 @@ -/* - * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. - * All Rights Reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it would be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write the Free Software Foundation, - * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA - */ -#include "xfs.h" -#include "xfs_fs.h" -#include "xfs_types.h" -#include "xfs_log.h" -#include "xfs_inum.h" -#include "xfs_trans.h" -#include "xfs_sb.h" -#include "xfs_dir.h" -#include "xfs_dir2.h" -#include "xfs_dmapi.h" -#include "xfs_mount.h" -#include "xfs_da_btree.h" -#include "xfs_bmap_btree.h" -#include "xfs_alloc_btree.h" -#include "xfs_ialloc_btree.h" -#include "xfs_alloc.h" -#include "xfs_btree.h" -#include "xfs_dir_sf.h" -#include "xfs_dir2_sf.h" -#include "xfs_attr_sf.h" -#include "xfs_dinode.h" -#include "xfs_inode.h" -#include "xfs_bmap.h" -#include "xfs_dir_leaf.h" -#include "xfs_error.h" - -/* - * xfs_dir.c - * - * Provide the external interfaces to manage directories. - */ - -/*======================================================================== - * Function prototypes for the kernel. - *========================================================================*/ - -/* - * Functions for the dirops interfaces. - */ -static void	xfs_dir_mount(struct xfs_mount *mp); - -static int	xfs_dir_isempty(struct xfs_inode *dp); - -static int	xfs_dir_init(struct xfs_trans *trans, -			     struct xfs_inode *dir, -			     struct xfs_inode *parent_dir); - -static int	xfs_dir_createname(struct xfs_trans *trans, -				   struct xfs_inode *dp, -				   char *name_string, -				   int name_len, -				   xfs_ino_t inode_number, -				   xfs_fsblock_t *firstblock, -				   xfs_bmap_free_t *flist, -				   xfs_extlen_t total); - -static int	xfs_dir_lookup(struct xfs_trans *tp, -			       struct xfs_inode *dp, -			       char *name_string, -			       int name_length, -			       xfs_ino_t *inode_number); - -static int	xfs_dir_removename(struct xfs_trans *trans, -				   struct xfs_inode *dp, -				   char *name_string, -				   int name_length, -				   xfs_ino_t ino, -				   xfs_fsblock_t *firstblock, -				   xfs_bmap_free_t *flist, -				   xfs_extlen_t total); - -static int	xfs_dir_getdents(struct xfs_trans *tp, -				 struct xfs_inode *dp, -				 struct uio *uiop, -				 int *eofp); - -static int	xfs_dir_replace(struct xfs_trans *tp, -				struct xfs_inode *dp, -				char *name_string, -				int name_length, -				xfs_ino_t inode_number, -				xfs_fsblock_t *firstblock, -				xfs_bmap_free_t *flist, -				xfs_extlen_t total); - -static int	xfs_dir_canenter(struct xfs_trans *tp, -				 struct xfs_inode *dp, -				 char *name_string, -				 int name_length); - -static int	xfs_dir_shortform_validate_ondisk(xfs_mount_t *mp, -						  xfs_dinode_t *dip); - -xfs_dirops_t xfsv1_dirops = { -	.xd_mount			= xfs_dir_mount, -	.xd_isempty			= xfs_dir_isempty, -	.xd_init			= xfs_dir_init, -	.xd_createname			= xfs_dir_createname, -	.xd_lookup			= xfs_dir_lookup, -	.xd_removename			= xfs_dir_removename, -	.xd_getdents			= xfs_dir_getdents, -	.xd_replace			= xfs_dir_replace, -	.xd_canenter			= xfs_dir_canenter, -	.xd_shortform_validate_ondisk	= xfs_dir_shortform_validate_ondisk, -	.xd_shortform_to_single		= xfs_dir_shortform_to_leaf, -}; - -/* - * Internal routines when dirsize == XFS_LBSIZE(mp). - */ -STATIC int xfs_dir_leaf_lookup(xfs_da_args_t *args); -STATIC int xfs_dir_leaf_removename(xfs_da_args_t *args, int *number_entries, -						 int *total_namebytes); -STATIC int xfs_dir_leaf_getdents(xfs_trans_t *trans, xfs_inode_t *dp, -					     uio_t *uio, int *eofp, -					     xfs_dirent_t *dbp, -					     xfs_dir_put_t put); -STATIC int xfs_dir_leaf_replace(xfs_da_args_t *args); - -/* - * Internal routines when dirsize > XFS_LBSIZE(mp). - */ -STATIC int xfs_dir_node_addname(xfs_da_args_t *args); -STATIC int xfs_dir_node_lookup(xfs_da_args_t *args); -STATIC int xfs_dir_node_removename(xfs_da_args_t *args); -STATIC int xfs_dir_node_getdents(xfs_trans_t *trans, xfs_inode_t *dp, -					     uio_t *uio, int *eofp, -					     xfs_dirent_t *dbp, -					     xfs_dir_put_t put); -STATIC int xfs_dir_node_replace(xfs_da_args_t *args); - -#if defined(XFS_DIR_TRACE) -ktrace_t *xfs_dir_trace_buf; -#endif - - -/*======================================================================== - * Overall external interface routines. - *========================================================================*/ - -xfs_dahash_t	xfs_dir_hash_dot, xfs_dir_hash_dotdot; - -/* - * One-time startup routine called from xfs_init(). - */ -void -xfs_dir_startup(void) -{ -	xfs_dir_hash_dot = xfs_da_hashname(".", 1); -	xfs_dir_hash_dotdot = xfs_da_hashname("..", 2); -} - -/* - * Initialize directory-related fields in the mount structure. - */ -static void -xfs_dir_mount(xfs_mount_t *mp) -{ -	uint shortcount, leafcount, count; - -	mp->m_dirversion = 1; -	if (!(mp->m_flags & XFS_MOUNT_ATTR2)) { -		shortcount = (mp->m_attroffset - -				(uint)sizeof(xfs_dir_sf_hdr_t)) / -				 (uint)sizeof(xfs_dir_sf_entry_t); -		leafcount = (XFS_LBSIZE(mp) - -				(uint)sizeof(xfs_dir_leaf_hdr_t)) / -				 ((uint)sizeof(xfs_dir_leaf_entry_t) + -				  (uint)sizeof(xfs_dir_leaf_name_t)); -	} else { -		shortcount = (XFS_BMDR_SPACE_CALC(MINABTPTRS) - -			      (uint)sizeof(xfs_dir_sf_hdr_t)) / -			       (uint)sizeof(xfs_dir_sf_entry_t); -		leafcount = (XFS_LBSIZE(mp) - -			    (uint)sizeof(xfs_dir_leaf_hdr_t)) / -			     ((uint)sizeof(xfs_dir_leaf_entry_t) + -			      (uint)sizeof(xfs_dir_leaf_name_t)); -	} -	count = shortcount > leafcount ? shortcount : leafcount; -	mp->m_dircook_elog = xfs_da_log2_roundup(count + 1); -	ASSERT(mp->m_dircook_elog <= mp->m_sb.sb_blocklog); -	mp->m_dir_node_ents = mp->m_attr_node_ents = -		(XFS_LBSIZE(mp) - (uint)sizeof(xfs_da_node_hdr_t)) / -		(uint)sizeof(xfs_da_node_entry_t); -	mp->m_dir_magicpct = (XFS_LBSIZE(mp) * 37) / 100; -	mp->m_dirblksize = mp->m_sb.sb_blocksize; -	mp->m_dirblkfsbs = 1; -} - -/* - * Return 1 if directory contains only "." and "..". - */ -static int -xfs_dir_isempty(xfs_inode_t *dp) -{ -	xfs_dir_sf_hdr_t *hdr; - -	ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); -	if (dp->i_d.di_size == 0) -		return(1); -	if (dp->i_d.di_size > XFS_IFORK_DSIZE(dp)) -		return(0); -	hdr = (xfs_dir_sf_hdr_t *)dp->i_df.if_u1.if_data; -	return(hdr->count == 0); -} - -/* - * Initialize a directory with its "." and ".." entries. - */ -static int -xfs_dir_init(xfs_trans_t *trans, xfs_inode_t *dir, xfs_inode_t *parent_dir) -{ -	xfs_da_args_t args; -	int error; - -	memset((char *)&args, 0, sizeof(args)); -	args.dp = dir; -	args.trans = trans; - -	ASSERT((dir->i_d.di_mode & S_IFMT) == S_IFDIR); -	if ((error = xfs_dir_ino_validate(trans->t_mountp, parent_dir->i_ino))) -		return error; - -	return(xfs_dir_shortform_create(&args, parent_dir->i_ino)); -} - -/* - * Generic handler routine to add a name to a directory. - * Transitions directory from shortform to Btree as necessary. - */ -static int							/* error */ -xfs_dir_createname(xfs_trans_t *trans, xfs_inode_t *dp, char *name, -		   int namelen, xfs_ino_t inum, xfs_fsblock_t *firstblock, -		   xfs_bmap_free_t *flist, xfs_extlen_t total) -{ -	xfs_da_args_t args; -	int retval, newsize, done; - -	ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); - -	if ((retval = xfs_dir_ino_validate(trans->t_mountp, inum))) -		return (retval); - -	XFS_STATS_INC(xs_dir_create); -	/* -	 * Fill in the arg structure for this request. -	 */ -	args.name = name; -	args.namelen = namelen; -	args.hashval = xfs_da_hashname(name, namelen); -	args.inumber = inum; -	args.dp = dp; -	args.firstblock = firstblock; -	args.flist = flist; -	args.total = total; -	args.whichfork = XFS_DATA_FORK; -	args.trans = trans; -	args.justcheck = 0; -	args.addname = args.oknoent = 1; - -	/* -	 * Decide on what work routines to call based on the inode size. -	 */ -	done = 0; -	if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) { -		newsize = XFS_DIR_SF_ENTSIZE_BYNAME(args.namelen); -		if ((dp->i_d.di_size + newsize) <= XFS_IFORK_DSIZE(dp)) { -			retval = xfs_dir_shortform_addname(&args); -			done = 1; -		} else { -			if (total == 0) -				return XFS_ERROR(ENOSPC); -			retval = xfs_dir_shortform_to_leaf(&args); -			done = retval != 0; -		} -	} -	if (!done && xfs_bmap_one_block(dp, XFS_DATA_FORK)) { -		retval = xfs_dir_leaf_addname(&args); -		done = retval != ENOSPC; -		if (!done) { -			if (total == 0) -				return XFS_ERROR(ENOSPC); -			retval = xfs_dir_leaf_to_node(&args); -			done = retval != 0; -		} -	} -	if (!done) { -		retval = xfs_dir_node_addname(&args); -	} -	return(retval); -} - -/* - * Generic handler routine to check if a name can be added to a directory, - * without adding any blocks to the directory. - */ -static int							/* error */ -xfs_dir_canenter(xfs_trans_t *trans, xfs_inode_t *dp, char *name, int namelen) -{ -	xfs_da_args_t args; -	int retval, newsize; - -	ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); -	/* -	 * Fill in the arg structure for this request. -	 */ -	args.name = name; -	args.namelen = namelen; -	args.hashval = xfs_da_hashname(name, namelen); -	args.inumber = 0; -	args.dp = dp; -	args.firstblock = NULL; -	args.flist = NULL; -	args.total = 0; -	args.whichfork = XFS_DATA_FORK; -	args.trans = trans; -	args.justcheck = args.addname = args.oknoent = 1; - -	/* -	 * Decide on what work routines to call based on the inode size. -	 */ -	if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) { -		newsize = XFS_DIR_SF_ENTSIZE_BYNAME(args.namelen); -		if ((dp->i_d.di_size + newsize) <= XFS_IFORK_DSIZE(dp)) -			retval = 0; -		else -			retval = XFS_ERROR(ENOSPC); -	} else if (xfs_bmap_one_block(dp, XFS_DATA_FORK)) { -		retval = xfs_dir_leaf_addname(&args); -	} else { -		retval = xfs_dir_node_addname(&args); -	} -	return(retval); -} - -/* - * Generic handler routine to remove a name from a directory. - * Transitions directory from Btree to shortform as necessary. - */ -static int							/* error */ -xfs_dir_removename(xfs_trans_t *trans, xfs_inode_t *dp, char *name, -		   int namelen, xfs_ino_t ino, xfs_fsblock_t *firstblock, -		   xfs_bmap_free_t *flist, xfs_extlen_t total) -{ -	xfs_da_args_t args; -	int count, totallen, newsize, retval; - -	ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); -	XFS_STATS_INC(xs_dir_remove); -	/* -	 * Fill in the arg structure for this request. -	 */ -	args.name = name; -	args.namelen = namelen; -	args.hashval = xfs_da_hashname(name, namelen); -	args.inumber = ino; -	args.dp = dp; -	args.firstblock = firstblock; -	args.flist = flist; -	args.total = total; -	args.whichfork = XFS_DATA_FORK; -	args.trans = trans; -	args.justcheck = args.addname = args.oknoent = 0; - -	/* -	 * Decide on what work routines to call based on the inode size. -	 */ -	if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) { -		retval = xfs_dir_shortform_removename(&args); -	} else if (xfs_bmap_one_block(dp, XFS_DATA_FORK)) { -		retval = xfs_dir_leaf_removename(&args, &count, &totallen); -		if (retval == 0) { -			newsize = XFS_DIR_SF_ALLFIT(count, totallen); -			if (newsize <= XFS_IFORK_DSIZE(dp)) { -				retval = xfs_dir_leaf_to_shortform(&args); -			} -		} -	} else { -		retval = xfs_dir_node_removename(&args); -	} -	return(retval); -} - -static int							/* error */ -xfs_dir_lookup(xfs_trans_t *trans, xfs_inode_t *dp, char *name, int namelen, -				   xfs_ino_t *inum) -{ -	xfs_da_args_t args; -	int retval; - -	ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); - -	XFS_STATS_INC(xs_dir_lookup); -	/* -	 * Fill in the arg structure for this request. -	 */ -	args.name = name; -	args.namelen = namelen; -	args.hashval = xfs_da_hashname(name, namelen); -	args.inumber = 0; -	args.dp = dp; -	args.firstblock = NULL; -	args.flist = NULL; -	args.total = 0; -	args.whichfork = XFS_DATA_FORK; -	args.trans = trans; -	args.justcheck = args.addname = 0; -	args.oknoent = 1; - -	/* -	 * Decide on what work routines to call based on the inode size. -	 */ -	if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) { -		retval = xfs_dir_shortform_lookup(&args); -	} else if (xfs_bmap_one_block(dp, XFS_DATA_FORK)) { -		retval = xfs_dir_leaf_lookup(&args); -	} else { -		retval = xfs_dir_node_lookup(&args); -	} -	if (retval == EEXIST) -		retval = 0; -	*inum = args.inumber; -	return(retval); -} - -/* - * Implement readdir. - */ -static int							/* error */ -xfs_dir_getdents(xfs_trans_t *trans, xfs_inode_t *dp, uio_t *uio, int *eofp) -{ -	xfs_dirent_t *dbp; -	int  alignment, retval; -	xfs_dir_put_t put; - -	XFS_STATS_INC(xs_dir_getdents); -	ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); - -	/* -	 * If our caller has given us a single contiguous memory buffer, -	 * just work directly within that buffer.  If it's in user memory, -	 * lock it down first. -	 */ -	alignment = sizeof(xfs_off_t) - 1; -	if ((uio->uio_iovcnt == 1) && -	    (((__psint_t)uio->uio_iov[0].iov_base & alignment) == 0) && -	    ((uio->uio_iov[0].iov_len & alignment) == 0)) { -		dbp = NULL; -		put = xfs_dir_put_dirent64_direct; -	} else { -		dbp = kmem_alloc(sizeof(*dbp) + MAXNAMELEN, KM_SLEEP); -		put = xfs_dir_put_dirent64_uio; -	} - -	/* -	 * Decide on what work routines to call based on the inode size. -	 */ -	*eofp = 0; - -	if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) { -		retval = xfs_dir_shortform_getdents(dp, uio, eofp, dbp, put); -	} else if (xfs_bmap_one_block(dp, XFS_DATA_FORK)) { -		retval = xfs_dir_leaf_getdents(trans, dp, uio, eofp, dbp, put); -	} else { -		retval = xfs_dir_node_getdents(trans, dp, uio, eofp, dbp, put); -	} -	if (dbp != NULL) -		kmem_free(dbp, sizeof(*dbp) + MAXNAMELEN); - -	return(retval); -} - -static int							/* error */ -xfs_dir_replace(xfs_trans_t *trans, xfs_inode_t *dp, char *name, int namelen, -				    xfs_ino_t inum, xfs_fsblock_t *firstblock, -				    xfs_bmap_free_t *flist, xfs_extlen_t total) -{ -	xfs_da_args_t args; -	int retval; - -	ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); - -	if ((retval = xfs_dir_ino_validate(trans->t_mountp, inum))) -		return retval; - -	/* -	 * Fill in the arg structure for this request. -	 */ -	args.name = name; -	args.namelen = namelen; -	args.hashval = xfs_da_hashname(name, namelen); -	args.inumber = inum; -	args.dp = dp; -	args.firstblock = firstblock; -	args.flist = flist; -	args.total = total; -	args.whichfork = XFS_DATA_FORK; -	args.trans = trans; -	args.justcheck = args.addname = args.oknoent = 0; - -	/* -	 * Decide on what work routines to call based on the inode size. -	 */ -	if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) { -		retval = xfs_dir_shortform_replace(&args); -	} else if (xfs_bmap_one_block(dp, XFS_DATA_FORK)) { -		retval = xfs_dir_leaf_replace(&args); -	} else { -		retval = xfs_dir_node_replace(&args); -	} - -	return(retval); -} - -static int -xfs_dir_shortform_validate_ondisk(xfs_mount_t *mp, xfs_dinode_t *dp) -{ -	xfs_ino_t		ino; -	int			namelen_sum; -	int			count; -	xfs_dir_shortform_t	*sf; -	xfs_dir_sf_entry_t	*sfe; -	int			i; - - - -	if ((INT_GET(dp->di_core.di_mode, ARCH_CONVERT) & S_IFMT) != S_IFDIR) { -		return 0; -	} -	if (INT_GET(dp->di_core.di_format, ARCH_CONVERT) != XFS_DINODE_FMT_LOCAL) { -		return 0; -	} -	if (INT_GET(dp->di_core.di_size, ARCH_CONVERT) < sizeof(sf->hdr)) { -		xfs_fs_cmn_err(CE_WARN, mp, "Invalid shortform size: dp 0x%p", -			dp); -		return 1; -	} -	sf = (xfs_dir_shortform_t *)(&dp->di_u.di_dirsf); -	ino = XFS_GET_DIR_INO8(sf->hdr.parent); -	if (xfs_dir_ino_validate(mp, ino)) -		return 1; - -	count =	sf->hdr.count; -	if ((count < 0) || ((count * 10) > XFS_LITINO(mp))) { -		xfs_fs_cmn_err(CE_WARN, mp, -			"Invalid shortform count: dp 0x%p", dp); -		return(1); -	} - -	if (count == 0) { -		return 0; -	} - -	namelen_sum = 0; -	sfe = &sf->list[0]; -	for (i = sf->hdr.count - 1; i >= 0; i--) { -		ino = XFS_GET_DIR_INO8(sfe->inumber); -		xfs_dir_ino_validate(mp, ino); -		if (sfe->namelen >= XFS_LITINO(mp)) { -			xfs_fs_cmn_err(CE_WARN, mp, -				"Invalid shortform namelen: dp 0x%p", dp); -			return 1; -		} -		namelen_sum += sfe->namelen; -		sfe = XFS_DIR_SF_NEXTENTRY(sfe); -	} -	if (namelen_sum >= XFS_LITINO(mp)) { -		xfs_fs_cmn_err(CE_WARN, mp, -			"Invalid shortform namelen: dp 0x%p", dp); -		return 1; -	} - -	return 0; -} - -/*======================================================================== - * External routines when dirsize == XFS_LBSIZE(dp->i_mount). - *========================================================================*/ - -/* - * Add a name to the leaf directory structure - * This is the external routine. - */ -int -xfs_dir_leaf_addname(xfs_da_args_t *args) -{ -	int index, retval; -	xfs_dabuf_t *bp; - -	retval = xfs_da_read_buf(args->trans, args->dp, 0, -1, &bp, -					      XFS_DATA_FORK); -	if (retval) -		return(retval); -	ASSERT(bp != NULL); - -	retval = xfs_dir_leaf_lookup_int(bp, args, &index); -	if (retval == ENOENT) -		retval = xfs_dir_leaf_add(bp, args, index); -	xfs_da_buf_done(bp); -	return(retval); -} - -/* - * Remove a name from the leaf directory structure - * This is the external routine. - */ -STATIC int -xfs_dir_leaf_removename(xfs_da_args_t *args, int *count, int *totallen) -{ -	xfs_dir_leafblock_t *leaf; -	int index, retval; -	xfs_dabuf_t *bp; - -	retval = xfs_da_read_buf(args->trans, args->dp, 0, -1, &bp, -					      XFS_DATA_FORK); -	if (retval) -		return(retval); -	ASSERT(bp != NULL); -	leaf = bp->data; -	ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR_LEAF_MAGIC); -	retval = xfs_dir_leaf_lookup_int(bp, args, &index); -	if (retval == EEXIST) { -		(void)xfs_dir_leaf_remove(args->trans, bp, index); -		*count = be16_to_cpu(leaf->hdr.count); -		*totallen = be16_to_cpu(leaf->hdr.namebytes); -		retval = 0; -	} -	xfs_da_buf_done(bp); -	return(retval); -} - -/* - * Look up a name in a leaf directory structure. - * This is the external routine. - */ -STATIC int -xfs_dir_leaf_lookup(xfs_da_args_t *args) -{ -	int index, retval; -	xfs_dabuf_t *bp; - -	retval = xfs_da_read_buf(args->trans, args->dp, 0, -1, &bp, -					      XFS_DATA_FORK); -	if (retval) -		return(retval); -	ASSERT(bp != NULL); -	retval = xfs_dir_leaf_lookup_int(bp, args, &index); -	xfs_da_brelse(args->trans, bp); -	return(retval); -} - -/* - * Copy out directory entries for getdents(), for leaf directories. - */ -STATIC int -xfs_dir_leaf_getdents(xfs_trans_t *trans, xfs_inode_t *dp, uio_t *uio, -				  int *eofp, xfs_dirent_t *dbp, xfs_dir_put_t put) -{ -	xfs_dabuf_t *bp; -	int retval, eob; - -	retval = xfs_da_read_buf(dp->i_transp, dp, 0, -1, &bp, XFS_DATA_FORK); -	if (retval) -		return(retval); -	ASSERT(bp != NULL); -	retval = xfs_dir_leaf_getdents_int(bp, dp, 0, uio, &eob, dbp, put, -1); -	xfs_da_brelse(trans, bp); -	*eofp = (eob == 0); -	return(retval); -} - -/* - * Look up a name in a leaf directory structure, replace the inode number. - * This is the external routine. - */ -STATIC int -xfs_dir_leaf_replace(xfs_da_args_t *args) -{ -	int index, retval; -	xfs_dabuf_t *bp; -	xfs_ino_t inum; -	xfs_dir_leafblock_t *leaf; -	xfs_dir_leaf_entry_t *entry; -	xfs_dir_leaf_name_t *namest; - -	inum = args->inumber; -	retval = xfs_da_read_buf(args->trans, args->dp, 0, -1, &bp, -					      XFS_DATA_FORK); -	if (retval) -		return(retval); -	ASSERT(bp != NULL); -	retval = xfs_dir_leaf_lookup_int(bp, args, &index); -	if (retval == EEXIST) { -		leaf = bp->data; -		entry = &leaf->entries[index]; -		namest = XFS_DIR_LEAF_NAMESTRUCT(leaf, be16_to_cpu(entry->nameidx)); -		/* XXX - replace assert? */ -		XFS_DIR_SF_PUT_DIRINO(&inum, &namest->inumber); -		xfs_da_log_buf(args->trans, bp, -		    XFS_DA_LOGRANGE(leaf, namest, sizeof(namest->inumber))); -		xfs_da_buf_done(bp); -		retval = 0; -	} else -		xfs_da_brelse(args->trans, bp); -	return(retval); -} - - -/*======================================================================== - * External routines when dirsize > XFS_LBSIZE(mp). - *========================================================================*/ - -/* - * Add a name to a Btree-format directory. - * - * This will involve walking down the Btree, and may involve splitting - * leaf nodes and even splitting intermediate nodes up to and including - * the root node (a special case of an intermediate node). - */ -STATIC int -xfs_dir_node_addname(xfs_da_args_t *args) -{ -	xfs_da_state_t *state; -	xfs_da_state_blk_t *blk; -	int retval, error; - -	/* -	 * Fill in bucket of arguments/results/context to carry around. -	 */ -	state = xfs_da_state_alloc(); -	state->args = args; -	state->mp = args->dp->i_mount; -	state->blocksize = state->mp->m_sb.sb_blocksize; -	state->node_ents = state->mp->m_dir_node_ents; - -	/* -	 * Search to see if name already exists, and get back a pointer -	 * to where it should go. -	 */ -	error = xfs_da_node_lookup_int(state, &retval); -	if (error) -		retval = error; -	if (retval != ENOENT) -		goto error; -	blk = &state->path.blk[ state->path.active-1 ]; -	ASSERT(blk->magic == XFS_DIR_LEAF_MAGIC); -	retval = xfs_dir_leaf_add(blk->bp, args, blk->index); -	if (retval == 0) { -		/* -		 * Addition succeeded, update Btree hashvals. -		 */ -		if (!args->justcheck) -			xfs_da_fixhashpath(state, &state->path); -	} else { -		/* -		 * Addition failed, split as many Btree elements as required. -		 */ -		if (args->total == 0) { -			ASSERT(retval == ENOSPC); -			goto error; -		} -		retval = xfs_da_split(state); -	} -error: -	xfs_da_state_free(state); - -	return(retval); -} - -/* - * Remove a name from a B-tree directory. - * - * This will involve walking down the Btree, and may involve joining - * leaf nodes and even joining intermediate nodes up to and including - * the root node (a special case of an intermediate node). - */ -STATIC int -xfs_dir_node_removename(xfs_da_args_t *args) -{ -	xfs_da_state_t *state; -	xfs_da_state_blk_t *blk; -	int retval, error; - -	state = xfs_da_state_alloc(); -	state->args = args; -	state->mp = args->dp->i_mount; -	state->blocksize = state->mp->m_sb.sb_blocksize; -	state->node_ents = state->mp->m_dir_node_ents; - -	/* -	 * Search to see if name exists, and get back a pointer to it. -	 */ -	error = xfs_da_node_lookup_int(state, &retval); -	if (error) -		retval = error; -	if (retval != EEXIST) { -		xfs_da_state_free(state); -		return(retval); -	} - -	/* -	 * Remove the name and update the hashvals in the tree. -	 */ -	blk = &state->path.blk[ state->path.active-1 ]; -	ASSERT(blk->magic == XFS_DIR_LEAF_MAGIC); -	retval = xfs_dir_leaf_remove(args->trans, blk->bp, blk->index); -	xfs_da_fixhashpath(state, &state->path); - -	/* -	 * Check to see if the tree needs to be collapsed. -	 */ -	error = 0; -	if (retval) { -		error = xfs_da_join(state); -	} - -	xfs_da_state_free(state); -	if (error) -		return(error); -	return(0); -} - -/* - * Look up a filename in a int directory. - * Use an internal routine to actually do all the work. - */ -STATIC int -xfs_dir_node_lookup(xfs_da_args_t *args) -{ -	xfs_da_state_t *state; -	int retval, error, i; - -	state = xfs_da_state_alloc(); -	state->args = args; -	state->mp = args->dp->i_mount; -	state->blocksize = state->mp->m_sb.sb_blocksize; -	state->node_ents = state->mp->m_dir_node_ents; - -	/* -	 * Search to see if name exists, -	 * and get back a pointer to it. -	 */ -	error = xfs_da_node_lookup_int(state, &retval); -	if (error) { -		retval = error; -	} - -	/* -	 * If not in a transaction, we have to release all the buffers. -	 */ -	for (i = 0; i < state->path.active; i++) { -		xfs_da_brelse(args->trans, state->path.blk[i].bp); -		state->path.blk[i].bp = NULL; -	} - -	xfs_da_state_free(state); -	return(retval); -} - -STATIC int -xfs_dir_node_getdents(xfs_trans_t *trans, xfs_inode_t *dp, uio_t *uio, -				  int *eofp, xfs_dirent_t *dbp, xfs_dir_put_t put) -{ -	xfs_da_intnode_t *node; -	xfs_da_node_entry_t *btree; -	xfs_dir_leafblock_t *leaf = NULL; -	xfs_dablk_t bno, nextbno; -	xfs_dahash_t cookhash; -	xfs_mount_t *mp; -	int error, eob, i; -	xfs_dabuf_t *bp; -	xfs_daddr_t nextda; - -	/* -	 * Pick up our context. -	 */ -	mp = dp->i_mount; -	bp = NULL; -	bno = XFS_DA_COOKIE_BNO(mp, uio->uio_offset); -	cookhash = XFS_DA_COOKIE_HASH(mp, uio->uio_offset); - -	xfs_dir_trace_g_du("node: start", dp, uio); - -	/* -	 * Re-find our place, even if we're confused about what our place is. -	 * -	 * First we check the block number from the magic cookie, it is a -	 * cache of where we ended last time.  If we find a leaf block, and -	 * the starting hashval in that block is less than our desired -	 * hashval, then we run with it. -	 */ -	if (bno > 0) { -		error = xfs_da_read_buf(trans, dp, bno, -2, &bp, XFS_DATA_FORK); -		if ((error != 0) && (error != EFSCORRUPTED)) -			return(error); -		if (bp) -			leaf = bp->data; -		if (bp && be16_to_cpu(leaf->hdr.info.magic) != XFS_DIR_LEAF_MAGIC) { -			xfs_dir_trace_g_dub("node: block not a leaf", -						   dp, uio, bno); -			xfs_da_brelse(trans, bp); -			bp = NULL; -		} -		if (bp && be32_to_cpu(leaf->entries[0].hashval) > cookhash) { -			xfs_dir_trace_g_dub("node: leaf hash too large", -						   dp, uio, bno); -			xfs_da_brelse(trans, bp); -			bp = NULL; -		} -		if (bp && cookhash > be32_to_cpu(leaf->entries[ -					be16_to_cpu(leaf->hdr.count) - 1].hashval)) { -			xfs_dir_trace_g_dub("node: leaf hash too small", -						   dp, uio, bno); -			xfs_da_brelse(trans, bp); -			bp = NULL; -		} -	} - -	/* -	 * If we did not find a leaf block from the blockno in the cookie, -	 * or we there was no blockno in the cookie (eg: first time thru), -	 * the we start at the top of the Btree and re-find our hashval. -	 */ -	if (bp == NULL) { -		xfs_dir_trace_g_du("node: start at root" , dp, uio); -		bno = 0; -		for (;;) { -			error = xfs_da_read_buf(trans, dp, bno, -1, &bp, -						       XFS_DATA_FORK); -			if (error) -				return(error); -			if (bp == NULL) -				return(XFS_ERROR(EFSCORRUPTED)); -			node = bp->data; -			if (be16_to_cpu(node->hdr.info.magic) != XFS_DA_NODE_MAGIC) -				break; -			btree = &node->btree[0]; -			xfs_dir_trace_g_dun("node: node detail", dp, uio, node); -			for (i = 0; i < be16_to_cpu(node->hdr.count); btree++, i++) { -				if (be32_to_cpu(btree->hashval) >= cookhash) { -					bno = be32_to_cpu(btree->before); -					break; -				} -			} -			if (i == be16_to_cpu(node->hdr.count)) { -				xfs_da_brelse(trans, bp); -				xfs_dir_trace_g_du("node: hash beyond EOF", -							  dp, uio); -				uio->uio_offset = XFS_DA_MAKE_COOKIE(mp, 0, 0, -							     XFS_DA_MAXHASH); -				*eofp = 1; -				return(0); -			} -			xfs_dir_trace_g_dub("node: going to block", -						   dp, uio, bno); -			xfs_da_brelse(trans, bp); -		} -	} -	ASSERT(cookhash != XFS_DA_MAXHASH); - -	/* -	 * We've dropped down to the (first) leaf block that contains the -	 * hashval we are interested in.  Continue rolling upward thru the -	 * leaf blocks until we fill up our buffer. -	 */ -	for (;;) { -		leaf = bp->data; -		if (unlikely(be16_to_cpu(leaf->hdr.info.magic) != XFS_DIR_LEAF_MAGIC)) { -			xfs_dir_trace_g_dul("node: not a leaf", dp, uio, leaf); -			xfs_da_brelse(trans, bp); -			XFS_CORRUPTION_ERROR("xfs_dir_node_getdents(1)", -					     XFS_ERRLEVEL_LOW, mp, leaf); -			return XFS_ERROR(EFSCORRUPTED); -		} -		xfs_dir_trace_g_dul("node: leaf detail", dp, uio, leaf); -		if ((nextbno = be32_to_cpu(leaf->hdr.info.forw))) { -			nextda = xfs_da_reada_buf(trans, dp, nextbno, -						  XFS_DATA_FORK); -		} else -			nextda = -1; -		error = xfs_dir_leaf_getdents_int(bp, dp, bno, uio, &eob, dbp, -						  put, nextda); -		xfs_da_brelse(trans, bp); -		bno = nextbno; -		if (eob) { -			xfs_dir_trace_g_dub("node: E-O-B", dp, uio, bno); -			*eofp = 0; -			return(error); -		} -		if (bno == 0) -			break; -		error = xfs_da_read_buf(trans, dp, bno, nextda, &bp, -					XFS_DATA_FORK); -		if (error) -			return(error); -		if (unlikely(bp == NULL)) { -			XFS_ERROR_REPORT("xfs_dir_node_getdents(2)", -					 XFS_ERRLEVEL_LOW, mp); -			return(XFS_ERROR(EFSCORRUPTED)); -		} -	} -	*eofp = 1; -	xfs_dir_trace_g_du("node: E-O-F", dp, uio); -	return(0); -} - -/* - * Look up a filename in an int directory, replace the inode number. - * Use an internal routine to actually do the lookup. - */ -STATIC int -xfs_dir_node_replace(xfs_da_args_t *args) -{ -	xfs_da_state_t *state; -	xfs_da_state_blk_t *blk; -	xfs_dir_leafblock_t *leaf; -	xfs_dir_leaf_entry_t *entry; -	xfs_dir_leaf_name_t *namest; -	xfs_ino_t inum; -	int retval, error, i; -	xfs_dabuf_t *bp; - -	state = xfs_da_state_alloc(); -	state->args = args; -	state->mp = args->dp->i_mount; -	state->blocksize = state->mp->m_sb.sb_blocksize; -	state->node_ents = state->mp->m_dir_node_ents; -	inum = args->inumber; - -	/* -	 * Search to see if name exists, -	 * and get back a pointer to it. -	 */ -	error = xfs_da_node_lookup_int(state, &retval); -	if (error) { -		retval = error; -	} - -	if (retval == EEXIST) { -		blk = &state->path.blk[state->path.active - 1]; -		ASSERT(blk->magic == XFS_DIR_LEAF_MAGIC); -		bp = blk->bp; -		leaf = bp->data; -		entry = &leaf->entries[blk->index]; -		namest = XFS_DIR_LEAF_NAMESTRUCT(leaf, be16_to_cpu(entry->nameidx)); -		/* XXX - replace assert ? */ -		XFS_DIR_SF_PUT_DIRINO(&inum, &namest->inumber); -		xfs_da_log_buf(args->trans, bp, -		    XFS_DA_LOGRANGE(leaf, namest, sizeof(namest->inumber))); -		xfs_da_buf_done(bp); -		blk->bp = NULL; -		retval = 0; -	} else { -		i = state->path.active - 1; -		xfs_da_brelse(args->trans, state->path.blk[i].bp); -		state->path.blk[i].bp = NULL; -	} -	for (i = 0; i < state->path.active - 1; i++) { -		xfs_da_brelse(args->trans, state->path.blk[i].bp); -		state->path.blk[i].bp = NULL; -	} - -	xfs_da_state_free(state); -	return(retval); -} - -#if defined(XFS_DIR_TRACE) -/* - * Add a trace buffer entry for an inode and a uio. - */ -void -xfs_dir_trace_g_du(char *where, xfs_inode_t *dp, uio_t *uio) -{ -	xfs_dir_trace_enter(XFS_DIR_KTRACE_G_DU, where, -		     (void *)dp, (void *)dp->i_mount, -		     (void *)((unsigned long)(uio->uio_offset >> 32)), -		     (void *)((unsigned long)(uio->uio_offset & 0xFFFFFFFF)), -		     (void *)(unsigned long)uio->uio_resid, -		     NULL, NULL, NULL, NULL, NULL, NULL, NULL); -} - -/* - * Add a trace buffer entry for an inode and a uio. - */ -void -xfs_dir_trace_g_dub(char *where, xfs_inode_t *dp, uio_t *uio, xfs_dablk_t bno) -{ -	xfs_dir_trace_enter(XFS_DIR_KTRACE_G_DUB, where, -		     (void *)dp, (void *)dp->i_mount, -		     (void *)((unsigned long)(uio->uio_offset >> 32)), -		     (void *)((unsigned long)(uio->uio_offset & 0xFFFFFFFF)), -		     (void *)(unsigned long)uio->uio_resid, -		     (void *)(unsigned long)bno, -		     NULL, NULL, NULL, NULL, NULL, NULL); -} - -/* - * Add a trace buffer entry for an inode and a uio. - */ -void -xfs_dir_trace_g_dun(char *where, xfs_inode_t *dp, uio_t *uio, -			xfs_da_intnode_t *node) -{ -	int	last = be16_to_cpu(node->hdr.count) - 1; - -	xfs_dir_trace_enter(XFS_DIR_KTRACE_G_DUN, where, -		     (void *)dp, (void *)dp->i_mount, -		     (void *)((unsigned long)(uio->uio_offset >> 32)), -		     (void *)((unsigned long)(uio->uio_offset & 0xFFFFFFFF)), -		     (void *)(unsigned long)uio->uio_resid, -		     (void *)(unsigned long)be32_to_cpu(node->hdr.info.forw), -		     (void *)(unsigned long) -			be16_to_cpu(node->hdr.count), -		     (void *)(unsigned long) -			be32_to_cpu(node->btree[0].hashval), -		     (void *)(unsigned long) -			be32_to_cpu(node->btree[last].hashval), -		     NULL, NULL, NULL); -} - -/* - * Add a trace buffer entry for an inode and a uio. - */ -void -xfs_dir_trace_g_dul(char *where, xfs_inode_t *dp, uio_t *uio, -			xfs_dir_leafblock_t *leaf) -{ -	int	last = be16_to_cpu(leaf->hdr.count) - 1; - -	xfs_dir_trace_enter(XFS_DIR_KTRACE_G_DUL, where, -		     (void *)dp, (void *)dp->i_mount, -		     (void *)((unsigned long)(uio->uio_offset >> 32)), -		     (void *)((unsigned long)(uio->uio_offset & 0xFFFFFFFF)), -		     (void *)(unsigned long)uio->uio_resid, -		     (void *)(unsigned long)be32_to_cpu(leaf->hdr.info.forw), -		     (void *)(unsigned long)be16_to_cpu(leaf->hdr.count), -		     (void *)(unsigned long)be32_to_cpu(leaf->entries[0].hashval), -		     (void *)(unsigned long)be32_to_cpu(leaf->entries[last].hashval), -		     NULL, NULL, NULL); -} - -/* - * Add a trace buffer entry for an inode and a uio. - */ -void -xfs_dir_trace_g_due(char *where, xfs_inode_t *dp, uio_t *uio, -			xfs_dir_leaf_entry_t *entry) -{ -	xfs_dir_trace_enter(XFS_DIR_KTRACE_G_DUE, where, -		     (void *)dp, (void *)dp->i_mount, -		     (void *)((unsigned long)(uio->uio_offset >> 32)), -		     (void *)((unsigned long)(uio->uio_offset & 0xFFFFFFFF)), -		     (void *)(unsigned long)uio->uio_resid, -		     (void *)(unsigned long)be32_to_cpu(entry->hashval), -		     NULL, NULL, NULL, NULL, NULL, NULL); -} - -/* - * Add a trace buffer entry for an inode and a uio. - */ -void -xfs_dir_trace_g_duc(char *where, xfs_inode_t *dp, uio_t *uio, xfs_off_t cookie) -{ -	xfs_dir_trace_enter(XFS_DIR_KTRACE_G_DUC, where, -		     (void *)dp, (void *)dp->i_mount, -		     (void *)((unsigned long)(uio->uio_offset >> 32)), -		     (void *)((unsigned long)(uio->uio_offset & 0xFFFFFFFF)), -		     (void *)(unsigned long)uio->uio_resid, -		     (void *)((unsigned long)(cookie >> 32)), -		     (void *)((unsigned long)(cookie & 0xFFFFFFFF)), -		     NULL, NULL, NULL, NULL, NULL); -} - -/* - * Add a trace buffer entry for the arguments given to the routine, - * generic form. - */ -void -xfs_dir_trace_enter(int type, char *where, -			void * a0, void * a1, -			void * a2, void * a3, -			void * a4, void * a5, -			void * a6, void * a7, -			void * a8, void * a9, -			void * a10, void * a11) -{ -	ASSERT(xfs_dir_trace_buf); -	ktrace_enter(xfs_dir_trace_buf, (void *)(unsigned long)type, -					(void *)where, -					(void *)a0, (void *)a1, (void *)a2, -					(void *)a3, (void *)a4, (void *)a5, -					(void *)a6, (void *)a7, (void *)a8, -					(void *)a9, (void *)a10, (void *)a11, -					NULL, NULL); -} -#endif	/* XFS_DIR_TRACE */ diff --git a/fs/xfs/xfs_dir.h b/fs/xfs/xfs_dir.h index 8cc8afb9f6c..e69de29bb2d 100644 --- a/fs/xfs/xfs_dir.h +++ b/fs/xfs/xfs_dir.h @@ -1,142 +0,0 @@ -/* - * Copyright (c) 2000,2005 Silicon Graphics, Inc. - * All Rights Reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it would be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write the Free Software Foundation, - * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA - */ -#ifndef __XFS_DIR_H__ -#define	__XFS_DIR_H__ - -/* - * Large directories are structured around Btrees where all the data - * elements are in the leaf nodes.  Filenames are hashed into an int, - * then that int is used as the index into the Btree.  Since the hashval - * of a filename may not be unique, we may have duplicate keys.  The - * internal links in the Btree are logical block offsets into the file. - * - * Small directories use a different format and are packed as tightly - * as possible so as to fit into the literal area of the inode. - */ - -/*======================================================================== - * Function prototypes for the kernel. - *========================================================================*/ - -struct uio; -struct xfs_bmap_free; -struct xfs_da_args; -struct xfs_dinode; -struct xfs_inode; -struct xfs_mount; -struct xfs_trans; - -/* - * Directory function types. - * Put in structures (xfs_dirops_t) for v1 and v2 directories. - */ -typedef void	(*xfs_dir_mount_t)(struct xfs_mount *mp); -typedef int	(*xfs_dir_isempty_t)(struct xfs_inode *dp); -typedef int	(*xfs_dir_init_t)(struct xfs_trans *tp, -				  struct xfs_inode *dp, -				  struct xfs_inode *pdp); -typedef int	(*xfs_dir_createname_t)(struct xfs_trans *tp, -					struct xfs_inode *dp, -					char *name, -					int namelen, -					xfs_ino_t inum, -					xfs_fsblock_t *first, -					struct xfs_bmap_free *flist, -					xfs_extlen_t total); -typedef int	(*xfs_dir_lookup_t)(struct xfs_trans *tp, -				    struct xfs_inode *dp, -				    char *name, -				    int namelen, -				    xfs_ino_t *inum); -typedef int	(*xfs_dir_removename_t)(struct xfs_trans *tp, -					struct xfs_inode *dp, -					char *name, -					int namelen, -					xfs_ino_t ino, -					xfs_fsblock_t *first, -					struct xfs_bmap_free *flist, -					xfs_extlen_t total); -typedef int	(*xfs_dir_getdents_t)(struct xfs_trans *tp, -				      struct xfs_inode *dp, -				      struct uio *uio, -				      int *eofp); -typedef int	(*xfs_dir_replace_t)(struct xfs_trans *tp, -				     struct xfs_inode *dp, -				     char *name, -				     int namelen, -				     xfs_ino_t inum, -				     xfs_fsblock_t *first, -				     struct xfs_bmap_free *flist, -				     xfs_extlen_t total); -typedef int	(*xfs_dir_canenter_t)(struct xfs_trans *tp, -				      struct xfs_inode *dp, -				      char *name, -				      int namelen); -typedef int	(*xfs_dir_shortform_validate_ondisk_t)(struct xfs_mount *mp, -						       struct xfs_dinode *dip); -typedef int	(*xfs_dir_shortform_to_single_t)(struct xfs_da_args *args); - -typedef struct xfs_dirops { -	xfs_dir_mount_t				xd_mount; -	xfs_dir_isempty_t			xd_isempty; -	xfs_dir_init_t				xd_init; -	xfs_dir_createname_t			xd_createname; -	xfs_dir_lookup_t			xd_lookup; -	xfs_dir_removename_t			xd_removename; -	xfs_dir_getdents_t			xd_getdents; -	xfs_dir_replace_t			xd_replace; -	xfs_dir_canenter_t			xd_canenter; -	xfs_dir_shortform_validate_ondisk_t	xd_shortform_validate_ondisk; -	xfs_dir_shortform_to_single_t		xd_shortform_to_single; -} xfs_dirops_t; - -/* - * Overall external interface routines. - */ -void	xfs_dir_startup(void);	/* called exactly once */ - -#define	XFS_DIR_MOUNT(mp)	\ -	((mp)->m_dirops.xd_mount(mp)) -#define	XFS_DIR_ISEMPTY(mp,dp)	\ -	((mp)->m_dirops.xd_isempty(dp)) -#define	XFS_DIR_INIT(mp,tp,dp,pdp)	\ -	((mp)->m_dirops.xd_init(tp,dp,pdp)) -#define	XFS_DIR_CREATENAME(mp,tp,dp,name,namelen,inum,first,flist,total) \ -	((mp)->m_dirops.xd_createname(tp,dp,name,namelen,inum,first,flist,\ -				      total)) -#define	XFS_DIR_LOOKUP(mp,tp,dp,name,namelen,inum)	\ -	((mp)->m_dirops.xd_lookup(tp,dp,name,namelen,inum)) -#define	XFS_DIR_REMOVENAME(mp,tp,dp,name,namelen,ino,first,flist,total)	\ -	((mp)->m_dirops.xd_removename(tp,dp,name,namelen,ino,first,flist,total)) -#define	XFS_DIR_GETDENTS(mp,tp,dp,uio,eofp)	\ -	((mp)->m_dirops.xd_getdents(tp,dp,uio,eofp)) -#define	XFS_DIR_REPLACE(mp,tp,dp,name,namelen,inum,first,flist,total)	\ -	((mp)->m_dirops.xd_replace(tp,dp,name,namelen,inum,first,flist,total)) -#define	XFS_DIR_CANENTER(mp,tp,dp,name,namelen)	\ -	((mp)->m_dirops.xd_canenter(tp,dp,name,namelen)) -#define	XFS_DIR_SHORTFORM_VALIDATE_ONDISK(mp,dip)	\ -	((mp)->m_dirops.xd_shortform_validate_ondisk(mp,dip)) -#define	XFS_DIR_SHORTFORM_TO_SINGLE(mp,args)	\ -	((mp)->m_dirops.xd_shortform_to_single(args)) - -#define	XFS_DIR_IS_V1(mp)	((mp)->m_dirversion == 1) -#define	XFS_DIR_IS_V2(mp)	((mp)->m_dirversion == 2) -extern xfs_dirops_t xfsv1_dirops; -extern xfs_dirops_t xfsv2_dirops; - -#endif	/* __XFS_DIR_H__ */ diff --git a/fs/xfs/xfs_dir2.c b/fs/xfs/xfs_dir2.c index 80238a2263f..8edbe1adb95 100644 --- a/fs/xfs/xfs_dir2.c +++ b/fs/xfs/xfs_dir2.c @@ -24,21 +24,18 @@  #include "xfs_trans.h"  #include "xfs_sb.h"  #include "xfs_ag.h" -#include "xfs_dir.h"  #include "xfs_dir2.h"  #include "xfs_dmapi.h"  #include "xfs_mount.h"  #include "xfs_da_btree.h"  #include "xfs_bmap_btree.h"  #include "xfs_alloc_btree.h" -#include "xfs_dir_sf.h"  #include "xfs_dir2_sf.h"  #include "xfs_attr_sf.h"  #include "xfs_dinode.h"  #include "xfs_inode.h"  #include "xfs_inode_item.h"  #include "xfs_bmap.h" -#include "xfs_dir_leaf.h"  #include "xfs_dir2_data.h"  #include "xfs_dir2_leaf.h"  #include "xfs_dir2_block.h" @@ -46,69 +43,14 @@  #include "xfs_dir2_trace.h"  #include "xfs_error.h" -/* - * Declarations for interface routines. - */ -static void	xfs_dir2_mount(xfs_mount_t *mp); -static int	xfs_dir2_isempty(xfs_inode_t *dp); -static int	xfs_dir2_init(xfs_trans_t *tp, xfs_inode_t *dp, -			      xfs_inode_t *pdp); -static int	xfs_dir2_createname(xfs_trans_t *tp, xfs_inode_t *dp, -				    char *name, int namelen, xfs_ino_t inum, -				    xfs_fsblock_t *first, -				    xfs_bmap_free_t *flist, xfs_extlen_t total); -static int	xfs_dir2_lookup(xfs_trans_t *tp, xfs_inode_t *dp, char *name, -				int namelen, xfs_ino_t *inum); -static int	xfs_dir2_removename(xfs_trans_t *tp, xfs_inode_t *dp, -				    char *name, int namelen, xfs_ino_t ino, -				    xfs_fsblock_t *first, -				    xfs_bmap_free_t *flist, xfs_extlen_t total); -static int	xfs_dir2_getdents(xfs_trans_t *tp, xfs_inode_t *dp, uio_t *uio, -				  int *eofp); -static int	xfs_dir2_replace(xfs_trans_t *tp, xfs_inode_t *dp, char *name, -				 int namelen, xfs_ino_t inum, -				 xfs_fsblock_t *first, xfs_bmap_free_t *flist, -				 xfs_extlen_t total); -static int	xfs_dir2_canenter(xfs_trans_t *tp, xfs_inode_t *dp, char *name, -				  int namelen); -static int	xfs_dir2_shortform_validate_ondisk(xfs_mount_t *mp, -						   xfs_dinode_t *dip); - -/* - * Utility routine declarations. - */  static int	xfs_dir2_put_dirent64_direct(xfs_dir2_put_args_t *pa);  static int	xfs_dir2_put_dirent64_uio(xfs_dir2_put_args_t *pa); -/* - * Directory operations vector. - */ -xfs_dirops_t	xfsv2_dirops = { -	.xd_mount			= xfs_dir2_mount, -	.xd_isempty			= xfs_dir2_isempty, -	.xd_init			= xfs_dir2_init, -	.xd_createname			= xfs_dir2_createname, -	.xd_lookup			= xfs_dir2_lookup, -	.xd_removename			= xfs_dir2_removename, -	.xd_getdents			= xfs_dir2_getdents, -	.xd_replace			= xfs_dir2_replace, -	.xd_canenter			= xfs_dir2_canenter, -	.xd_shortform_validate_ondisk	= xfs_dir2_shortform_validate_ondisk, -	.xd_shortform_to_single		= xfs_dir2_sf_to_block, -}; - -/* - * Interface routines. - */ - -/* - * Initialize directory-related fields in the mount structure. - */ -static void -xfs_dir2_mount( -	xfs_mount_t	*mp)		/* filesystem mount point */ +void +xfs_dir_mount( +	xfs_mount_t	*mp)  { -	mp->m_dirversion = 2; +	ASSERT(XFS_SB_VERSION_HASDIRV2(&mp->m_sb));  	ASSERT((1 << (mp->m_sb.sb_blocklog + mp->m_sb.sb_dirblklog)) <=  	       XFS_MAX_BLOCKSIZE);  	mp->m_dirblksize = 1 << (mp->m_sb.sb_blocklog + mp->m_sb.sb_dirblklog); @@ -128,19 +70,15 @@ xfs_dir2_mount(  /*   * Return 1 if directory contains only "." and "..".   */ -static int				/* return code */ -xfs_dir2_isempty( -	xfs_inode_t	*dp)		/* incore inode structure */ +int +xfs_dir_isempty( +	xfs_inode_t	*dp)  { -	xfs_dir2_sf_t	*sfp;		/* shortform directory structure */ +	xfs_dir2_sf_t	*sfp;  	ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); -	/* -	 * Might happen during shutdown. -	 */ -	if (dp->i_d.di_size == 0) { +	if (dp->i_d.di_size == 0)	/* might happen during shutdown. */  		return 1; -	}  	if (dp->i_d.di_size > XFS_IFORK_DSIZE(dp))  		return 0;  	sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; @@ -148,53 +86,83 @@ xfs_dir2_isempty(  }  /* + * Validate a given inode number. + */ +int +xfs_dir_ino_validate( +	xfs_mount_t	*mp, +	xfs_ino_t	ino) +{ +	xfs_agblock_t	agblkno; +	xfs_agino_t	agino; +	xfs_agnumber_t	agno; +	int		ino_ok; +	int		ioff; + +	agno = XFS_INO_TO_AGNO(mp, ino); +	agblkno = XFS_INO_TO_AGBNO(mp, ino); +	ioff = XFS_INO_TO_OFFSET(mp, ino); +	agino = XFS_OFFBNO_TO_AGINO(mp, agblkno, ioff); +	ino_ok = +		agno < mp->m_sb.sb_agcount && +		agblkno < mp->m_sb.sb_agblocks && +		agblkno != 0 && +		ioff < (1 << mp->m_sb.sb_inopblog) && +		XFS_AGINO_TO_INO(mp, agno, agino) == ino; +	if (unlikely(XFS_TEST_ERROR(!ino_ok, mp, XFS_ERRTAG_DIR_INO_VALIDATE, +			XFS_RANDOM_DIR_INO_VALIDATE))) { +		xfs_fs_cmn_err(CE_WARN, mp, "Invalid inode number 0x%Lx", +				(unsigned long long) ino); +		XFS_ERROR_REPORT("xfs_dir_ino_validate", XFS_ERRLEVEL_LOW, mp); +		return XFS_ERROR(EFSCORRUPTED); +	} +	return 0; +} + +/*   * Initialize a directory with its "." and ".." entries.   */ -static int				/* error */ -xfs_dir2_init( -	xfs_trans_t	*tp,		/* transaction pointer */ -	xfs_inode_t	*dp,		/* incore directory inode */ -	xfs_inode_t	*pdp)		/* incore parent directory inode */ +int +xfs_dir_init( +	xfs_trans_t	*tp, +	xfs_inode_t	*dp, +	xfs_inode_t	*pdp)  { -	xfs_da_args_t	args;		/* operation arguments */ -	int		error;		/* error return value */ +	xfs_da_args_t	args; +	int		error;  	memset((char *)&args, 0, sizeof(args));  	args.dp = dp;  	args.trans = tp;  	ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); -	if ((error = xfs_dir_ino_validate(tp->t_mountp, pdp->i_ino))) { +	if ((error = xfs_dir_ino_validate(tp->t_mountp, pdp->i_ino)))  		return error; -	}  	return xfs_dir2_sf_create(&args, pdp->i_ino);  }  /*    Enter a name in a directory.   */ -static int					/* error */ -xfs_dir2_createname( -	xfs_trans_t		*tp,		/* transaction pointer */ -	xfs_inode_t		*dp,		/* incore directory inode */ -	char			*name,		/* new entry name */ -	int			namelen,	/* new entry name length */ +int +xfs_dir_createname( +	xfs_trans_t		*tp, +	xfs_inode_t		*dp, +	char			*name, +	int			namelen,  	xfs_ino_t		inum,		/* new entry inode number */  	xfs_fsblock_t		*first,		/* bmap's firstblock */  	xfs_bmap_free_t		*flist,		/* bmap's freeblock list */  	xfs_extlen_t		total)		/* bmap's total block count */  { -	xfs_da_args_t		args;		/* operation arguments */ -	int			rval;		/* return value */ +	xfs_da_args_t		args; +	int			rval;  	int			v;		/* type-checking value */  	ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); -	if ((rval = xfs_dir_ino_validate(tp->t_mountp, inum))) { +	if ((rval = xfs_dir_ino_validate(tp->t_mountp, inum)))  		return rval; -	}  	XFS_STATS_INC(xs_dir_create); -	/* -	 * Fill in the arg structure for this request. -	 */ +  	args.name = name;  	args.namelen = namelen;  	args.hashval = xfs_da_hashname(name, namelen); @@ -207,18 +175,16 @@ xfs_dir2_createname(  	args.trans = tp;  	args.justcheck = 0;  	args.addname = args.oknoent = 1; -	/* -	 * Decide on what work routines to call based on the inode size. -	 */ +  	if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL)  		rval = xfs_dir2_sf_addname(&args); -	else if ((rval = xfs_dir2_isblock(tp, dp, &v))) { +	else if ((rval = xfs_dir2_isblock(tp, dp, &v)))  		return rval; -	} else if (v) +	else if (v)  		rval = xfs_dir2_block_addname(&args); -	else if ((rval = xfs_dir2_isleaf(tp, dp, &v))) { +	else if ((rval = xfs_dir2_isleaf(tp, dp, &v)))  		return rval; -	} else if (v) +	else if (v)  		rval = xfs_dir2_leaf_addname(&args);  	else  		rval = xfs_dir2_node_addname(&args); @@ -228,24 +194,21 @@ xfs_dir2_createname(  /*   * Lookup a name in a directory, give back the inode number.   */ -static int				/* error */ -xfs_dir2_lookup( -	xfs_trans_t	*tp,		/* transaction pointer */ -	xfs_inode_t	*dp,		/* incore directory inode */ -	char		*name,		/* lookup name */ -	int		namelen,	/* lookup name length */ +int +xfs_dir_lookup( +	xfs_trans_t	*tp, +	xfs_inode_t	*dp, +	char		*name, +	int		namelen,  	xfs_ino_t	*inum)		/* out: inode number */  { -	xfs_da_args_t	args;		/* operation arguments */ -	int		rval;		/* return value */ +	xfs_da_args_t	args; +	int		rval;  	int		v;		/* type-checking value */  	ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR);  	XFS_STATS_INC(xs_dir_lookup); -	/* -	 * Fill in the arg structure for this request. -	 */  	args.name = name;  	args.namelen = namelen;  	args.hashval = xfs_da_hashname(name, namelen); @@ -258,18 +221,16 @@ xfs_dir2_lookup(  	args.trans = tp;  	args.justcheck = args.addname = 0;  	args.oknoent = 1; -	/* -	 * Decide on what work routines to call based on the inode size. -	 */ +  	if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL)  		rval = xfs_dir2_sf_lookup(&args); -	else if ((rval = xfs_dir2_isblock(tp, dp, &v))) { +	else if ((rval = xfs_dir2_isblock(tp, dp, &v)))  		return rval; -	} else if (v) +	else if (v)  		rval = xfs_dir2_block_lookup(&args); -	else if ((rval = xfs_dir2_isleaf(tp, dp, &v))) { +	else if ((rval = xfs_dir2_isleaf(tp, dp, &v)))  		return rval; -	} else if (v) +	else if (v)  		rval = xfs_dir2_leaf_lookup(&args);  	else  		rval = xfs_dir2_node_lookup(&args); @@ -283,26 +244,24 @@ xfs_dir2_lookup(  /*   * Remove an entry from a directory.   */ -static int				/* error */ -xfs_dir2_removename( -	xfs_trans_t	*tp,		/* transaction pointer */ -	xfs_inode_t	*dp,		/* incore directory inode */ -	char		*name,		/* name of entry to remove */ -	int		namelen,	/* name length of entry to remove */ -	xfs_ino_t	ino,		/* inode number of entry to remove */ +int +xfs_dir_removename( +	xfs_trans_t	*tp, +	xfs_inode_t	*dp, +	char		*name, +	int		namelen, +	xfs_ino_t	ino,  	xfs_fsblock_t	*first,		/* bmap's firstblock */  	xfs_bmap_free_t	*flist,		/* bmap's freeblock list */  	xfs_extlen_t	total)		/* bmap's total block count */  { -	xfs_da_args_t	args;		/* operation arguments */ -	int		rval;		/* return value */ +	xfs_da_args_t	args; +	int		rval;  	int		v;		/* type-checking value */  	ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR);  	XFS_STATS_INC(xs_dir_remove); -	/* -	 * Fill in the arg structure for this request. -	 */ +  	args.name = name;  	args.namelen = namelen;  	args.hashval = xfs_da_hashname(name, namelen); @@ -314,18 +273,16 @@ xfs_dir2_removename(  	args.whichfork = XFS_DATA_FORK;  	args.trans = tp;  	args.justcheck = args.addname = args.oknoent = 0; -	/* -	 * Decide on what work routines to call based on the inode size. -	 */ +  	if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL)  		rval = xfs_dir2_sf_removename(&args); -	else if ((rval = xfs_dir2_isblock(tp, dp, &v))) { +	else if ((rval = xfs_dir2_isblock(tp, dp, &v)))  		return rval; -	} else if (v) +	else if (v)  		rval = xfs_dir2_block_removename(&args); -	else if ((rval = xfs_dir2_isleaf(tp, dp, &v))) { +	else if ((rval = xfs_dir2_isleaf(tp, dp, &v)))  		return rval; -	} else if (v) +	else if (v)  		rval = xfs_dir2_leaf_removename(&args);  	else  		rval = xfs_dir2_node_removename(&args); @@ -335,10 +292,10 @@ xfs_dir2_removename(  /*   * Read a directory.   */ -static int				/* error */ -xfs_dir2_getdents( -	xfs_trans_t	*tp,		/* transaction pointer */ -	xfs_inode_t	*dp,		/* incore directory inode */ +int +xfs_dir_getdents( +	xfs_trans_t	*tp, +	xfs_inode_t	*dp,  	uio_t		*uio,		/* caller's buffer control */  	int		*eofp)		/* out: eof reached */  { @@ -367,14 +324,11 @@ xfs_dir2_getdents(  	}  	*eofp = 0; -	/* -	 * Decide on what work routines to call based on the inode size. -	 */  	if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL)  		rval = xfs_dir2_sf_getdents(dp, uio, eofp, dbp, put); -	else if ((rval = xfs_dir2_isblock(tp, dp, &v))) { +	else if ((rval = xfs_dir2_isblock(tp, dp, &v)))  		; -	} else if (v) +	else if (v)  		rval = xfs_dir2_block_getdents(tp, dp, uio, eofp, dbp, put);  	else  		rval = xfs_dir2_leaf_getdents(tp, dp, uio, eofp, dbp, put); @@ -386,29 +340,26 @@ xfs_dir2_getdents(  /*   * Replace the inode number of a directory entry.   */ -static int				/* error */ -xfs_dir2_replace( -	xfs_trans_t	*tp,		/* transaction pointer */ -	xfs_inode_t	*dp,		/* incore directory inode */ +int +xfs_dir_replace( +	xfs_trans_t	*tp, +	xfs_inode_t	*dp,  	char		*name,		/* name of entry to replace */ -	int		namelen,	/* name length of entry to replace */ +	int		namelen,  	xfs_ino_t	inum,		/* new inode number */  	xfs_fsblock_t	*first,		/* bmap's firstblock */  	xfs_bmap_free_t	*flist,		/* bmap's freeblock list */  	xfs_extlen_t	total)		/* bmap's total block count */  { -	xfs_da_args_t	args;		/* operation arguments */ -	int		rval;		/* return value */ +	xfs_da_args_t	args; +	int		rval;  	int		v;		/* type-checking value */  	ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); -	if ((rval = xfs_dir_ino_validate(tp->t_mountp, inum))) { +	if ((rval = xfs_dir_ino_validate(tp->t_mountp, inum)))  		return rval; -	} -	/* -	 * Fill in the arg structure for this request. -	 */ +  	args.name = name;  	args.namelen = namelen;  	args.hashval = xfs_da_hashname(name, namelen); @@ -420,18 +371,16 @@ xfs_dir2_replace(  	args.whichfork = XFS_DATA_FORK;  	args.trans = tp;  	args.justcheck = args.addname = args.oknoent = 0; -	/* -	 * Decide on what work routines to call based on the inode size. -	 */ +  	if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL)  		rval = xfs_dir2_sf_replace(&args); -	else if ((rval = xfs_dir2_isblock(tp, dp, &v))) { +	else if ((rval = xfs_dir2_isblock(tp, dp, &v)))  		return rval; -	} else if (v) +	else if (v)  		rval = xfs_dir2_block_replace(&args); -	else if ((rval = xfs_dir2_isleaf(tp, dp, &v))) { +	else if ((rval = xfs_dir2_isleaf(tp, dp, &v)))  		return rval; -	} else if (v) +	else if (v)  		rval = xfs_dir2_leaf_replace(&args);  	else  		rval = xfs_dir2_node_replace(&args); @@ -441,21 +390,19 @@ xfs_dir2_replace(  /*   * See if this entry can be added to the directory without allocating space.   */ -static int				/* error */ -xfs_dir2_canenter( -	xfs_trans_t	*tp,		/* transaction pointer */ -	xfs_inode_t	*dp,		/* incore directory inode */ +int +xfs_dir_canenter( +	xfs_trans_t	*tp, +	xfs_inode_t	*dp,  	char		*name,		/* name of entry to add */ -	int		namelen)	/* name length of entry to add */ +	int		namelen)  { -	xfs_da_args_t	args;		/* operation arguments */ -	int		rval;		/* return value */ +	xfs_da_args_t	args; +	int		rval;  	int		v;		/* type-checking value */  	ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); -	/* -	 * Fill in the arg structure for this request. -	 */ +  	args.name = name;  	args.namelen = namelen;  	args.hashval = xfs_da_hashname(name, namelen); @@ -467,18 +414,16 @@ xfs_dir2_canenter(  	args.whichfork = XFS_DATA_FORK;  	args.trans = tp;  	args.justcheck = args.addname = args.oknoent = 1; -	/* -	 * Decide on what work routines to call based on the inode size. -	 */ +  	if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL)  		rval = xfs_dir2_sf_addname(&args); -	else if ((rval = xfs_dir2_isblock(tp, dp, &v))) { +	else if ((rval = xfs_dir2_isblock(tp, dp, &v)))  		return rval; -	} else if (v) +	else if (v)  		rval = xfs_dir2_block_addname(&args); -	else if ((rval = xfs_dir2_isleaf(tp, dp, &v))) { +	else if ((rval = xfs_dir2_isleaf(tp, dp, &v)))  		return rval; -	} else if (v) +	else if (v)  		rval = xfs_dir2_leaf_addname(&args);  	else  		rval = xfs_dir2_node_addname(&args); @@ -486,19 +431,6 @@ xfs_dir2_canenter(  }  /* - * Dummy routine for shortform inode validation. - * Can't really do this. - */ -/* ARGSUSED */ -static int				/* error */ -xfs_dir2_shortform_validate_ondisk( -	xfs_mount_t	*mp,		/* filesystem mount point */ -	xfs_dinode_t	*dip)		/* ondisk inode */ -{ -	return 0; -} - -/*   * Utility routines.   */ @@ -507,24 +439,24 @@ xfs_dir2_shortform_validate_ondisk(   * This routine is for data and free blocks, not leaf/node blocks   * which are handled by xfs_da_grow_inode.   */ -int					/* error */ +int  xfs_dir2_grow_inode( -	xfs_da_args_t	*args,		/* operation arguments */ +	xfs_da_args_t	*args,  	int		space,		/* v2 dir's space XFS_DIR2_xxx_SPACE */  	xfs_dir2_db_t	*dbp)		/* out: block number added */  {  	xfs_fileoff_t	bno;		/* directory offset of new block */  	int		count;		/* count of filesystem blocks */  	xfs_inode_t	*dp;		/* incore directory inode */ -	int		error;		/* error return value */ +	int		error;  	int		got;		/* blocks actually mapped */ -	int		i;		/* temp mapping index */ +	int		i;  	xfs_bmbt_irec_t	map;		/* single structure for bmap */  	int		mapi;		/* mapping index */  	xfs_bmbt_irec_t	*mapp;		/* bmap mapping structure(s) */ -	xfs_mount_t	*mp;		/* filesystem mount point */ +	xfs_mount_t	*mp;  	int		nmap;		/* number of bmap entries */ -	xfs_trans_t	*tp;		/* transaction pointer */ +	xfs_trans_t	*tp;  	xfs_dir2_trace_args_s("grow_inode", args, space);  	dp = args->dp; @@ -538,9 +470,8 @@ xfs_dir2_grow_inode(  	/*  	 * Find the first hole for our block.  	 */ -	if ((error = xfs_bmap_first_unused(tp, dp, count, &bno, XFS_DATA_FORK))) { +	if ((error = xfs_bmap_first_unused(tp, dp, count, &bno, XFS_DATA_FORK)))  		return error; -	}  	nmap = 1;  	ASSERT(args->firstblock != NULL);  	/* @@ -549,13 +480,9 @@ xfs_dir2_grow_inode(  	if ((error = xfs_bmapi(tp, dp, bno, count,  			XFS_BMAPI_WRITE|XFS_BMAPI_METADATA|XFS_BMAPI_CONTIG,  			args->firstblock, args->total, &map, &nmap, -			args->flist, NULL))) { +			args->flist, NULL)))  		return error; -	}  	ASSERT(nmap <= 1); -	/* -	 * Got it in 1. -	 */  	if (nmap == 1) {  		mapp = ↦  		mapi = 1; @@ -646,20 +573,19 @@ xfs_dir2_grow_inode(  /*   * See if the directory is a single-block form directory.   */ -int					/* error */ +int  xfs_dir2_isblock( -	xfs_trans_t	*tp,		/* transaction pointer */ -	xfs_inode_t	*dp,		/* incore directory inode */ +	xfs_trans_t	*tp, +	xfs_inode_t	*dp,  	int		*vp)		/* out: 1 is block, 0 is not block */  {  	xfs_fileoff_t	last;		/* last file offset */ -	xfs_mount_t	*mp;		/* filesystem mount point */ -	int		rval;		/* return value */ +	xfs_mount_t	*mp; +	int		rval;  	mp = dp->i_mount; -	if ((rval = xfs_bmap_last_offset(tp, dp, &last, XFS_DATA_FORK))) { +	if ((rval = xfs_bmap_last_offset(tp, dp, &last, XFS_DATA_FORK)))  		return rval; -	}  	rval = XFS_FSB_TO_B(mp, last) == mp->m_dirblksize;  	ASSERT(rval == 0 || dp->i_d.di_size == mp->m_dirblksize);  	*vp = rval; @@ -669,20 +595,19 @@ xfs_dir2_isblock(  /*   * See if the directory is a single-leaf form directory.   */ -int					/* error */ +int  xfs_dir2_isleaf( -	xfs_trans_t	*tp,		/* transaction pointer */ -	xfs_inode_t	*dp,		/* incore directory inode */ +	xfs_trans_t	*tp, +	xfs_inode_t	*dp,  	int		*vp)		/* out: 1 is leaf, 0 is not leaf */  {  	xfs_fileoff_t	last;		/* last file offset */ -	xfs_mount_t	*mp;		/* filesystem mount point */ -	int		rval;		/* return value */ +	xfs_mount_t	*mp; +	int		rval;  	mp = dp->i_mount; -	if ((rval = xfs_bmap_last_offset(tp, dp, &last, XFS_DATA_FORK))) { +	if ((rval = xfs_bmap_last_offset(tp, dp, &last, XFS_DATA_FORK)))  		return rval; -	}  	*vp = last == mp->m_dirleafblk + (1 << mp->m_sb.sb_dirblklog);  	return 0;  } @@ -690,9 +615,9 @@ xfs_dir2_isleaf(  /*   * Getdents put routine for 64-bit ABI, direct form.   */ -static int					/* error */ +static int  xfs_dir2_put_dirent64_direct( -	xfs_dir2_put_args_t	*pa)		/* argument bundle */ +	xfs_dir2_put_args_t	*pa)  {  	xfs_dirent_t		*idbp;		/* dirent pointer */  	iovec_t			*iovp;		/* io vector */ @@ -727,9 +652,9 @@ xfs_dir2_put_dirent64_direct(  /*   * Getdents put routine for 64-bit ABI, uio form.   */ -static int					/* error */ +static int  xfs_dir2_put_dirent64_uio( -	xfs_dir2_put_args_t	*pa)		/* argument bundle */ +	xfs_dir2_put_args_t	*pa)  {  	xfs_dirent_t		*idbp;		/* dirent pointer */  	int			namelen;	/* entry name length */ @@ -765,17 +690,17 @@ xfs_dir2_put_dirent64_uio(   */  int  xfs_dir2_shrink_inode( -	xfs_da_args_t	*args,		/* operation arguments */ -	xfs_dir2_db_t	db,		/* directory block number */ -	xfs_dabuf_t	*bp)		/* block's buffer */ +	xfs_da_args_t	*args, +	xfs_dir2_db_t	db, +	xfs_dabuf_t	*bp)  {  	xfs_fileoff_t	bno;		/* directory file offset */  	xfs_dablk_t	da;		/* directory file offset */  	int		done;		/* bunmap is finished */ -	xfs_inode_t	*dp;		/* incore directory inode */ -	int		error;		/* error return value */ -	xfs_mount_t	*mp;		/* filesystem mount point */ -	xfs_trans_t	*tp;		/* transaction pointer */ +	xfs_inode_t	*dp; +	int		error; +	xfs_mount_t	*mp; +	xfs_trans_t	*tp;  	xfs_dir2_trace_args_db("shrink_inode", args, db, bp);  	dp = args->dp; diff --git a/fs/xfs/xfs_dir2.h b/fs/xfs/xfs_dir2.h index 7dd364b1e03..86560b6f794 100644 --- a/fs/xfs/xfs_dir2.h +++ b/fs/xfs/xfs_dir2.h @@ -22,7 +22,9 @@ struct uio;  struct xfs_dabuf;  struct xfs_da_args;  struct xfs_dir2_put_args; +struct xfs_bmap_free;  struct xfs_inode; +struct xfs_mount;  struct xfs_trans;  /* @@ -73,7 +75,35 @@ typedef struct xfs_dir2_put_args {  } xfs_dir2_put_args_t;  /* - * Other interfaces used by the rest of the dir v2 code. + * Generic directory interface routines + */ +extern void xfs_dir_startup(void); +extern void xfs_dir_mount(struct xfs_mount *mp); +extern int xfs_dir_isempty(struct xfs_inode *dp); +extern int xfs_dir_init(struct xfs_trans *tp, struct xfs_inode *dp, +				struct xfs_inode *pdp); +extern int xfs_dir_createname(struct xfs_trans *tp, struct xfs_inode *dp, +				char *name, int namelen, xfs_ino_t inum, +				xfs_fsblock_t *first, +				struct xfs_bmap_free *flist, xfs_extlen_t tot); +extern int xfs_dir_lookup(struct xfs_trans *tp, struct xfs_inode *dp, +				char *name, int namelen, xfs_ino_t *inum); +extern int xfs_dir_removename(struct xfs_trans *tp, struct xfs_inode *dp, +				char *name, int namelen, xfs_ino_t ino, +				xfs_fsblock_t *first, +				struct xfs_bmap_free *flist, xfs_extlen_t tot); +extern int xfs_dir_getdents(struct xfs_trans *tp, struct xfs_inode *dp, +				uio_t *uio, int *eofp); +extern int xfs_dir_replace(struct xfs_trans *tp, struct xfs_inode *dp, +				char *name, int namelen, xfs_ino_t inum, +				xfs_fsblock_t *first, +				struct xfs_bmap_free *flist, xfs_extlen_t tot); +extern int xfs_dir_canenter(struct xfs_trans *tp, struct xfs_inode *dp, +				char *name, int namelen); +extern int xfs_dir_ino_validate(struct xfs_mount *mp, xfs_ino_t ino); + +/* + * Utility routines for v2 directories.   */  extern int xfs_dir2_grow_inode(struct xfs_da_args *args, int space,  				xfs_dir2_db_t *dbp); diff --git a/fs/xfs/xfs_dir2_block.c b/fs/xfs/xfs_dir2_block.c index 2621ff521db..9d7438bba30 100644 --- a/fs/xfs/xfs_dir2_block.c +++ b/fs/xfs/xfs_dir2_block.c @@ -22,19 +22,16 @@  #include "xfs_inum.h"  #include "xfs_trans.h"  #include "xfs_sb.h" -#include "xfs_dir.h"  #include "xfs_dir2.h"  #include "xfs_dmapi.h"  #include "xfs_mount.h"  #include "xfs_da_btree.h"  #include "xfs_bmap_btree.h" -#include "xfs_dir_sf.h"  #include "xfs_dir2_sf.h"  #include "xfs_attr_sf.h"  #include "xfs_dinode.h"  #include "xfs_inode.h"  #include "xfs_inode_item.h" -#include "xfs_dir_leaf.h"  #include "xfs_dir2_data.h"  #include "xfs_dir2_leaf.h"  #include "xfs_dir2_block.h" @@ -51,6 +48,18 @@ static int xfs_dir2_block_lookup_int(xfs_da_args_t *args, xfs_dabuf_t **bpp,  				     int *entno);  static int xfs_dir2_block_sort(const void *a, const void *b); +static xfs_dahash_t xfs_dir_hash_dot, xfs_dir_hash_dotdot; + +/* + * One-time startup routine called from xfs_init(). + */ +void +xfs_dir_startup(void) +{ +	xfs_dir_hash_dot = xfs_da_hashname(".", 1); +	xfs_dir_hash_dotdot = xfs_da_hashname("..", 2); +} +  /*   * Add an entry to a block directory.   */ diff --git a/fs/xfs/xfs_dir2_data.c b/fs/xfs/xfs_dir2_data.c index 7be37d38961..f7c79921707 100644 --- a/fs/xfs/xfs_dir2_data.c +++ b/fs/xfs/xfs_dir2_data.c @@ -22,18 +22,15 @@  #include "xfs_inum.h"  #include "xfs_trans.h"  #include "xfs_sb.h" -#include "xfs_dir.h"  #include "xfs_dir2.h"  #include "xfs_dmapi.h"  #include "xfs_mount.h"  #include "xfs_da_btree.h"  #include "xfs_bmap_btree.h" -#include "xfs_dir_sf.h"  #include "xfs_dir2_sf.h"  #include "xfs_attr_sf.h"  #include "xfs_dinode.h"  #include "xfs_inode.h" -#include "xfs_dir_leaf.h"  #include "xfs_dir2_data.h"  #include "xfs_dir2_leaf.h"  #include "xfs_dir2_block.h" diff --git a/fs/xfs/xfs_dir2_leaf.c b/fs/xfs/xfs_dir2_leaf.c index 74ef99f2ee5..b1cf1fbf423 100644 --- a/fs/xfs/xfs_dir2_leaf.c +++ b/fs/xfs/xfs_dir2_leaf.c @@ -24,14 +24,12 @@  #include "xfs_trans.h"  #include "xfs_sb.h"  #include "xfs_ag.h" -#include "xfs_dir.h"  #include "xfs_dir2.h"  #include "xfs_dmapi.h"  #include "xfs_mount.h"  #include "xfs_da_btree.h"  #include "xfs_bmap_btree.h"  #include "xfs_attr_sf.h" -#include "xfs_dir_sf.h"  #include "xfs_dir2_sf.h"  #include "xfs_dinode.h"  #include "xfs_inode.h" diff --git a/fs/xfs/xfs_dir2_node.c b/fs/xfs/xfs_dir2_node.c index b1f85cc7795..9ca71719b68 100644 --- a/fs/xfs/xfs_dir2_node.c +++ b/fs/xfs/xfs_dir2_node.c @@ -22,13 +22,11 @@  #include "xfs_inum.h"  #include "xfs_trans.h"  #include "xfs_sb.h" -#include "xfs_dir.h"  #include "xfs_dir2.h"  #include "xfs_dmapi.h"  #include "xfs_mount.h"  #include "xfs_da_btree.h"  #include "xfs_bmap_btree.h" -#include "xfs_dir_sf.h"  #include "xfs_dir2_sf.h"  #include "xfs_attr_sf.h"  #include "xfs_dinode.h" diff --git a/fs/xfs/xfs_dir2_sf.c b/fs/xfs/xfs_dir2_sf.c index 06afa1b324c..0cd77b17bf9 100644 --- a/fs/xfs/xfs_dir2_sf.c +++ b/fs/xfs/xfs_dir2_sf.c @@ -22,19 +22,16 @@  #include "xfs_inum.h"  #include "xfs_trans.h"  #include "xfs_sb.h" -#include "xfs_dir.h"  #include "xfs_dir2.h"  #include "xfs_dmapi.h"  #include "xfs_mount.h"  #include "xfs_da_btree.h"  #include "xfs_bmap_btree.h" -#include "xfs_dir_sf.h"  #include "xfs_dir2_sf.h"  #include "xfs_attr_sf.h"  #include "xfs_dinode.h"  #include "xfs_inode.h"  #include "xfs_inode_item.h" -#include "xfs_dir_leaf.h"  #include "xfs_error.h"  #include "xfs_dir2_data.h"  #include "xfs_dir2_leaf.h" diff --git a/fs/xfs/xfs_dir2_trace.c b/fs/xfs/xfs_dir2_trace.c index c626943b411..f3fb2ffd6f5 100644 --- a/fs/xfs/xfs_dir2_trace.c +++ b/fs/xfs/xfs_dir2_trace.c @@ -19,11 +19,9 @@  #include "xfs_fs.h"  #include "xfs_types.h"  #include "xfs_inum.h" -#include "xfs_dir.h"  #include "xfs_dir2.h"  #include "xfs_da_btree.h"  #include "xfs_bmap_btree.h" -#include "xfs_dir_sf.h"  #include "xfs_dir2_sf.h"  #include "xfs_attr_sf.h"  #include "xfs_dinode.h" diff --git a/fs/xfs/xfs_dir_leaf.c b/fs/xfs/xfs_dir_leaf.c index e7121040cd9..e69de29bb2d 100644 --- a/fs/xfs/xfs_dir_leaf.c +++ b/fs/xfs/xfs_dir_leaf.c @@ -1,2230 +0,0 @@ -/* - * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. - * All Rights Reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it would be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write the Free Software Foundation, - * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA - */ -#include "xfs.h" -#include "xfs_fs.h" -#include "xfs_types.h" -#include "xfs_log.h" -#include "xfs_inum.h" -#include "xfs_trans.h" -#include "xfs_sb.h" -#include "xfs_dir.h" -#include "xfs_dir2.h" -#include "xfs_dmapi.h" -#include "xfs_mount.h" -#include "xfs_da_btree.h" -#include "xfs_bmap_btree.h" -#include "xfs_alloc_btree.h" -#include "xfs_ialloc_btree.h" -#include "xfs_dir_sf.h" -#include "xfs_dir2_sf.h" -#include "xfs_attr_sf.h" -#include "xfs_dinode.h" -#include "xfs_inode.h" -#include "xfs_inode_item.h" -#include "xfs_alloc.h" -#include "xfs_btree.h" -#include "xfs_bmap.h" -#include "xfs_dir_leaf.h" -#include "xfs_error.h" - -/* - * xfs_dir_leaf.c - * - * Routines to implement leaf blocks of directories as Btrees of hashed names. - */ - -/*======================================================================== - * Function prototypes for the kernel. - *========================================================================*/ - -/* - * Routines used for growing the Btree. - */ -STATIC void xfs_dir_leaf_add_work(xfs_dabuf_t *leaf_buffer, xfs_da_args_t *args, -					      int insertion_index, -					      int freemap_index); -STATIC int xfs_dir_leaf_compact(xfs_trans_t *trans, xfs_dabuf_t *leaf_buffer, -					    int musthave, int justcheck); -STATIC void xfs_dir_leaf_rebalance(xfs_da_state_t *state, -						  xfs_da_state_blk_t *blk1, -						  xfs_da_state_blk_t *blk2); -STATIC int xfs_dir_leaf_figure_balance(xfs_da_state_t *state, -					  xfs_da_state_blk_t *leaf_blk_1, -					  xfs_da_state_blk_t *leaf_blk_2, -					  int *number_entries_in_blk1, -					  int *number_namebytes_in_blk1); - -STATIC int xfs_dir_leaf_create(struct xfs_da_args *args, -				xfs_dablk_t which_block, -				struct xfs_dabuf **bpp); - -/* - * Utility routines. - */ -STATIC void xfs_dir_leaf_moveents(xfs_dir_leafblock_t *src_leaf, -					      int src_start, -					      xfs_dir_leafblock_t *dst_leaf, -					      int dst_start, int move_count, -					      xfs_mount_t *mp); - - -/*======================================================================== - * External routines when dirsize < XFS_IFORK_DSIZE(dp). - *========================================================================*/ - - -/* - * Validate a given inode number. - */ -int -xfs_dir_ino_validate(xfs_mount_t *mp, xfs_ino_t ino) -{ -	xfs_agblock_t	agblkno; -	xfs_agino_t	agino; -	xfs_agnumber_t	agno; -	int		ino_ok; -	int		ioff; - -	agno = XFS_INO_TO_AGNO(mp, ino); -	agblkno = XFS_INO_TO_AGBNO(mp, ino); -	ioff = XFS_INO_TO_OFFSET(mp, ino); -	agino = XFS_OFFBNO_TO_AGINO(mp, agblkno, ioff); -	ino_ok = -		agno < mp->m_sb.sb_agcount && -		agblkno < mp->m_sb.sb_agblocks && -		agblkno != 0 && -		ioff < (1 << mp->m_sb.sb_inopblog) && -		XFS_AGINO_TO_INO(mp, agno, agino) == ino; -	if (unlikely(XFS_TEST_ERROR(!ino_ok, mp, XFS_ERRTAG_DIR_INO_VALIDATE, -			XFS_RANDOM_DIR_INO_VALIDATE))) { -		xfs_fs_cmn_err(CE_WARN, mp, "Invalid inode number 0x%Lx", -				(unsigned long long) ino); -		XFS_ERROR_REPORT("xfs_dir_ino_validate", XFS_ERRLEVEL_LOW, mp); -		return XFS_ERROR(EFSCORRUPTED); -	} -	return 0; -} - -/* - * Create the initial contents of a shortform directory. - */ -int -xfs_dir_shortform_create(xfs_da_args_t *args, xfs_ino_t parent) -{ -	xfs_dir_sf_hdr_t *hdr; -	xfs_inode_t *dp; - -	dp = args->dp; -	ASSERT(dp != NULL); -	ASSERT(dp->i_d.di_size == 0); -	if (dp->i_d.di_format == XFS_DINODE_FMT_EXTENTS) { -		dp->i_df.if_flags &= ~XFS_IFEXTENTS;	/* just in case */ -		dp->i_d.di_format = XFS_DINODE_FMT_LOCAL; -		xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE); -		dp->i_df.if_flags |= XFS_IFINLINE; -	} -	ASSERT(dp->i_df.if_flags & XFS_IFINLINE); -	ASSERT(dp->i_df.if_bytes == 0); -	xfs_idata_realloc(dp, sizeof(*hdr), XFS_DATA_FORK); -	hdr = (xfs_dir_sf_hdr_t *)dp->i_df.if_u1.if_data; -	XFS_DIR_SF_PUT_DIRINO(&parent, &hdr->parent); - -	hdr->count = 0; -	dp->i_d.di_size = sizeof(*hdr); -	xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_DDATA); -	return 0; -} - -/* - * Add a name to the shortform directory structure. - * Overflow from the inode has already been checked for. - */ -int -xfs_dir_shortform_addname(xfs_da_args_t *args) -{ -	xfs_dir_shortform_t *sf; -	xfs_dir_sf_entry_t *sfe; -	int i, offset, size; -	xfs_inode_t *dp; - -	dp = args->dp; -	ASSERT(dp->i_df.if_flags & XFS_IFINLINE); -	/* -	 * Catch the case where the conversion from shortform to leaf -	 * failed part way through. -	 */ -	if (dp->i_d.di_size < sizeof(xfs_dir_sf_hdr_t)) { -		ASSERT(XFS_FORCED_SHUTDOWN(dp->i_mount)); -		return XFS_ERROR(EIO); -	} -	ASSERT(dp->i_df.if_bytes == dp->i_d.di_size); -	ASSERT(dp->i_df.if_u1.if_data != NULL); -	sf = (xfs_dir_shortform_t *)dp->i_df.if_u1.if_data; -	sfe = &sf->list[0]; -	for (i = sf->hdr.count-1; i >= 0; i--) { -		if (sfe->namelen == args->namelen && -		    args->name[0] == sfe->name[0] && -		    memcmp(args->name, sfe->name, args->namelen) == 0) -			return XFS_ERROR(EEXIST); -		sfe = XFS_DIR_SF_NEXTENTRY(sfe); -	} - -	offset = (int)((char *)sfe - (char *)sf); -	size = XFS_DIR_SF_ENTSIZE_BYNAME(args->namelen); -	xfs_idata_realloc(dp, size, XFS_DATA_FORK); -	sf = (xfs_dir_shortform_t *)dp->i_df.if_u1.if_data; -	sfe = (xfs_dir_sf_entry_t *)((char *)sf + offset); - -	XFS_DIR_SF_PUT_DIRINO(&args->inumber, &sfe->inumber); -	sfe->namelen = args->namelen; -	memcpy(sfe->name, args->name, sfe->namelen); -	sf->hdr.count++; - -	dp->i_d.di_size += size; -	xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_DDATA); - -	return 0; -} - -/* - * Remove a name from the shortform directory structure. - */ -int -xfs_dir_shortform_removename(xfs_da_args_t *args) -{ -	xfs_dir_shortform_t *sf; -	xfs_dir_sf_entry_t *sfe; -	int base, size = 0, i; -	xfs_inode_t *dp; - -	dp = args->dp; -	ASSERT(dp->i_df.if_flags & XFS_IFINLINE); -	/* -	 * Catch the case where the conversion from shortform to leaf -	 * failed part way through. -	 */ -	if (dp->i_d.di_size < sizeof(xfs_dir_sf_hdr_t)) { -		ASSERT(XFS_FORCED_SHUTDOWN(dp->i_mount)); -		return XFS_ERROR(EIO); -	} -	ASSERT(dp->i_df.if_bytes == dp->i_d.di_size); -	ASSERT(dp->i_df.if_u1.if_data != NULL); -	base = sizeof(xfs_dir_sf_hdr_t); -	sf = (xfs_dir_shortform_t *)dp->i_df.if_u1.if_data; -	sfe = &sf->list[0]; -	for (i = sf->hdr.count-1; i >= 0; i--) { -		size = XFS_DIR_SF_ENTSIZE_BYENTRY(sfe); -		if (sfe->namelen == args->namelen && -		    sfe->name[0] == args->name[0] && -		    memcmp(sfe->name, args->name, args->namelen) == 0) -			break; -		base += size; -		sfe = XFS_DIR_SF_NEXTENTRY(sfe); -	} -	if (i < 0) { -		ASSERT(args->oknoent); -		return XFS_ERROR(ENOENT); -	} - -	if ((base + size) != dp->i_d.di_size) { -		memmove(&((char *)sf)[base], &((char *)sf)[base+size], -					      dp->i_d.di_size - (base+size)); -	} -	sf->hdr.count--; - -	xfs_idata_realloc(dp, -size, XFS_DATA_FORK); -	dp->i_d.di_size -= size; -	xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_DDATA); - -	return 0; -} - -/* - * Look up a name in a shortform directory structure. - */ -int -xfs_dir_shortform_lookup(xfs_da_args_t *args) -{ -	xfs_dir_shortform_t *sf; -	xfs_dir_sf_entry_t *sfe; -	int i; -	xfs_inode_t *dp; - -	dp = args->dp; -	ASSERT(dp->i_df.if_flags & XFS_IFINLINE); -	/* -	 * Catch the case where the conversion from shortform to leaf -	 * failed part way through. -	 */ -	if (dp->i_d.di_size < sizeof(xfs_dir_sf_hdr_t)) { -		ASSERT(XFS_FORCED_SHUTDOWN(dp->i_mount)); -		return XFS_ERROR(EIO); -	} -	ASSERT(dp->i_df.if_bytes == dp->i_d.di_size); -	ASSERT(dp->i_df.if_u1.if_data != NULL); -	sf = (xfs_dir_shortform_t *)dp->i_df.if_u1.if_data; -	if (args->namelen == 2 && -	    args->name[0] == '.' && args->name[1] == '.') { -		XFS_DIR_SF_GET_DIRINO(&sf->hdr.parent, &args->inumber); -		return(XFS_ERROR(EEXIST)); -	} -	if (args->namelen == 1 && args->name[0] == '.') { -		args->inumber = dp->i_ino; -		return(XFS_ERROR(EEXIST)); -	} -	sfe = &sf->list[0]; -	for (i = sf->hdr.count-1; i >= 0; i--) { -		if (sfe->namelen == args->namelen && -		    sfe->name[0] == args->name[0] && -		    memcmp(args->name, sfe->name, args->namelen) == 0) { -			XFS_DIR_SF_GET_DIRINO(&sfe->inumber, &args->inumber); -			return(XFS_ERROR(EEXIST)); -		} -		sfe = XFS_DIR_SF_NEXTENTRY(sfe); -	} -	ASSERT(args->oknoent); -	return(XFS_ERROR(ENOENT)); -} - -/* - * Convert from using the shortform to the leaf. - */ -int -xfs_dir_shortform_to_leaf(xfs_da_args_t *iargs) -{ -	xfs_inode_t *dp; -	xfs_dir_shortform_t *sf; -	xfs_dir_sf_entry_t *sfe; -	xfs_da_args_t args; -	xfs_ino_t inumber; -	char *tmpbuffer; -	int retval, i, size; -	xfs_dablk_t blkno; -	xfs_dabuf_t *bp; - -	dp = iargs->dp; -	/* -	 * Catch the case where the conversion from shortform to leaf -	 * failed part way through. -	 */ -	if (dp->i_d.di_size < sizeof(xfs_dir_sf_hdr_t)) { -		ASSERT(XFS_FORCED_SHUTDOWN(dp->i_mount)); -		return XFS_ERROR(EIO); -	} -	ASSERT(dp->i_df.if_bytes == dp->i_d.di_size); -	ASSERT(dp->i_df.if_u1.if_data != NULL); -	size = dp->i_df.if_bytes; -	tmpbuffer = kmem_alloc(size, KM_SLEEP); -	ASSERT(tmpbuffer != NULL); - -	memcpy(tmpbuffer, dp->i_df.if_u1.if_data, size); - -	sf = (xfs_dir_shortform_t *)tmpbuffer; -	XFS_DIR_SF_GET_DIRINO(&sf->hdr.parent, &inumber); - -	xfs_idata_realloc(dp, -size, XFS_DATA_FORK); -	dp->i_d.di_size = 0; -	xfs_trans_log_inode(iargs->trans, dp, XFS_ILOG_CORE); -	retval = xfs_da_grow_inode(iargs, &blkno); -	if (retval) -		goto out; - -	ASSERT(blkno == 0); -	retval = xfs_dir_leaf_create(iargs, blkno, &bp); -	if (retval) -		goto out; -	xfs_da_buf_done(bp); - -	args.name = "."; -	args.namelen = 1; -	args.hashval = xfs_dir_hash_dot; -	args.inumber = dp->i_ino; -	args.dp = dp; -	args.firstblock = iargs->firstblock; -	args.flist = iargs->flist; -	args.total = iargs->total; -	args.whichfork = XFS_DATA_FORK; -	args.trans = iargs->trans; -	args.justcheck = 0; -	args.addname = args.oknoent = 1; -	retval = xfs_dir_leaf_addname(&args); -	if (retval) -		goto out; - -	args.name = ".."; -	args.namelen = 2; -	args.hashval = xfs_dir_hash_dotdot; -	args.inumber = inumber; -	retval = xfs_dir_leaf_addname(&args); -	if (retval) -		goto out; - -	sfe = &sf->list[0]; -	for (i = 0; i < sf->hdr.count; i++) { -		args.name = (char *)(sfe->name); -		args.namelen = sfe->namelen; -		args.hashval = xfs_da_hashname((char *)(sfe->name), -					       sfe->namelen); -		XFS_DIR_SF_GET_DIRINO(&sfe->inumber, &args.inumber); -		retval = xfs_dir_leaf_addname(&args); -		if (retval) -			goto out; -		sfe = XFS_DIR_SF_NEXTENTRY(sfe); -	} -	retval = 0; - -out: -	kmem_free(tmpbuffer, size); -	return retval; -} - -STATIC int -xfs_dir_shortform_compare(const void *a, const void *b) -{ -	xfs_dir_sf_sort_t *sa, *sb; - -	sa = (xfs_dir_sf_sort_t *)a; -	sb = (xfs_dir_sf_sort_t *)b; -	if (sa->hash < sb->hash) -		return -1; -	else if (sa->hash > sb->hash) -		return 1; -	else -		return sa->entno - sb->entno; -} - -/* - * Copy out directory entries for getdents(), for shortform directories. - */ -/*ARGSUSED*/ -int -xfs_dir_shortform_getdents(xfs_inode_t *dp, uio_t *uio, int *eofp, -				       xfs_dirent_t *dbp, xfs_dir_put_t put) -{ -	xfs_dir_shortform_t *sf; -	xfs_dir_sf_entry_t *sfe; -	int retval, i, sbsize, nsbuf, lastresid=0, want_entno; -	xfs_mount_t *mp; -	xfs_dahash_t cookhash, hash; -	xfs_dir_put_args_t p; -	xfs_dir_sf_sort_t *sbuf, *sbp; - -	mp = dp->i_mount; -	sf = (xfs_dir_shortform_t *)dp->i_df.if_u1.if_data; -	cookhash = XFS_DA_COOKIE_HASH(mp, uio->uio_offset); -	want_entno = XFS_DA_COOKIE_ENTRY(mp, uio->uio_offset); -	nsbuf = sf->hdr.count + 2; -	sbsize = (nsbuf + 1) * sizeof(*sbuf); -	sbp = sbuf = kmem_alloc(sbsize, KM_SLEEP); - -	xfs_dir_trace_g_du("sf: start", dp, uio); - -	/* -	 * Collect all the entries into the buffer. -	 * Entry 0 is . -	 */ -	sbp->entno = 0; -	sbp->seqno = 0; -	sbp->hash = xfs_dir_hash_dot; -	sbp->ino = dp->i_ino; -	sbp->name = "."; -	sbp->namelen = 1; -	sbp++; - -	/* -	 * Entry 1 is .. -	 */ -	sbp->entno = 1; -	sbp->seqno = 0; -	sbp->hash = xfs_dir_hash_dotdot; -	sbp->ino = XFS_GET_DIR_INO8(sf->hdr.parent); -	sbp->name = ".."; -	sbp->namelen = 2; -	sbp++; - -	/* -	 * Scan the directory data for the rest of the entries. -	 */ -	for (i = 0, sfe = &sf->list[0]; i < sf->hdr.count; i++) { - -		if (unlikely( -		    ((char *)sfe < (char *)sf) || -		    ((char *)sfe >= ((char *)sf + dp->i_df.if_bytes)))) { -			xfs_dir_trace_g_du("sf: corrupted", dp, uio); -			XFS_CORRUPTION_ERROR("xfs_dir_shortform_getdents", -					     XFS_ERRLEVEL_LOW, mp, sfe); -			kmem_free(sbuf, sbsize); -			return XFS_ERROR(EFSCORRUPTED); -		} - -		sbp->entno = i + 2; -		sbp->seqno = 0; -		sbp->hash = xfs_da_hashname((char *)sfe->name, sfe->namelen); -		sbp->ino = XFS_GET_DIR_INO8(sfe->inumber); -		sbp->name = (char *)sfe->name; -		sbp->namelen = sfe->namelen; -		sfe = XFS_DIR_SF_NEXTENTRY(sfe); -		sbp++; -	} - -	/* -	 * Sort the entries on hash then entno. -	 */ -	xfs_sort(sbuf, nsbuf, sizeof(*sbuf), xfs_dir_shortform_compare); -	/* -	 * Stuff in last entry. -	 */ -	sbp->entno = nsbuf; -	sbp->hash = XFS_DA_MAXHASH; -	sbp->seqno = 0; -	/* -	 * Figure out the sequence numbers in case there's a hash duplicate. -	 */ -	for (hash = sbuf->hash, sbp = sbuf + 1; -				sbp < &sbuf[nsbuf + 1]; sbp++) { -		if (sbp->hash == hash) -			sbp->seqno = sbp[-1].seqno + 1; -		else -			hash = sbp->hash; -	} - -	/* -	 * Set up put routine. -	 */ -	p.dbp = dbp; -	p.put = put; -	p.uio = uio; - -	/* -	 * Find our place. -	 */ -	for (sbp = sbuf; sbp < &sbuf[nsbuf + 1]; sbp++) { -		if (sbp->hash > cookhash || -		    (sbp->hash == cookhash && sbp->seqno >= want_entno)) -			break; -	} - -	/* -	 * Did we fail to find anything?  We stop at the last entry, -	 * the one we put maxhash into. -	 */ -	if (sbp == &sbuf[nsbuf]) { -		kmem_free(sbuf, sbsize); -		xfs_dir_trace_g_du("sf: hash beyond end", dp, uio); -		uio->uio_offset = XFS_DA_MAKE_COOKIE(mp, 0, 0, XFS_DA_MAXHASH); -		*eofp = 1; -		return 0; -	} - -	/* -	 * Loop putting entries into the user buffer. -	 */ -	while (sbp < &sbuf[nsbuf]) { -		/* -		 * Save the first resid in a run of equal-hashval entries -		 * so that we can back them out if they don't all fit. -		 */ -		if (sbp->seqno == 0 || sbp == sbuf) -			lastresid = uio->uio_resid; -		XFS_PUT_COOKIE(p.cook, mp, 0, sbp[1].seqno, sbp[1].hash); -		p.ino = sbp->ino; -#if XFS_BIG_INUMS -		p.ino += mp->m_inoadd; -#endif -		p.name = sbp->name; -		p.namelen = sbp->namelen; -		retval = p.put(&p); -		if (!p.done) { -			uio->uio_offset = -				XFS_DA_MAKE_COOKIE(mp, 0, 0, sbp->hash); -			kmem_free(sbuf, sbsize); -			uio->uio_resid = lastresid; -			xfs_dir_trace_g_du("sf: E-O-B", dp, uio); -			return retval; -		} -		sbp++; -	} -	kmem_free(sbuf, sbsize); -	uio->uio_offset = p.cook.o; -	*eofp = 1; -	xfs_dir_trace_g_du("sf: E-O-F", dp, uio); -	return 0; -} - -/* - * Look up a name in a shortform directory structure, replace the inode number. - */ -int -xfs_dir_shortform_replace(xfs_da_args_t *args) -{ -	xfs_dir_shortform_t *sf; -	xfs_dir_sf_entry_t *sfe; -	xfs_inode_t *dp; -	int i; - -	dp = args->dp; -	ASSERT(dp->i_df.if_flags & XFS_IFINLINE); -	/* -	 * Catch the case where the conversion from shortform to leaf -	 * failed part way through. -	 */ -	if (dp->i_d.di_size < sizeof(xfs_dir_sf_hdr_t)) { -		ASSERT(XFS_FORCED_SHUTDOWN(dp->i_mount)); -		return XFS_ERROR(EIO); -	} -	ASSERT(dp->i_df.if_bytes == dp->i_d.di_size); -	ASSERT(dp->i_df.if_u1.if_data != NULL); -	sf = (xfs_dir_shortform_t *)dp->i_df.if_u1.if_data; -	if (args->namelen == 2 && -	    args->name[0] == '.' && args->name[1] == '.') { -		/* XXX - replace assert? */ -		XFS_DIR_SF_PUT_DIRINO(&args->inumber, &sf->hdr.parent); -		xfs_trans_log_inode(args->trans, dp, XFS_ILOG_DDATA); -		return 0; -	} -	ASSERT(args->namelen != 1 || args->name[0] != '.'); -	sfe = &sf->list[0]; -	for (i = sf->hdr.count-1; i >= 0; i--) { -		if (sfe->namelen == args->namelen && -		    sfe->name[0] == args->name[0] && -		    memcmp(args->name, sfe->name, args->namelen) == 0) { -			ASSERT(memcmp((char *)&args->inumber, -				(char *)&sfe->inumber, sizeof(xfs_ino_t))); -			XFS_DIR_SF_PUT_DIRINO(&args->inumber, &sfe->inumber); -			xfs_trans_log_inode(args->trans, dp, XFS_ILOG_DDATA); -			return 0; -		} -		sfe = XFS_DIR_SF_NEXTENTRY(sfe); -	} -	ASSERT(args->oknoent); -	return XFS_ERROR(ENOENT); -} - -/* - * Convert a leaf directory to shortform structure - */ -int -xfs_dir_leaf_to_shortform(xfs_da_args_t *iargs) -{ -	xfs_dir_leafblock_t *leaf; -	xfs_dir_leaf_hdr_t *hdr; -	xfs_dir_leaf_entry_t *entry; -	xfs_dir_leaf_name_t *namest; -	xfs_da_args_t args; -	xfs_inode_t *dp; -	xfs_ino_t parent = 0; -	char *tmpbuffer; -	int retval, i; -	xfs_dabuf_t *bp; - -	dp = iargs->dp; -	tmpbuffer = kmem_alloc(XFS_LBSIZE(dp->i_mount), KM_SLEEP); -	ASSERT(tmpbuffer != NULL); - -	retval = xfs_da_read_buf(iargs->trans, iargs->dp, 0, -1, &bp, -					       XFS_DATA_FORK); -	if (retval) -		goto out; -	ASSERT(bp != NULL); -	memcpy(tmpbuffer, bp->data, XFS_LBSIZE(dp->i_mount)); -	leaf = (xfs_dir_leafblock_t *)tmpbuffer; -	ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR_LEAF_MAGIC); -	memset(bp->data, 0, XFS_LBSIZE(dp->i_mount)); - -	/* -	 * Find and special case the parent inode number -	 */ -	hdr = &leaf->hdr; -	entry = &leaf->entries[0]; -	for (i = be16_to_cpu(hdr->count)-1; i >= 0; entry++, i--) { -		namest = XFS_DIR_LEAF_NAMESTRUCT(leaf, be16_to_cpu(entry->nameidx)); -		if ((entry->namelen == 2) && -		    (namest->name[0] == '.') && -		    (namest->name[1] == '.')) { -			XFS_DIR_SF_GET_DIRINO(&namest->inumber, &parent); -			entry->nameidx = 0; -		} else if ((entry->namelen == 1) && (namest->name[0] == '.')) { -			entry->nameidx = 0; -		} -	} -	retval = xfs_da_shrink_inode(iargs, 0, bp); -	if (retval) -		goto out; -	retval = xfs_dir_shortform_create(iargs, parent); -	if (retval) -		goto out; - -	/* -	 * Copy the rest of the filenames -	 */ -	entry = &leaf->entries[0]; -	args.dp = dp; -	args.firstblock = iargs->firstblock; -	args.flist = iargs->flist; -	args.total = iargs->total; -	args.whichfork = XFS_DATA_FORK; -	args.trans = iargs->trans; -	args.justcheck = 0; -	args.addname = args.oknoent = 1; -	for (i = 0; i < be16_to_cpu(hdr->count); entry++, i++) { -		if (!entry->nameidx) -			continue; -		namest = XFS_DIR_LEAF_NAMESTRUCT(leaf, be16_to_cpu(entry->nameidx)); -		args.name = (char *)(namest->name); -		args.namelen = entry->namelen; -		args.hashval = be32_to_cpu(entry->hashval); -		XFS_DIR_SF_GET_DIRINO(&namest->inumber, &args.inumber); -		xfs_dir_shortform_addname(&args); -	} - -out: -	kmem_free(tmpbuffer, XFS_LBSIZE(dp->i_mount)); -	return retval; -} - -/* - * Convert from using a single leaf to a root node and a leaf. - */ -int -xfs_dir_leaf_to_node(xfs_da_args_t *args) -{ -	xfs_dir_leafblock_t *leaf; -	xfs_da_intnode_t *node; -	xfs_inode_t *dp; -	xfs_dabuf_t *bp1, *bp2; -	xfs_dablk_t blkno; -	int retval; - -	dp = args->dp; -	retval = xfs_da_grow_inode(args, &blkno); -	ASSERT(blkno == 1); -	if (retval) -		return retval; -	retval = xfs_da_read_buf(args->trans, args->dp, 0, -1, &bp1, -					      XFS_DATA_FORK); -	if (retval) -		return retval; -	ASSERT(bp1 != NULL); -	retval = xfs_da_get_buf(args->trans, args->dp, 1, -1, &bp2, -					     XFS_DATA_FORK); -	if (retval) { -		xfs_da_buf_done(bp1); -		return retval; -	} -	ASSERT(bp2 != NULL); -	memcpy(bp2->data, bp1->data, XFS_LBSIZE(dp->i_mount)); -	xfs_da_buf_done(bp1); -	xfs_da_log_buf(args->trans, bp2, 0, XFS_LBSIZE(dp->i_mount) - 1); - -	/* -	 * Set up the new root node. -	 */ -	retval = xfs_da_node_create(args, 0, 1, &bp1, XFS_DATA_FORK); -	if (retval) { -		xfs_da_buf_done(bp2); -		return retval; -	} -	node = bp1->data; -	leaf = bp2->data; -	ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR_LEAF_MAGIC); -	node->btree[0].hashval = leaf->entries[be16_to_cpu(leaf->hdr.count)-1].hashval; -	xfs_da_buf_done(bp2); -	node->btree[0].before = cpu_to_be32(blkno); -	node->hdr.count = cpu_to_be16(1); -	xfs_da_log_buf(args->trans, bp1, -		XFS_DA_LOGRANGE(node, &node->btree[0], sizeof(node->btree[0]))); -	xfs_da_buf_done(bp1); - -	return retval; -} - - -/*======================================================================== - * Routines used for growing the Btree. - *========================================================================*/ - -/* - * Create the initial contents of a leaf directory - * or a leaf in a node directory. - */ -STATIC int -xfs_dir_leaf_create(xfs_da_args_t *args, xfs_dablk_t blkno, xfs_dabuf_t **bpp) -{ -	xfs_dir_leafblock_t *leaf; -	xfs_dir_leaf_hdr_t *hdr; -	xfs_inode_t *dp; -	xfs_dabuf_t *bp; -	int retval; - -	dp = args->dp; -	ASSERT(dp != NULL); -	retval = xfs_da_get_buf(args->trans, dp, blkno, -1, &bp, XFS_DATA_FORK); -	if (retval) -		return retval; -	ASSERT(bp != NULL); -	leaf = bp->data; -	memset((char *)leaf, 0, XFS_LBSIZE(dp->i_mount)); -	hdr = &leaf->hdr; -	hdr->info.magic = cpu_to_be16(XFS_DIR_LEAF_MAGIC); -	hdr->firstused = cpu_to_be16(XFS_LBSIZE(dp->i_mount)); -	if (!hdr->firstused) -		hdr->firstused = cpu_to_be16(XFS_LBSIZE(dp->i_mount) - 1); -	hdr->freemap[0].base = cpu_to_be16(sizeof(xfs_dir_leaf_hdr_t)); -	hdr->freemap[0].size = cpu_to_be16(be16_to_cpu(hdr->firstused) - -					   be16_to_cpu(hdr->freemap[0].base)); - -	xfs_da_log_buf(args->trans, bp, 0, XFS_LBSIZE(dp->i_mount) - 1); - -	*bpp = bp; -	return 0; -} - -/* - * Split the leaf node, rebalance, then add the new entry. - */ -int -xfs_dir_leaf_split(xfs_da_state_t *state, xfs_da_state_blk_t *oldblk, -				  xfs_da_state_blk_t *newblk) -{ -	xfs_dablk_t blkno; -	xfs_da_args_t *args; -	int error; - -	/* -	 * Allocate space for a new leaf node. -	 */ -	args = state->args; -	ASSERT(args != NULL); -	ASSERT(oldblk->magic == XFS_DIR_LEAF_MAGIC); -	error = xfs_da_grow_inode(args, &blkno); -	if (error) -		return error; -	error = xfs_dir_leaf_create(args, blkno, &newblk->bp); -	if (error) -		return error; -	newblk->blkno = blkno; -	newblk->magic = XFS_DIR_LEAF_MAGIC; - -	/* -	 * Rebalance the entries across the two leaves. -	 */ -	xfs_dir_leaf_rebalance(state, oldblk, newblk); -	error = xfs_da_blk_link(state, oldblk, newblk); -	if (error) -		return error; - -	/* -	 * Insert the new entry in the correct block. -	 */ -	if (state->inleaf) { -		error = xfs_dir_leaf_add(oldblk->bp, args, oldblk->index); -	} else { -		error = xfs_dir_leaf_add(newblk->bp, args, newblk->index); -	} - -	/* -	 * Update last hashval in each block since we added the name. -	 */ -	oldblk->hashval = xfs_dir_leaf_lasthash(oldblk->bp, NULL); -	newblk->hashval = xfs_dir_leaf_lasthash(newblk->bp, NULL); -	return error; -} - -/* - * Add a name to the leaf directory structure. - * - * Must take into account fragmented leaves and leaves where spacemap has - * lost some freespace information (ie: holes). - */ -int -xfs_dir_leaf_add(xfs_dabuf_t *bp, xfs_da_args_t *args, int index) -{ -	xfs_dir_leafblock_t *leaf; -	xfs_dir_leaf_hdr_t *hdr; -	xfs_dir_leaf_map_t *map; -	int tablesize, entsize, sum, i, tmp, error; - -	leaf = bp->data; -	ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR_LEAF_MAGIC); -	ASSERT((index >= 0) && (index <= be16_to_cpu(leaf->hdr.count))); -	hdr = &leaf->hdr; -	entsize = XFS_DIR_LEAF_ENTSIZE_BYNAME(args->namelen); - -	/* -	 * Search through freemap for first-fit on new name length. -	 * (may need to figure in size of entry struct too) -	 */ -	tablesize = (be16_to_cpu(hdr->count) + 1) * -		sizeof(xfs_dir_leaf_entry_t) + sizeof(xfs_dir_leaf_hdr_t); -	map = &hdr->freemap[XFS_DIR_LEAF_MAPSIZE-1]; -	for (sum = 0, i = XFS_DIR_LEAF_MAPSIZE-1; i >= 0; map--, i--) { -		if (tablesize > be16_to_cpu(hdr->firstused)) { -			sum += be16_to_cpu(map->size); -			continue; -		} -		if (!map->size) -			continue;	/* no space in this map */ -		tmp = entsize; -		if (be16_to_cpu(map->base) < be16_to_cpu(hdr->firstused)) -			tmp += (uint)sizeof(xfs_dir_leaf_entry_t); -		if (be16_to_cpu(map->size) >= tmp) { -			if (!args->justcheck) -				xfs_dir_leaf_add_work(bp, args, index, i); -			return 0; -		} -		sum += be16_to_cpu(map->size); -	} - -	/* -	 * If there are no holes in the address space of the block, -	 * and we don't have enough freespace, then compaction will do us -	 * no good and we should just give up. -	 */ -	if (!hdr->holes && (sum < entsize)) -		return XFS_ERROR(ENOSPC); - -	/* -	 * Compact the entries to coalesce free space. -	 * Pass the justcheck flag so the checking pass can return -	 * an error, without changing anything, if it won't fit. -	 */ -	error = xfs_dir_leaf_compact(args->trans, bp, -			args->total == 0 ? -				entsize + -				(uint)sizeof(xfs_dir_leaf_entry_t) : 0, -			args->justcheck); -	if (error) -		return error; -	/* -	 * After compaction, the block is guaranteed to have only one -	 * free region, in freemap[0].  If it is not big enough, give up. -	 */ -	if (be16_to_cpu(hdr->freemap[0].size) < -	    (entsize + (uint)sizeof(xfs_dir_leaf_entry_t))) -		return XFS_ERROR(ENOSPC); - -	if (!args->justcheck) -		xfs_dir_leaf_add_work(bp, args, index, 0); -	return 0; -} - -/* - * Add a name to a leaf directory structure. - */ -STATIC void -xfs_dir_leaf_add_work(xfs_dabuf_t *bp, xfs_da_args_t *args, int index, -		      int mapindex) -{ -	xfs_dir_leafblock_t *leaf; -	xfs_dir_leaf_hdr_t *hdr; -	xfs_dir_leaf_entry_t *entry; -	xfs_dir_leaf_name_t *namest; -	xfs_dir_leaf_map_t *map; -	/* REFERENCED */ -	xfs_mount_t *mp; -	int tmp, i; - -	leaf = bp->data; -	ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR_LEAF_MAGIC); -	hdr = &leaf->hdr; -	ASSERT((mapindex >= 0) && (mapindex < XFS_DIR_LEAF_MAPSIZE)); -	ASSERT((index >= 0) && (index <= be16_to_cpu(hdr->count))); - -	/* -	 * Force open some space in the entry array and fill it in. -	 */ -	entry = &leaf->entries[index]; -	if (index < be16_to_cpu(hdr->count)) { -		tmp  = be16_to_cpu(hdr->count) - index; -		tmp *= (uint)sizeof(xfs_dir_leaf_entry_t); -		memmove(entry + 1, entry, tmp); -		xfs_da_log_buf(args->trans, bp, -		    XFS_DA_LOGRANGE(leaf, entry, tmp + (uint)sizeof(*entry))); -	} -	be16_add(&hdr->count, 1); - -	/* -	 * Allocate space for the new string (at the end of the run). -	 */ -	map = &hdr->freemap[mapindex]; -	mp = args->trans->t_mountp; -	ASSERT(be16_to_cpu(map->base) < XFS_LBSIZE(mp)); -	ASSERT(be16_to_cpu(map->size) >= XFS_DIR_LEAF_ENTSIZE_BYNAME(args->namelen)); -	ASSERT(be16_to_cpu(map->size) < XFS_LBSIZE(mp)); - -	be16_add(&map->size, -(XFS_DIR_LEAF_ENTSIZE_BYNAME(args->namelen))); -	entry->nameidx = cpu_to_be16(be16_to_cpu(map->base) + -				     be16_to_cpu(map->size)); -	entry->hashval = cpu_to_be32(args->hashval); -	entry->namelen = args->namelen; -	xfs_da_log_buf(args->trans, bp, -	    XFS_DA_LOGRANGE(leaf, entry, sizeof(*entry))); - -	/* -	 * Copy the string and inode number into the new space. -	 */ -	namest = XFS_DIR_LEAF_NAMESTRUCT(leaf, be16_to_cpu(entry->nameidx)); -	XFS_DIR_SF_PUT_DIRINO(&args->inumber, &namest->inumber); -	memcpy(namest->name, args->name, args->namelen); -	xfs_da_log_buf(args->trans, bp, -	    XFS_DA_LOGRANGE(leaf, namest, XFS_DIR_LEAF_ENTSIZE_BYENTRY(entry))); - -	/* -	 * Update the control info for this leaf node -	 */ -	if (be16_to_cpu(entry->nameidx) < be16_to_cpu(hdr->firstused)) -		hdr->firstused = entry->nameidx; -	ASSERT(be16_to_cpu(hdr->firstused) >= -	       ((be16_to_cpu(hdr->count)*sizeof(*entry))+sizeof(*hdr))); -	tmp = (be16_to_cpu(hdr->count)-1) * (uint)sizeof(xfs_dir_leaf_entry_t) -			+ (uint)sizeof(xfs_dir_leaf_hdr_t); -	map = &hdr->freemap[0]; -	for (i = 0; i < XFS_DIR_LEAF_MAPSIZE; map++, i++) { -		if (be16_to_cpu(map->base) == tmp) { -			int entry_size = sizeof(xfs_dir_leaf_entry_t); -			be16_add(&map->base, entry_size); -			be16_add(&map->size, -entry_size); -		} -	} -	be16_add(&hdr->namebytes, args->namelen); -	xfs_da_log_buf(args->trans, bp, -		XFS_DA_LOGRANGE(leaf, hdr, sizeof(*hdr))); -} - -/* - * Garbage collect a leaf directory block by copying it to a new buffer. - */ -STATIC int -xfs_dir_leaf_compact(xfs_trans_t *trans, xfs_dabuf_t *bp, int musthave, -		     int justcheck) -{ -	xfs_dir_leafblock_t *leaf_s, *leaf_d; -	xfs_dir_leaf_hdr_t *hdr_s, *hdr_d; -	xfs_mount_t *mp; -	char *tmpbuffer; -	char *tmpbuffer2=NULL; -	int rval; -	int lbsize; - -	mp = trans->t_mountp; -	lbsize = XFS_LBSIZE(mp); -	tmpbuffer = kmem_alloc(lbsize, KM_SLEEP); -	ASSERT(tmpbuffer != NULL); -	memcpy(tmpbuffer, bp->data, lbsize); - -	/* -	 * Make a second copy in case xfs_dir_leaf_moveents() -	 * below destroys the original. -	 */ -	if (musthave || justcheck) { -		tmpbuffer2 = kmem_alloc(lbsize, KM_SLEEP); -		memcpy(tmpbuffer2, bp->data, lbsize); -	} -	memset(bp->data, 0, lbsize); - -	/* -	 * Copy basic information -	 */ -	leaf_s = (xfs_dir_leafblock_t *)tmpbuffer; -	leaf_d = bp->data; -	hdr_s = &leaf_s->hdr; -	hdr_d = &leaf_d->hdr; -	hdr_d->info = hdr_s->info;	/* struct copy */ -	hdr_d->firstused = cpu_to_be16(lbsize); -	if (!hdr_d->firstused) -		hdr_d->firstused = cpu_to_be16(lbsize - 1); -	hdr_d->namebytes = 0; -	hdr_d->count = 0; -	hdr_d->holes = 0; -	hdr_d->freemap[0].base = cpu_to_be16(sizeof(xfs_dir_leaf_hdr_t)); -	hdr_d->freemap[0].size = cpu_to_be16(be16_to_cpu(hdr_d->firstused) - -			                     be16_to_cpu(hdr_d->freemap[0].base)); - -	/* -	 * Copy all entry's in the same (sorted) order, -	 * but allocate filenames packed and in sequence. -	 * This changes the source (leaf_s) as well. -	 */ -	xfs_dir_leaf_moveents(leaf_s, 0, leaf_d, 0, be16_to_cpu(hdr_s->count), mp); - -	if (musthave && be16_to_cpu(hdr_d->freemap[0].size) < musthave) -		rval = XFS_ERROR(ENOSPC); -	else -		rval = 0; - -	if (justcheck || rval == ENOSPC) { -		ASSERT(tmpbuffer2); -		memcpy(bp->data, tmpbuffer2, lbsize); -	} else { -		xfs_da_log_buf(trans, bp, 0, lbsize - 1); -	} - -	kmem_free(tmpbuffer, lbsize); -	if (musthave || justcheck) -		kmem_free(tmpbuffer2, lbsize); -	return rval; -} - -/* - * Redistribute the directory entries between two leaf nodes, - * taking into account the size of the new entry. - * - * NOTE: if new block is empty, then it will get the upper half of old block. - */ -STATIC void -xfs_dir_leaf_rebalance(xfs_da_state_t *state, xfs_da_state_blk_t *blk1, -				      xfs_da_state_blk_t *blk2) -{ -	xfs_da_state_blk_t *tmp_blk; -	xfs_dir_leafblock_t *leaf1, *leaf2; -	xfs_dir_leaf_hdr_t *hdr1, *hdr2; -	int count, totallen, max, space, swap; - -	/* -	 * Set up environment. -	 */ -	ASSERT(blk1->magic == XFS_DIR_LEAF_MAGIC); -	ASSERT(blk2->magic == XFS_DIR_LEAF_MAGIC); -	leaf1 = blk1->bp->data; -	leaf2 = blk2->bp->data; -	ASSERT(be16_to_cpu(leaf1->hdr.info.magic) == XFS_DIR_LEAF_MAGIC); -	ASSERT(be16_to_cpu(leaf2->hdr.info.magic) == XFS_DIR_LEAF_MAGIC); - -	/* -	 * Check ordering of blocks, reverse if it makes things simpler. -	 */ -	swap = 0; -	if (xfs_dir_leaf_order(blk1->bp, blk2->bp)) { -		tmp_blk = blk1; -		blk1 = blk2; -		blk2 = tmp_blk; -		leaf1 = blk1->bp->data; -		leaf2 = blk2->bp->data; -		swap = 1; -	} -	hdr1 = &leaf1->hdr; -	hdr2 = &leaf2->hdr; - -	/* -	 * Examine entries until we reduce the absolute difference in -	 * byte usage between the two blocks to a minimum.  Then get -	 * the direction to copy and the number of elements to move. -	 */ -	state->inleaf = xfs_dir_leaf_figure_balance(state, blk1, blk2, -							   &count, &totallen); -	if (swap) -		state->inleaf = !state->inleaf; - -	/* -	 * Move any entries required from leaf to leaf: -	 */ -	if (count < be16_to_cpu(hdr1->count)) { -		/* -		 * Figure the total bytes to be added to the destination leaf. -		 */ -		count = be16_to_cpu(hdr1->count) - count;	/* number entries being moved */ -		space = be16_to_cpu(hdr1->namebytes) - totallen; -		space += count * ((uint)sizeof(xfs_dir_leaf_name_t)-1); -		space += count * (uint)sizeof(xfs_dir_leaf_entry_t); - -		/* -		 * leaf2 is the destination, compact it if it looks tight. -		 */ -		max  = be16_to_cpu(hdr2->firstused) - (uint)sizeof(xfs_dir_leaf_hdr_t); -		max -= be16_to_cpu(hdr2->count) * (uint)sizeof(xfs_dir_leaf_entry_t); -		if (space > max) { -			xfs_dir_leaf_compact(state->args->trans, blk2->bp, -								 0, 0); -		} - -		/* -		 * Move high entries from leaf1 to low end of leaf2. -		 */ -		xfs_dir_leaf_moveents(leaf1, be16_to_cpu(hdr1->count) - count, -					     leaf2, 0, count, state->mp); - -		xfs_da_log_buf(state->args->trans, blk1->bp, 0, -						   state->blocksize-1); -		xfs_da_log_buf(state->args->trans, blk2->bp, 0, -						   state->blocksize-1); - -	} else if (count > be16_to_cpu(hdr1->count)) { -		/* -		 * Figure the total bytes to be added to the destination leaf. -		 */ -		count -= be16_to_cpu(hdr1->count);		/* number entries being moved */ -		space  = totallen - be16_to_cpu(hdr1->namebytes); -		space += count * ((uint)sizeof(xfs_dir_leaf_name_t)-1); -		space += count * (uint)sizeof(xfs_dir_leaf_entry_t); - -		/* -		 * leaf1 is the destination, compact it if it looks tight. -		 */ -		max  = be16_to_cpu(hdr1->firstused) - (uint)sizeof(xfs_dir_leaf_hdr_t); -		max -= be16_to_cpu(hdr1->count) * (uint)sizeof(xfs_dir_leaf_entry_t); -		if (space > max) { -			xfs_dir_leaf_compact(state->args->trans, blk1->bp, -								 0, 0); -		} - -		/* -		 * Move low entries from leaf2 to high end of leaf1. -		 */ -		xfs_dir_leaf_moveents(leaf2, 0, leaf1, be16_to_cpu(hdr1->count), -					     count, state->mp); - -		xfs_da_log_buf(state->args->trans, blk1->bp, 0, -						   state->blocksize-1); -		xfs_da_log_buf(state->args->trans, blk2->bp, 0, -						   state->blocksize-1); -	} - -	/* -	 * Copy out last hashval in each block for B-tree code. -	 */ -	blk1->hashval = be32_to_cpu(leaf1->entries[ -			be16_to_cpu(leaf1->hdr.count)-1].hashval); -	blk2->hashval = be32_to_cpu(leaf2->entries[ -			be16_to_cpu(leaf2->hdr.count)-1].hashval); - -	/* -	 * Adjust the expected index for insertion. -	 * GROT: this doesn't work unless blk2 was originally empty. -	 */ -	if (!state->inleaf) { -		blk2->index = blk1->index - be16_to_cpu(leaf1->hdr.count); -	} -} - -/* - * Examine entries until we reduce the absolute difference in - * byte usage between the two blocks to a minimum. - * GROT: Is this really necessary?  With other than a 512 byte blocksize, - * GROT: there will always be enough room in either block for a new entry. - * GROT: Do a double-split for this case? - */ -STATIC int -xfs_dir_leaf_figure_balance(xfs_da_state_t *state, -					   xfs_da_state_blk_t *blk1, -					   xfs_da_state_blk_t *blk2, -					   int *countarg, int *namebytesarg) -{ -	xfs_dir_leafblock_t *leaf1, *leaf2; -	xfs_dir_leaf_hdr_t *hdr1, *hdr2; -	xfs_dir_leaf_entry_t *entry; -	int count, max, totallen, half; -	int lastdelta, foundit, tmp; - -	/* -	 * Set up environment. -	 */ -	leaf1 = blk1->bp->data; -	leaf2 = blk2->bp->data; -	hdr1 = &leaf1->hdr; -	hdr2 = &leaf2->hdr; -	foundit = 0; -	totallen = 0; - -	/* -	 * Examine entries until we reduce the absolute difference in -	 * byte usage between the two blocks to a minimum. -	 */ -	max = be16_to_cpu(hdr1->count) + be16_to_cpu(hdr2->count); -	half  = (max+1) * (uint)(sizeof(*entry)+sizeof(xfs_dir_leaf_entry_t)-1); -	half += be16_to_cpu(hdr1->namebytes) + be16_to_cpu(hdr2->namebytes) + -		state->args->namelen; -	half /= 2; -	lastdelta = state->blocksize; -	entry = &leaf1->entries[0]; -	for (count = 0; count < max; entry++, count++) { - -#define XFS_DIR_ABS(A)	(((A) < 0) ? -(A) : (A)) -		/* -		 * The new entry is in the first block, account for it. -		 */ -		if (count == blk1->index) { -			tmp = totallen + (uint)sizeof(*entry) -				+ XFS_DIR_LEAF_ENTSIZE_BYNAME(state->args->namelen); -			if (XFS_DIR_ABS(half - tmp) > lastdelta) -				break; -			lastdelta = XFS_DIR_ABS(half - tmp); -			totallen = tmp; -			foundit = 1; -		} - -		/* -		 * Wrap around into the second block if necessary. -		 */ -		if (count == be16_to_cpu(hdr1->count)) { -			leaf1 = leaf2; -			entry = &leaf1->entries[0]; -		} - -		/* -		 * Figure out if next leaf entry would be too much. -		 */ -		tmp = totallen + (uint)sizeof(*entry) -				+ XFS_DIR_LEAF_ENTSIZE_BYENTRY(entry); -		if (XFS_DIR_ABS(half - tmp) > lastdelta) -			break; -		lastdelta = XFS_DIR_ABS(half - tmp); -		totallen = tmp; -#undef XFS_DIR_ABS -	} - -	/* -	 * Calculate the number of namebytes that will end up in lower block. -	 * If new entry not in lower block, fix up the count. -	 */ -	totallen -= -		count * (uint)(sizeof(*entry)+sizeof(xfs_dir_leaf_entry_t)-1); -	if (foundit) { -		totallen -= (sizeof(*entry)+sizeof(xfs_dir_leaf_entry_t)-1) + -			    state->args->namelen; -	} - -	*countarg = count; -	*namebytesarg = totallen; -	return foundit; -} - -/*======================================================================== - * Routines used for shrinking the Btree. - *========================================================================*/ - -/* - * Check a leaf block and its neighbors to see if the block should be - * collapsed into one or the other neighbor.  Always keep the block - * with the smaller block number. - * If the current block is over 50% full, don't try to join it, return 0. - * If the block is empty, fill in the state structure and return 2. - * If it can be collapsed, fill in the state structure and return 1. - * If nothing can be done, return 0. - */ -int -xfs_dir_leaf_toosmall(xfs_da_state_t *state, int *action) -{ -	xfs_dir_leafblock_t *leaf; -	xfs_da_state_blk_t *blk; -	xfs_da_blkinfo_t *info; -	int count, bytes, forward, error, retval, i; -	xfs_dablk_t blkno; -	xfs_dabuf_t *bp; - -	/* -	 * Check for the degenerate case of the block being over 50% full. -	 * If so, it's not worth even looking to see if we might be able -	 * to coalesce with a sibling. -	 */ -	blk = &state->path.blk[ state->path.active-1 ]; -	info = blk->bp->data; -	ASSERT(be16_to_cpu(info->magic) == XFS_DIR_LEAF_MAGIC); -	leaf = (xfs_dir_leafblock_t *)info; -	count = be16_to_cpu(leaf->hdr.count); -	bytes = (uint)sizeof(xfs_dir_leaf_hdr_t) + -		count * (uint)sizeof(xfs_dir_leaf_entry_t) + -		count * ((uint)sizeof(xfs_dir_leaf_name_t)-1) + -		be16_to_cpu(leaf->hdr.namebytes); -	if (bytes > (state->blocksize >> 1)) { -		*action = 0;	/* blk over 50%, don't try to join */ -		return 0; -	} - -	/* -	 * Check for the degenerate case of the block being empty. -	 * If the block is empty, we'll simply delete it, no need to -	 * coalesce it with a sibling block.  We choose (arbitrarily) -	 * to merge with the forward block unless it is NULL. -	 */ -	if (count == 0) { -		/* -		 * Make altpath point to the block we want to keep and -		 * path point to the block we want to drop (this one). -		 */ -		forward = (info->forw != 0); -		memcpy(&state->altpath, &state->path, sizeof(state->path)); -		error = xfs_da_path_shift(state, &state->altpath, forward, -						 0, &retval); -		if (error) -			return error; -		if (retval) { -			*action = 0; -		} else { -			*action = 2; -		} -		return 0; -	} - -	/* -	 * Examine each sibling block to see if we can coalesce with -	 * at least 25% free space to spare.  We need to figure out -	 * whether to merge with the forward or the backward block. -	 * We prefer coalescing with the lower numbered sibling so as -	 * to shrink a directory over time. -	 */ -	forward = (be32_to_cpu(info->forw) < be32_to_cpu(info->back));	/* start with smaller blk num */ -	for (i = 0; i < 2; forward = !forward, i++) { -		if (forward) -			blkno = be32_to_cpu(info->forw); -		else -			blkno = be32_to_cpu(info->back); -		if (blkno == 0) -			continue; -		error = xfs_da_read_buf(state->args->trans, state->args->dp, -							    blkno, -1, &bp, -							    XFS_DATA_FORK); -		if (error) -			return error; -		ASSERT(bp != NULL); - -		leaf = (xfs_dir_leafblock_t *)info; -		count  = be16_to_cpu(leaf->hdr.count); -		bytes  = state->blocksize - (state->blocksize>>2); -		bytes -= be16_to_cpu(leaf->hdr.namebytes); -		leaf = bp->data; -		ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR_LEAF_MAGIC); -		count += be16_to_cpu(leaf->hdr.count); -		bytes -= be16_to_cpu(leaf->hdr.namebytes); -		bytes -= count * ((uint)sizeof(xfs_dir_leaf_name_t) - 1); -		bytes -= count * (uint)sizeof(xfs_dir_leaf_entry_t); -		bytes -= (uint)sizeof(xfs_dir_leaf_hdr_t); -		if (bytes >= 0) -			break;	/* fits with at least 25% to spare */ - -		xfs_da_brelse(state->args->trans, bp); -	} -	if (i >= 2) { -		*action = 0; -		return 0; -	} -	xfs_da_buf_done(bp); - -	/* -	 * Make altpath point to the block we want to keep (the lower -	 * numbered block) and path point to the block we want to drop. -	 */ -	memcpy(&state->altpath, &state->path, sizeof(state->path)); -	if (blkno < blk->blkno) { -		error = xfs_da_path_shift(state, &state->altpath, forward, -						 0, &retval); -	} else { -		error = xfs_da_path_shift(state, &state->path, forward, -						 0, &retval); -	} -	if (error) -		return error; -	if (retval) { -		*action = 0; -	} else { -		*action = 1; -	} -	return 0; -} - -/* - * Remove a name from the leaf directory structure. - * - * Return 1 if leaf is less than 37% full, 0 if >= 37% full. - * If two leaves are 37% full, when combined they will leave 25% free. - */ -int -xfs_dir_leaf_remove(xfs_trans_t *trans, xfs_dabuf_t *bp, int index) -{ -	xfs_dir_leafblock_t *leaf; -	xfs_dir_leaf_hdr_t *hdr; -	xfs_dir_leaf_map_t *map; -	xfs_dir_leaf_entry_t *entry; -	xfs_dir_leaf_name_t *namest; -	int before, after, smallest, entsize; -	int tablesize, tmp, i; -	xfs_mount_t *mp; - -	leaf = bp->data; -	ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR_LEAF_MAGIC); -	hdr = &leaf->hdr; -	mp = trans->t_mountp; -	ASSERT(hdr->count && (be16_to_cpu(hdr->count) < (XFS_LBSIZE(mp)/8))); -	ASSERT((index >= 0) && (index < be16_to_cpu(hdr->count))); -	ASSERT(be16_to_cpu(hdr->firstused) >= -	       ((be16_to_cpu(hdr->count)*sizeof(*entry))+sizeof(*hdr))); -	entry = &leaf->entries[index]; -	ASSERT(be16_to_cpu(entry->nameidx) >= be16_to_cpu(hdr->firstused)); -	ASSERT(be16_to_cpu(entry->nameidx) < XFS_LBSIZE(mp)); - -	/* -	 * Scan through free region table: -	 *    check for adjacency of free'd entry with an existing one, -	 *    find smallest free region in case we need to replace it, -	 *    adjust any map that borders the entry table, -	 */ -	tablesize = be16_to_cpu(hdr->count) * (uint)sizeof(xfs_dir_leaf_entry_t) -			+ (uint)sizeof(xfs_dir_leaf_hdr_t); -	map = &hdr->freemap[0]; -	tmp = be16_to_cpu(map->size); -	before = after = -1; -	smallest = XFS_DIR_LEAF_MAPSIZE - 1; -	entsize = XFS_DIR_LEAF_ENTSIZE_BYENTRY(entry); -	for (i = 0; i < XFS_DIR_LEAF_MAPSIZE; map++, i++) { -		ASSERT(be16_to_cpu(map->base) < XFS_LBSIZE(mp)); -		ASSERT(be16_to_cpu(map->size) < XFS_LBSIZE(mp)); -		if (be16_to_cpu(map->base) == tablesize) { -			int entry_size = sizeof(xfs_dir_leaf_entry_t); -			be16_add(&map->base, -entry_size); -			be16_add(&map->size, entry_size); -		} - -		if ((be16_to_cpu(map->base) + be16_to_cpu(map->size)) == -				be16_to_cpu(entry->nameidx)) { -			before = i; -		} else if (be16_to_cpu(map->base) == -				(be16_to_cpu(entry->nameidx) + entsize)) { -			after = i; -		} else if (be16_to_cpu(map->size) < tmp) { -			tmp = be16_to_cpu(map->size); -			smallest = i; -		} -	} - -	/* -	 * Coalesce adjacent freemap regions, -	 * or replace the smallest region. -	 */ -	if ((before >= 0) || (after >= 0)) { -		if ((before >= 0) && (after >= 0)) { -			map = &hdr->freemap[before]; -			be16_add(&map->size, entsize); -			be16_add(&map->size, be16_to_cpu(hdr->freemap[after].size)); -			hdr->freemap[after].base = 0; -			hdr->freemap[after].size = 0; -		} else if (before >= 0) { -			map = &hdr->freemap[before]; -			be16_add(&map->size, entsize); -		} else { -			map = &hdr->freemap[after]; -			map->base = entry->nameidx; -			be16_add(&map->size, entsize); -		} -	} else { -		/* -		 * Replace smallest region (if it is smaller than free'd entry) -		 */ -		map = &hdr->freemap[smallest]; -		if (be16_to_cpu(map->size) < entsize) { -			map->base = entry->nameidx; -			map->size = cpu_to_be16(entsize); -		} -	} - -	/* -	 * Did we remove the first entry? -	 */ -	if (be16_to_cpu(entry->nameidx) == be16_to_cpu(hdr->firstused)) -		smallest = 1; -	else -		smallest = 0; - -	/* -	 * Compress the remaining entries and zero out the removed stuff. -	 */ -	namest = XFS_DIR_LEAF_NAMESTRUCT(leaf, be16_to_cpu(entry->nameidx)); -	memset((char *)namest, 0, entsize); -	xfs_da_log_buf(trans, bp, XFS_DA_LOGRANGE(leaf, namest, entsize)); - -	be16_add(&hdr->namebytes, -(entry->namelen)); -	tmp = (be16_to_cpu(hdr->count) - index) * (uint)sizeof(xfs_dir_leaf_entry_t); -	memmove(entry, entry + 1, tmp); -	be16_add(&hdr->count, -1); -	xfs_da_log_buf(trans, bp, -	    XFS_DA_LOGRANGE(leaf, entry, tmp + (uint)sizeof(*entry))); -	entry = &leaf->entries[be16_to_cpu(hdr->count)]; -	memset((char *)entry, 0, sizeof(xfs_dir_leaf_entry_t)); - -	/* -	 * If we removed the first entry, re-find the first used byte -	 * in the name area.  Note that if the entry was the "firstused", -	 * then we don't have a "hole" in our block resulting from -	 * removing the name. -	 */ -	if (smallest) { -		tmp = XFS_LBSIZE(mp); -		entry = &leaf->entries[0]; -		for (i = be16_to_cpu(hdr->count)-1; i >= 0; entry++, i--) { -			ASSERT(be16_to_cpu(entry->nameidx) >= -			       be16_to_cpu(hdr->firstused)); -			ASSERT(be16_to_cpu(entry->nameidx) < XFS_LBSIZE(mp)); -			if (be16_to_cpu(entry->nameidx) < tmp) -				tmp = be16_to_cpu(entry->nameidx); -		} -		hdr->firstused = cpu_to_be16(tmp); -		if (!hdr->firstused) -			hdr->firstused = cpu_to_be16(tmp - 1); -	} else { -		hdr->holes = 1;		/* mark as needing compaction */ -	} - -	xfs_da_log_buf(trans, bp, XFS_DA_LOGRANGE(leaf, hdr, sizeof(*hdr))); - -	/* -	 * Check if leaf is less than 50% full, caller may want to -	 * "join" the leaf with a sibling if so. -	 */ -	tmp  = (uint)sizeof(xfs_dir_leaf_hdr_t); -	tmp += be16_to_cpu(leaf->hdr.count) * (uint)sizeof(xfs_dir_leaf_entry_t); -	tmp += be16_to_cpu(leaf->hdr.count) * ((uint)sizeof(xfs_dir_leaf_name_t) - 1); -	tmp += be16_to_cpu(leaf->hdr.namebytes); -	if (tmp < mp->m_dir_magicpct) -		return 1;			/* leaf is < 37% full */ -	return 0; -} - -/* - * Move all the directory entries from drop_leaf into save_leaf. - */ -void -xfs_dir_leaf_unbalance(xfs_da_state_t *state, xfs_da_state_blk_t *drop_blk, -				      xfs_da_state_blk_t *save_blk) -{ -	xfs_dir_leafblock_t *drop_leaf, *save_leaf, *tmp_leaf; -	xfs_dir_leaf_hdr_t *drop_hdr, *save_hdr, *tmp_hdr; -	xfs_mount_t *mp; -	char *tmpbuffer; - -	/* -	 * Set up environment. -	 */ -	mp = state->mp; -	ASSERT(drop_blk->magic == XFS_DIR_LEAF_MAGIC); -	ASSERT(save_blk->magic == XFS_DIR_LEAF_MAGIC); -	drop_leaf = drop_blk->bp->data; -	save_leaf = save_blk->bp->data; -	ASSERT(be16_to_cpu(drop_leaf->hdr.info.magic) == XFS_DIR_LEAF_MAGIC); -	ASSERT(be16_to_cpu(save_leaf->hdr.info.magic) == XFS_DIR_LEAF_MAGIC); -	drop_hdr = &drop_leaf->hdr; -	save_hdr = &save_leaf->hdr; - -	/* -	 * Save last hashval from dying block for later Btree fixup. -	 */ -	drop_blk->hashval = be32_to_cpu(drop_leaf->entries[ -			be16_to_cpu(drop_leaf->hdr.count)-1].hashval); - -	/* -	 * Check if we need a temp buffer, or can we do it in place. -	 * Note that we don't check "leaf" for holes because we will -	 * always be dropping it, toosmall() decided that for us already. -	 */ -	if (save_hdr->holes == 0) { -		/* -		 * dest leaf has no holes, so we add there.  May need -		 * to make some room in the entry array. -		 */ -		if (xfs_dir_leaf_order(save_blk->bp, drop_blk->bp)) { -			xfs_dir_leaf_moveents(drop_leaf, 0, save_leaf, 0, -					be16_to_cpu(drop_hdr->count), mp); -		} else { -			xfs_dir_leaf_moveents(drop_leaf, 0, -					save_leaf, be16_to_cpu(save_hdr->count), -					be16_to_cpu(drop_hdr->count), mp); -		} -	} else { -		/* -		 * Destination has holes, so we make a temporary copy -		 * of the leaf and add them both to that. -		 */ -		tmpbuffer = kmem_alloc(state->blocksize, KM_SLEEP); -		ASSERT(tmpbuffer != NULL); -		memset(tmpbuffer, 0, state->blocksize); -		tmp_leaf = (xfs_dir_leafblock_t *)tmpbuffer; -		tmp_hdr = &tmp_leaf->hdr; -		tmp_hdr->info = save_hdr->info;	/* struct copy */ -		tmp_hdr->count = 0; -		tmp_hdr->firstused = cpu_to_be16(state->blocksize); -		if (!tmp_hdr->firstused) -			tmp_hdr->firstused = cpu_to_be16(state->blocksize - 1); -		tmp_hdr->namebytes = 0; -		if (xfs_dir_leaf_order(save_blk->bp, drop_blk->bp)) { -			xfs_dir_leaf_moveents(drop_leaf, 0, tmp_leaf, 0, -					be16_to_cpu(drop_hdr->count), mp); -			xfs_dir_leaf_moveents(save_leaf, 0, -					tmp_leaf, be16_to_cpu(tmp_leaf->hdr.count), -					be16_to_cpu(save_hdr->count), mp); -		} else { -			xfs_dir_leaf_moveents(save_leaf, 0, tmp_leaf, 0, -						 be16_to_cpu(save_hdr->count), mp); -			xfs_dir_leaf_moveents(drop_leaf, 0, -					      tmp_leaf, be16_to_cpu(tmp_leaf->hdr.count), -					      be16_to_cpu(drop_hdr->count), mp); -		} -		memcpy(save_leaf, tmp_leaf, state->blocksize); -		kmem_free(tmpbuffer, state->blocksize); -	} - -	xfs_da_log_buf(state->args->trans, save_blk->bp, 0, -					   state->blocksize - 1); - -	/* -	 * Copy out last hashval in each block for B-tree code. -	 */ -	save_blk->hashval = be32_to_cpu(save_leaf->entries[ -			be16_to_cpu(save_leaf->hdr.count)-1].hashval); -} - -/*======================================================================== - * Routines used for finding things in the Btree. - *========================================================================*/ - -/* - * Look up a name in a leaf directory structure. - * This is the internal routine, it uses the caller's buffer. - * - * Note that duplicate keys are allowed, but only check within the - * current leaf node.  The Btree code must check in adjacent leaf nodes. - * - * Return in *index the index into the entry[] array of either the found - * entry, or where the entry should have been (insert before that entry). - * - * Don't change the args->inumber unless we find the filename. - */ -int -xfs_dir_leaf_lookup_int(xfs_dabuf_t *bp, xfs_da_args_t *args, int *index) -{ -	xfs_dir_leafblock_t *leaf; -	xfs_dir_leaf_entry_t *entry; -	xfs_dir_leaf_name_t *namest; -	int probe, span; -	xfs_dahash_t hashval; - -	leaf = bp->data; -	ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR_LEAF_MAGIC); -	ASSERT(be16_to_cpu(leaf->hdr.count) < (XFS_LBSIZE(args->dp->i_mount)/8)); - -	/* -	 * Binary search.  (note: small blocks will skip this loop) -	 */ -	hashval = args->hashval; -	probe = span = be16_to_cpu(leaf->hdr.count) / 2; -	for (entry = &leaf->entries[probe]; span > 4; -		   entry = &leaf->entries[probe]) { -		span /= 2; -		if (be32_to_cpu(entry->hashval) < hashval) -			probe += span; -		else if (be32_to_cpu(entry->hashval) > hashval) -			probe -= span; -		else -			break; -	} -	ASSERT((probe >= 0) && \ -	       ((!leaf->hdr.count) || (probe < be16_to_cpu(leaf->hdr.count)))); -	ASSERT((span <= 4) || (be32_to_cpu(entry->hashval) == hashval)); - -	/* -	 * Since we may have duplicate hashval's, find the first matching -	 * hashval in the leaf. -	 */ -	while ((probe > 0) && (be32_to_cpu(entry->hashval) >= hashval)) { -		entry--; -		probe--; -	} -	while ((probe < be16_to_cpu(leaf->hdr.count)) && -	       (be32_to_cpu(entry->hashval) < hashval)) { -		entry++; -		probe++; -	} -	if ((probe == be16_to_cpu(leaf->hdr.count)) || -	    (be32_to_cpu(entry->hashval) != hashval)) { -		*index = probe; -		ASSERT(args->oknoent); -		return XFS_ERROR(ENOENT); -	} - -	/* -	 * Duplicate keys may be present, so search all of them for a match. -	 */ -	while ((probe < be16_to_cpu(leaf->hdr.count)) && -	       (be32_to_cpu(entry->hashval) == hashval)) { -		namest = XFS_DIR_LEAF_NAMESTRUCT(leaf, be16_to_cpu(entry->nameidx)); -		if (entry->namelen == args->namelen && -		    namest->name[0] == args->name[0] && -		    memcmp(args->name, namest->name, args->namelen) == 0) { -			XFS_DIR_SF_GET_DIRINO(&namest->inumber, &args->inumber); -			*index = probe; -			return XFS_ERROR(EEXIST); -		} -		entry++; -		probe++; -	} -	*index = probe; -	ASSERT(probe == be16_to_cpu(leaf->hdr.count) || args->oknoent); -	return XFS_ERROR(ENOENT); -} - -/*======================================================================== - * Utility routines. - *========================================================================*/ - -/* - * Move the indicated entries from one leaf to another. - * NOTE: this routine modifies both source and destination leaves. - */ -/* ARGSUSED */ -STATIC void -xfs_dir_leaf_moveents(xfs_dir_leafblock_t *leaf_s, int start_s, -		      xfs_dir_leafblock_t *leaf_d, int start_d, -		      int count, xfs_mount_t *mp) -{ -	xfs_dir_leaf_hdr_t *hdr_s, *hdr_d; -	xfs_dir_leaf_entry_t *entry_s, *entry_d; -	int tmp, i; - -	/* -	 * Check for nothing to do. -	 */ -	if (count == 0) -		return; - -	/* -	 * Set up environment. -	 */ -	ASSERT(be16_to_cpu(leaf_s->hdr.info.magic) == XFS_DIR_LEAF_MAGIC); -	ASSERT(be16_to_cpu(leaf_d->hdr.info.magic) == XFS_DIR_LEAF_MAGIC); -	hdr_s = &leaf_s->hdr; -	hdr_d = &leaf_d->hdr; -	ASSERT(hdr_s->count && (be16_to_cpu(hdr_s->count) < (XFS_LBSIZE(mp)/8))); -	ASSERT(be16_to_cpu(hdr_s->firstused) >= -		((be16_to_cpu(hdr_s->count)*sizeof(*entry_s))+sizeof(*hdr_s))); -	ASSERT(be16_to_cpu(hdr_d->count) < (XFS_LBSIZE(mp)/8)); -	ASSERT(be16_to_cpu(hdr_d->firstused) >= -		((be16_to_cpu(hdr_d->count)*sizeof(*entry_d))+sizeof(*hdr_d))); - -	ASSERT(start_s < be16_to_cpu(hdr_s->count)); -	ASSERT(start_d <= be16_to_cpu(hdr_d->count)); -	ASSERT(count <= be16_to_cpu(hdr_s->count)); - -	/* -	 * Move the entries in the destination leaf up to make a hole? -	 */ -	if (start_d < be16_to_cpu(hdr_d->count)) { -		tmp  = be16_to_cpu(hdr_d->count) - start_d; -		tmp *= (uint)sizeof(xfs_dir_leaf_entry_t); -		entry_s = &leaf_d->entries[start_d]; -		entry_d = &leaf_d->entries[start_d + count]; -		memcpy(entry_d, entry_s, tmp); -	} - -	/* -	 * Copy all entry's in the same (sorted) order, -	 * but allocate filenames packed and in sequence. -	 */ -	entry_s = &leaf_s->entries[start_s]; -	entry_d = &leaf_d->entries[start_d]; -	for (i = 0; i < count; entry_s++, entry_d++, i++) { -		ASSERT(be16_to_cpu(entry_s->nameidx) >= -		       be16_to_cpu(hdr_s->firstused)); -		tmp = XFS_DIR_LEAF_ENTSIZE_BYENTRY(entry_s); -		be16_add(&hdr_d->firstused, -(tmp)); -		entry_d->hashval = entry_s->hashval; -		entry_d->nameidx = hdr_d->firstused; -		entry_d->namelen = entry_s->namelen; -		ASSERT(be16_to_cpu(entry_d->nameidx) + tmp <= XFS_LBSIZE(mp)); -		memcpy(XFS_DIR_LEAF_NAMESTRUCT(leaf_d, be16_to_cpu(entry_d->nameidx)), -		       XFS_DIR_LEAF_NAMESTRUCT(leaf_s, be16_to_cpu(entry_s->nameidx)), tmp); -		ASSERT(be16_to_cpu(entry_s->nameidx) + tmp <= XFS_LBSIZE(mp)); -		memset((char *)XFS_DIR_LEAF_NAMESTRUCT(leaf_s, -					be16_to_cpu(entry_s->nameidx)), 0, tmp); -		be16_add(&hdr_s->namebytes, -(entry_d->namelen)); -		be16_add(&hdr_d->namebytes, entry_d->namelen); -		be16_add(&hdr_s->count, -1); -		be16_add(&hdr_d->count, +1); -		tmp = be16_to_cpu(hdr_d->count) * (uint)sizeof(xfs_dir_leaf_entry_t) -				+ (uint)sizeof(xfs_dir_leaf_hdr_t); -		ASSERT(be16_to_cpu(hdr_d->firstused) >= tmp); - -	} - -	/* -	 * Zero out the entries we just copied. -	 */ -	if (start_s == be16_to_cpu(hdr_s->count)) { -		tmp = count * (uint)sizeof(xfs_dir_leaf_entry_t); -		entry_s = &leaf_s->entries[start_s]; -		ASSERT((char *)entry_s + tmp <= (char *)leaf_s + XFS_LBSIZE(mp)); -		memset((char *)entry_s, 0, tmp); -	} else { -		/* -		 * Move the remaining entries down to fill the hole, -		 * then zero the entries at the top. -		 */ -		tmp  = be16_to_cpu(hdr_s->count) - count; -		tmp *= (uint)sizeof(xfs_dir_leaf_entry_t); -		entry_s = &leaf_s->entries[start_s + count]; -		entry_d = &leaf_s->entries[start_s]; -		memcpy(entry_d, entry_s, tmp); - -		tmp = count * (uint)sizeof(xfs_dir_leaf_entry_t); -		entry_s = &leaf_s->entries[be16_to_cpu(hdr_s->count)]; -		ASSERT((char *)entry_s + tmp <= (char *)leaf_s + XFS_LBSIZE(mp)); -		memset((char *)entry_s, 0, tmp); -	} - -	/* -	 * Fill in the freemap information -	 */ -	hdr_d->freemap[0].base = cpu_to_be16(sizeof(xfs_dir_leaf_hdr_t) + -			be16_to_cpu(hdr_d->count) * sizeof(xfs_dir_leaf_entry_t)); -	hdr_d->freemap[0].size = cpu_to_be16(be16_to_cpu(hdr_d->firstused) - -			be16_to_cpu(hdr_d->freemap[0].base)); -	hdr_d->freemap[1].base = 0; -	hdr_d->freemap[1].size = 0; -	hdr_d->freemap[2].base = 0; -	hdr_d->freemap[2].size = 0; -	hdr_s->holes = 1;	/* leaf may not be compact */ -} - -/* - * Compare two leaf blocks "order". - */ -int -xfs_dir_leaf_order(xfs_dabuf_t *leaf1_bp, xfs_dabuf_t *leaf2_bp) -{ -	xfs_dir_leafblock_t *leaf1, *leaf2; - -	leaf1 = leaf1_bp->data; -	leaf2 = leaf2_bp->data; -	ASSERT((be16_to_cpu(leaf1->hdr.info.magic) == XFS_DIR_LEAF_MAGIC) && -	       (be16_to_cpu(leaf2->hdr.info.magic) == XFS_DIR_LEAF_MAGIC)); -	if (leaf1->hdr.count && leaf2->hdr.count && -	    ((be32_to_cpu(leaf2->entries[0].hashval) < -	      be32_to_cpu(leaf1->entries[0 ].hashval)) || -	     (be32_to_cpu(leaf2->entries[ -			  be16_to_cpu(leaf2->hdr.count)-1].hashval) < -	      be32_to_cpu(leaf1->entries[ -			  be16_to_cpu(leaf1->hdr.count)-1].hashval)))) { -		return 1; -	} -	return 0; -} - -/* - * Pick up the last hashvalue from a leaf block. - */ -xfs_dahash_t -xfs_dir_leaf_lasthash(xfs_dabuf_t *bp, int *count) -{ -	xfs_dir_leafblock_t *leaf; - -	leaf = bp->data; -	ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR_LEAF_MAGIC); -	if (count) -		*count = be16_to_cpu(leaf->hdr.count); -	if (!leaf->hdr.count) -		return(0); -	return be32_to_cpu(leaf->entries[be16_to_cpu(leaf->hdr.count)-1].hashval); -} - -/* - * Copy out directory entries for getdents(), for leaf directories. - */ -int -xfs_dir_leaf_getdents_int( -	xfs_dabuf_t	*bp, -	xfs_inode_t	*dp, -	xfs_dablk_t	bno, -	uio_t		*uio, -	int		*eobp, -	xfs_dirent_t	*dbp, -	xfs_dir_put_t	put, -	xfs_daddr_t		nextda) -{ -	xfs_dir_leafblock_t	*leaf; -	xfs_dir_leaf_entry_t	*entry; -	xfs_dir_leaf_name_t	*namest; -	int			entno, want_entno, i, nextentno; -	xfs_mount_t		*mp; -	xfs_dahash_t		cookhash; -	xfs_dahash_t		nexthash = 0; -#if (BITS_PER_LONG == 32) -	xfs_dahash_t		lasthash = XFS_DA_MAXHASH; -#endif -	xfs_dir_put_args_t	p; - -	mp = dp->i_mount; -	leaf = bp->data; -	if (be16_to_cpu(leaf->hdr.info.magic) != XFS_DIR_LEAF_MAGIC) { -		*eobp = 1; -		return XFS_ERROR(ENOENT);	/* XXX wrong code */ -	} - -	want_entno = XFS_DA_COOKIE_ENTRY(mp, uio->uio_offset); - -	cookhash = XFS_DA_COOKIE_HASH(mp, uio->uio_offset); - -	xfs_dir_trace_g_dul("leaf: start", dp, uio, leaf); - -	/* -	 * Re-find our place. -	 */ -	for (i = entno = 0, entry = &leaf->entries[0]; -		     i < be16_to_cpu(leaf->hdr.count); entry++, i++) { - -		namest = XFS_DIR_LEAF_NAMESTRUCT(leaf, -				    be16_to_cpu(entry->nameidx)); - -		if (unlikely( -		    ((char *)namest < (char *)leaf) || -		    ((char *)namest >= (char *)leaf + XFS_LBSIZE(mp)))) { -			XFS_CORRUPTION_ERROR("xfs_dir_leaf_getdents_int(1)", -					     XFS_ERRLEVEL_LOW, mp, leaf); -			xfs_dir_trace_g_du("leaf: corrupted", dp, uio); -			return XFS_ERROR(EFSCORRUPTED); -		} -		if (be32_to_cpu(entry->hashval) >= cookhash) { -			if (entno < want_entno && -			    be32_to_cpu(entry->hashval) == cookhash) { -				/* -				 * Trying to get to a particular offset in a -				 * run of equal-hashval entries. -				 */ -				entno++; -			} else if (want_entno > 0 && entno == want_entno && -				   be32_to_cpu(entry->hashval) == cookhash) { -				break; -			} else { -				entno = 0; -				break; -			} -		} -	} - -	if (i == be16_to_cpu(leaf->hdr.count)) { -		xfs_dir_trace_g_du("leaf: hash not found", dp, uio); -		if (!leaf->hdr.info.forw) -			uio->uio_offset = -				XFS_DA_MAKE_COOKIE(mp, 0, 0, XFS_DA_MAXHASH); -		/* -		 * Don't set uio_offset if there's another block: -		 * the node code will be setting uio_offset anyway. -		 */ -		*eobp = 0; -		return 0; -	} -	xfs_dir_trace_g_due("leaf: hash found", dp, uio, entry); - -	p.dbp = dbp; -	p.put = put; -	p.uio = uio; - -	/* -	 * We're synchronized, start copying entries out to the user. -	 */ -	for (; entno >= 0 && i < be16_to_cpu(leaf->hdr.count); -			     entry++, i++, (entno = nextentno)) { -		int lastresid=0, retval; -		xfs_dircook_t lastoffset; -		xfs_dahash_t thishash; - -		/* -		 * Check for a damaged directory leaf block and pick up -		 * the inode number from this entry. -		 */ -		namest = XFS_DIR_LEAF_NAMESTRUCT(leaf, -				    be16_to_cpu(entry->nameidx)); - -		if (unlikely( -		    ((char *)namest < (char *)leaf) || -		    ((char *)namest >= (char *)leaf + XFS_LBSIZE(mp)))) { -			XFS_CORRUPTION_ERROR("xfs_dir_leaf_getdents_int(2)", -					     XFS_ERRLEVEL_LOW, mp, leaf); -			xfs_dir_trace_g_du("leaf: corrupted", dp, uio); -			return XFS_ERROR(EFSCORRUPTED); -		} - -		xfs_dir_trace_g_duc("leaf: middle cookie  ", -						   dp, uio, p.cook.o); - -		if (i < (be16_to_cpu(leaf->hdr.count) - 1)) { -			nexthash = be32_to_cpu(entry[1].hashval); - -			if (nexthash == be32_to_cpu(entry->hashval)) -				nextentno = entno + 1; -			else -				nextentno = 0; -			XFS_PUT_COOKIE(p.cook, mp, bno, nextentno, nexthash); -			xfs_dir_trace_g_duc("leaf: middle cookie  ", -						   dp, uio, p.cook.o); - -		} else if ((thishash = be32_to_cpu(leaf->hdr.info.forw))) { -			xfs_dabuf_t *bp2; -			xfs_dir_leafblock_t *leaf2; - -			ASSERT(nextda != -1); - -			retval = xfs_da_read_buf(dp->i_transp, dp, thishash, -						 nextda, &bp2, XFS_DATA_FORK); -			if (retval) -				return retval; - -			ASSERT(bp2 != NULL); - -			leaf2 = bp2->data; - -			if (unlikely( -			       (be16_to_cpu(leaf2->hdr.info.magic) -						!= XFS_DIR_LEAF_MAGIC) -			    || (be32_to_cpu(leaf2->hdr.info.back) -						!= bno))) {	/* GROT */ -				XFS_CORRUPTION_ERROR("xfs_dir_leaf_getdents_int(3)", -						     XFS_ERRLEVEL_LOW, mp, -						     leaf2); -				xfs_da_brelse(dp->i_transp, bp2); - -				return XFS_ERROR(EFSCORRUPTED); -			} - -			nexthash = be32_to_cpu(leaf2->entries[0].hashval); -			nextentno = -1; -			XFS_PUT_COOKIE(p.cook, mp, thishash, 0, nexthash); -			xfs_da_brelse(dp->i_transp, bp2); -			xfs_dir_trace_g_duc("leaf: next blk cookie", -						   dp, uio, p.cook.o); -		} else { -			nextentno = -1; -			XFS_PUT_COOKIE(p.cook, mp, 0, 0, XFS_DA_MAXHASH); -		} - -		/* -		 * Save off the cookie so we can fall back should the -		 * 'put' into the outgoing buffer fails.  To handle a run -		 * of equal-hashvals, the off_t structure on 64bit -		 * builds has entno built into the cookie to ID the -		 * entry.  On 32bit builds, we only have space for the -		 * hashval so we can't ID specific entries within a group -		 * of same hashval entries.   For this, lastoffset is set -		 * to the first in the run of equal hashvals so we don't -		 * include any entries unless we can include all entries -		 * that share the same hashval.  Hopefully the buffer -		 * provided is big enough to handle it (see pv763517). -		 */ -		thishash = be32_to_cpu(entry->hashval); -#if (BITS_PER_LONG == 32) -		if (thishash != lasthash) { -			XFS_PUT_COOKIE(lastoffset, mp, bno, entno, thishash); -			lastresid = uio->uio_resid; -			lasthash = thishash; -		} else { -			xfs_dir_trace_g_duc("leaf: DUP COOKIES, skipped", -						   dp, uio, p.cook.o); -		} -#else -		XFS_PUT_COOKIE(lastoffset, mp, bno, entno, thishash); -		lastresid = uio->uio_resid; -#endif /* BITS_PER_LONG == 32 */ - -		/* -		 * Put the current entry into the outgoing buffer.  If we fail -		 * then restore the UIO to the first entry in the current -		 * run of equal-hashval entries (probably one 1 entry long). -		 */ -		p.ino = XFS_GET_DIR_INO8(namest->inumber); -#if XFS_BIG_INUMS -		p.ino += mp->m_inoadd; -#endif -		p.name = (char *)namest->name; -		p.namelen = entry->namelen; - -		retval = p.put(&p); - -		if (!p.done) { -			uio->uio_offset = lastoffset.o; -			uio->uio_resid = lastresid; - -			*eobp = 1; - -			xfs_dir_trace_g_du("leaf: E-O-B", dp, uio); - -			return retval; -		} -	} - -	uio->uio_offset = p.cook.o; - -	*eobp = 0; - -	xfs_dir_trace_g_du("leaf: E-O-F", dp, uio); - -	return 0; -} - -/* - * Format a dirent64 structure and copy it out the the user's buffer. - */ -int -xfs_dir_put_dirent64_direct(xfs_dir_put_args_t *pa) -{ -	iovec_t *iovp; -	int reclen, namelen; -	xfs_dirent_t *idbp; -	uio_t *uio; - -	namelen = pa->namelen; -	reclen = DIRENTSIZE(namelen); -	uio = pa->uio; -	if (reclen > uio->uio_resid) { -		pa->done = 0; -		return 0; -	} -	iovp = uio->uio_iov; -	idbp = (xfs_dirent_t *)iovp->iov_base; -	iovp->iov_base = (char *)idbp + reclen; -	iovp->iov_len -= reclen; -	uio->uio_resid -= reclen; -	idbp->d_reclen = reclen; -	idbp->d_ino = pa->ino; -	idbp->d_off = pa->cook.o; -	idbp->d_name[namelen] = '\0'; -	pa->done = 1; -	memcpy(idbp->d_name, pa->name, namelen); -	return 0; -} - -/* - * Format a dirent64 structure and copy it out the the user's buffer. - */ -int -xfs_dir_put_dirent64_uio(xfs_dir_put_args_t *pa) -{ -	int		retval, reclen, namelen; -	xfs_dirent_t	*idbp; -	uio_t		*uio; - -	namelen = pa->namelen; -	reclen = DIRENTSIZE(namelen); -	uio = pa->uio; -	if (reclen > uio->uio_resid) { -		pa->done = 0; -		return 0; -	} -	idbp = pa->dbp; -	idbp->d_reclen = reclen; -	idbp->d_ino = pa->ino; -	idbp->d_off = pa->cook.o; -	idbp->d_name[namelen] = '\0'; -	memcpy(idbp->d_name, pa->name, namelen); -	retval = uio_read((caddr_t)idbp, reclen, uio); -	pa->done = (retval == 0); -	return retval; -} diff --git a/fs/xfs/xfs_dir_leaf.h b/fs/xfs/xfs_dir_leaf.h index 7ca5845195d..e69de29bb2d 100644 --- a/fs/xfs/xfs_dir_leaf.h +++ b/fs/xfs/xfs_dir_leaf.h @@ -1,231 +0,0 @@ -/* - * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. - * All Rights Reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it would be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write the Free Software Foundation, - * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA - */ -#ifndef __XFS_DIR_LEAF_H__ -#define	__XFS_DIR_LEAF_H__ - -/* - * Directory layout, internal structure, access macros, etc. - * - * Large directories are structured around Btrees where all the data - * elements are in the leaf nodes.  Filenames are hashed into an int, - * then that int is used as the index into the Btree.  Since the hashval - * of a filename may not be unique, we may have duplicate keys.  The - * internal links in the Btree are logical block offsets into the file. - */ - -struct uio; -struct xfs_bmap_free; -struct xfs_dabuf; -struct xfs_da_args; -struct xfs_da_state; -struct xfs_da_state_blk; -struct xfs_dir_put_args; -struct xfs_inode; -struct xfs_mount; -struct xfs_trans; - -/*======================================================================== - * Directory Structure when equal to XFS_LBSIZE(mp) bytes. - *========================================================================*/ - -/* - * This is the structure of the leaf nodes in the Btree. - * - * Struct leaf_entry's are packed from the top.  Names grow from the bottom - * but are not packed.  The freemap contains run-length-encoded entries - * for the free bytes after the leaf_entry's, but only the N largest such, - * smaller runs are dropped.  When the freemap doesn't show enough space - * for an allocation, we compact the namelist area and try again.  If we - * still don't have enough space, then we have to split the block. - * - * Since we have duplicate hash keys, for each key that matches, compare - * the actual string.  The root and intermediate node search always takes - * the first-in-the-block key match found, so we should only have to work - * "forw"ard.  If none matches, continue with the "forw"ard leaf nodes - * until the hash key changes or the filename is found. - * - * The parent directory and the self-pointer are explicitly represented - * (ie: there are entries for "." and ".."). - * - * Note that the count being a __uint16_t limits us to something like a - * blocksize of 1.3MB in the face of worst case (short) filenames. - */ -#define XFS_DIR_LEAF_MAPSIZE	3	/* how many freespace slots */ - -typedef struct xfs_dir_leaf_map {	/* RLE map of free bytes */ -	__be16		base;	 	/* base of free region */ -	__be16		size; 		/* run length of free region */ -} xfs_dir_leaf_map_t; - -typedef struct xfs_dir_leaf_hdr {	/* constant-structure header block */ -	xfs_da_blkinfo_t info;		/* block type, links, etc. */ -	__be16		count;		/* count of active leaf_entry's */ -	__be16		namebytes;	/* num bytes of name strings stored */ -	__be16		firstused;	/* first used byte in name area */ -	__u8		holes;		/* != 0 if blk needs compaction */ -	__u8		pad1; -	xfs_dir_leaf_map_t freemap[XFS_DIR_LEAF_MAPSIZE]; -} xfs_dir_leaf_hdr_t; - -typedef struct xfs_dir_leaf_entry {	/* sorted on key, not name */ -	__be32		hashval;	/* hash value of name */ -	__be16		nameidx;	/* index into buffer of name */ -	__u8		namelen;	/* length of name string */ -	__u8		pad2; -} xfs_dir_leaf_entry_t; - -typedef struct xfs_dir_leaf_name { -	xfs_dir_ino_t	inumber;	/* inode number for this key */ -	__uint8_t	name[1];	/* name string itself */ -} xfs_dir_leaf_name_t; - -typedef struct xfs_dir_leafblock { -	xfs_dir_leaf_hdr_t	hdr;	/* constant-structure header block */ -	xfs_dir_leaf_entry_t	entries[1];	/* var sized array */ -	xfs_dir_leaf_name_t	namelist[1];	/* grows from bottom of buf */ -} xfs_dir_leafblock_t; - -/* - * Length of name for which a 512-byte block filesystem - * can get a double split. - */ -#define	XFS_DIR_LEAF_CAN_DOUBLE_SPLIT_LEN	\ -	(512 - (uint)sizeof(xfs_dir_leaf_hdr_t) - \ -	 (uint)sizeof(xfs_dir_leaf_entry_t) * 2 - \ -	 (uint)sizeof(xfs_dir_leaf_name_t) * 2 - (MAXNAMELEN - 2) + 1 + 1) - -typedef int (*xfs_dir_put_t)(struct xfs_dir_put_args *pa); - -typedef union { -	xfs_off_t		o;		/* offset (cookie) */ -	/* -	 * Watch the order here (endian-ness dependent). -	 */ -	struct { -#ifndef XFS_NATIVE_HOST -		xfs_dahash_t	h;	/* hash value */ -		__uint32_t	be;	/* block and entry */ -#else -		__uint32_t	be;	/* block and entry */ -		xfs_dahash_t	h;	/* hash value */ -#endif /* XFS_NATIVE_HOST */ -	} s; -} xfs_dircook_t; - -#define	XFS_PUT_COOKIE(c,mp,bno,entry,hash)	\ -	((c).s.be = XFS_DA_MAKE_BNOENTRY(mp, bno, entry), (c).s.h = (hash)) - -typedef struct xfs_dir_put_args { -	xfs_dircook_t	cook;		/* cookie of (next) entry */ -	xfs_intino_t	ino;		/* inode number */ -	struct xfs_dirent *dbp;		/* buffer pointer */ -	char		*name;		/* directory entry name */ -	int		namelen;	/* length of name */ -	int		done;		/* output: set if value was stored */ -	xfs_dir_put_t	put;		/* put function ptr (i/o) */ -	struct uio	*uio;		/* uio control structure */ -} xfs_dir_put_args_t; - -#define XFS_DIR_LEAF_ENTSIZE_BYNAME(len)	\ -	xfs_dir_leaf_entsize_byname(len) -static inline int xfs_dir_leaf_entsize_byname(int len) -{ -	return (uint)sizeof(xfs_dir_leaf_name_t)-1 + len; -} - -#define XFS_DIR_LEAF_ENTSIZE_BYENTRY(entry)	\ -	xfs_dir_leaf_entsize_byentry(entry) -static inline int xfs_dir_leaf_entsize_byentry(xfs_dir_leaf_entry_t *entry) -{ -	return (uint)sizeof(xfs_dir_leaf_name_t)-1 + (entry)->namelen; -} - -#define XFS_DIR_LEAF_NAMESTRUCT(leafp,offset)	\ -	xfs_dir_leaf_namestruct(leafp,offset) -static inline xfs_dir_leaf_name_t * -xfs_dir_leaf_namestruct(xfs_dir_leafblock_t *leafp, int offset) -{ -	return (xfs_dir_leaf_name_t *)&((char *)(leafp))[offset]; -} - -/*======================================================================== - * Function prototypes for the kernel. - *========================================================================*/ - -/* - * Internal routines when dirsize < XFS_LITINO(mp). - */ -int xfs_dir_shortform_create(struct xfs_da_args *args, xfs_ino_t parent); -int xfs_dir_shortform_addname(struct xfs_da_args *args); -int xfs_dir_shortform_lookup(struct xfs_da_args *args); -int xfs_dir_shortform_to_leaf(struct xfs_da_args *args); -int xfs_dir_shortform_removename(struct xfs_da_args *args); -int xfs_dir_shortform_getdents(struct xfs_inode *dp, struct uio *uio, int *eofp, -			       struct xfs_dirent *dbp, xfs_dir_put_t put); -int xfs_dir_shortform_replace(struct xfs_da_args *args); - -/* - * Internal routines when dirsize == XFS_LBSIZE(mp). - */ -int xfs_dir_leaf_to_node(struct xfs_da_args *args); -int xfs_dir_leaf_to_shortform(struct xfs_da_args *args); - -/* - * Routines used for growing the Btree. - */ -int	xfs_dir_leaf_split(struct xfs_da_state *state, -				  struct xfs_da_state_blk *oldblk, -				  struct xfs_da_state_blk *newblk); -int	xfs_dir_leaf_add(struct xfs_dabuf *leaf_buffer, -				struct xfs_da_args *args, int insertion_index); -int	xfs_dir_leaf_addname(struct xfs_da_args *args); -int	xfs_dir_leaf_lookup_int(struct xfs_dabuf *leaf_buffer, -				       struct xfs_da_args *args, -				       int *index_found_at); -int	xfs_dir_leaf_remove(struct xfs_trans *trans, -				   struct xfs_dabuf *leaf_buffer, -				   int index_to_remove); -int	xfs_dir_leaf_getdents_int(struct xfs_dabuf *bp, struct xfs_inode *dp, -					 xfs_dablk_t bno, struct uio *uio, -					 int *eobp, struct xfs_dirent *dbp, -					 xfs_dir_put_t put, xfs_daddr_t nextda); - -/* - * Routines used for shrinking the Btree. - */ -int	xfs_dir_leaf_toosmall(struct xfs_da_state *state, int *retval); -void	xfs_dir_leaf_unbalance(struct xfs_da_state *state, -					     struct xfs_da_state_blk *drop_blk, -					     struct xfs_da_state_blk *save_blk); - -/* - * Utility routines. - */ -uint	xfs_dir_leaf_lasthash(struct xfs_dabuf *bp, int *count); -int	xfs_dir_leaf_order(struct xfs_dabuf *leaf1_bp, -				  struct xfs_dabuf *leaf2_bp); -int	xfs_dir_put_dirent64_direct(xfs_dir_put_args_t *pa); -int	xfs_dir_put_dirent64_uio(xfs_dir_put_args_t *pa); -int	xfs_dir_ino_validate(struct xfs_mount *mp, xfs_ino_t ino); - -/* - * Global data. - */ -extern xfs_dahash_t	xfs_dir_hash_dot, xfs_dir_hash_dotdot; - -#endif /* __XFS_DIR_LEAF_H__ */ diff --git a/fs/xfs/xfs_dir_sf.h b/fs/xfs/xfs_dir_sf.h index 5b20b4d3f57..e69de29bb2d 100644 --- a/fs/xfs/xfs_dir_sf.h +++ b/fs/xfs/xfs_dir_sf.h @@ -1,155 +0,0 @@ -/* - * Copyright (c) 2000,2005 Silicon Graphics, Inc. - * All Rights Reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it would be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write the Free Software Foundation, - * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA - */ -#ifndef __XFS_DIR_SF_H__ -#define	__XFS_DIR_SF_H__ - -/* - * Directory layout when stored internal to an inode. - * - * Small directories are packed as tightly as possible so as to - * fit into the literal area of the inode. - */ - -typedef struct { __uint8_t i[sizeof(xfs_ino_t)]; } xfs_dir_ino_t; - -/* - * The parent directory has a dedicated field, and the self-pointer must - * be calculated on the fly. - * - * Entries are packed toward the top as tight as possible.  The header - * and the elements much be memcpy'd out into a work area to get correct - * alignment for the inode number fields. - */ -typedef struct xfs_dir_sf_hdr {		/* constant-structure header block */ -	xfs_dir_ino_t	parent;		/* parent dir inode number */ -	__uint8_t	count;		/* count of active entries */ -} xfs_dir_sf_hdr_t; - -typedef struct xfs_dir_sf_entry { -	xfs_dir_ino_t	inumber;	/* referenced inode number */ -	__uint8_t	namelen;	/* actual length of name (no NULL) */ -	__uint8_t	name[1];	/* name */ -} xfs_dir_sf_entry_t; - -typedef struct xfs_dir_shortform { -	xfs_dir_sf_hdr_t	hdr; -	xfs_dir_sf_entry_t	list[1];	/* variable sized array */ -} xfs_dir_shortform_t; - -/* - * We generate this then sort it, so that readdirs are returned in - * hash-order.  Else seekdir won't work. - */ -typedef struct xfs_dir_sf_sort { -	__uint8_t	entno;		/* .=0, ..=1, else entry# + 2 */ -	__uint8_t	seqno;		/* sequence # with same hash value */ -	__uint8_t	namelen;	/* length of name value (no null) */ -	xfs_dahash_t	hash;		/* this entry's hash value */ -	xfs_intino_t	ino;		/* this entry's inode number */ -	char		*name;		/* name value, pointer into buffer */ -} xfs_dir_sf_sort_t; - -#define	XFS_DIR_SF_GET_DIRINO(from,to)	xfs_dir_sf_get_dirino(from, to) -static inline void xfs_dir_sf_get_dirino(xfs_dir_ino_t *from, xfs_ino_t *to) -{ -	*(to) = XFS_GET_DIR_INO8(*from); -} - -#define	XFS_DIR_SF_PUT_DIRINO(from,to)	xfs_dir_sf_put_dirino(from, to) -static inline void xfs_dir_sf_put_dirino(xfs_ino_t *from, xfs_dir_ino_t *to) -{ -	XFS_PUT_DIR_INO8(*(from), *(to)); -} - -#define XFS_DIR_SF_ENTSIZE_BYNAME(len)	xfs_dir_sf_entsize_byname(len) -static inline int xfs_dir_sf_entsize_byname(int len) -{ -	return (uint)sizeof(xfs_dir_sf_entry_t)-1 + (len); -} - -#define XFS_DIR_SF_ENTSIZE_BYENTRY(sfep)	xfs_dir_sf_entsize_byentry(sfep) -static inline int xfs_dir_sf_entsize_byentry(xfs_dir_sf_entry_t *sfep) -{ -	return (uint)sizeof(xfs_dir_sf_entry_t)-1 + (sfep)->namelen; -} - -#define XFS_DIR_SF_NEXTENTRY(sfep)		xfs_dir_sf_nextentry(sfep) -static inline xfs_dir_sf_entry_t *xfs_dir_sf_nextentry(xfs_dir_sf_entry_t *sfep) -{ -	return (xfs_dir_sf_entry_t *) \ -		((char *)(sfep) + XFS_DIR_SF_ENTSIZE_BYENTRY(sfep)); -} - -#define XFS_DIR_SF_ALLFIT(count,totallen)	\ -	xfs_dir_sf_allfit(count,totallen) -static inline int xfs_dir_sf_allfit(int count, int totallen) -{ -	return ((uint)sizeof(xfs_dir_sf_hdr_t) + \ -	       ((uint)sizeof(xfs_dir_sf_entry_t)-1)*(count) + (totallen)); -} - -#if defined(XFS_DIR_TRACE) - -/* - * Kernel tracing support for directories. - */ -struct uio; -struct xfs_inode; -struct xfs_da_intnode; -struct xfs_dinode; -struct xfs_dir_leafblock; -struct xfs_dir_leaf_entry; - -#define	XFS_DIR_TRACE_SIZE	4096	/* size of global trace buffer */ -extern ktrace_t	*xfs_dir_trace_buf; - -/* - * Trace record types. - */ -#define	XFS_DIR_KTRACE_G_DU	1	/* dp, uio */ -#define	XFS_DIR_KTRACE_G_DUB	2	/* dp, uio, bno */ -#define	XFS_DIR_KTRACE_G_DUN	3	/* dp, uio, node */ -#define	XFS_DIR_KTRACE_G_DUL	4	/* dp, uio, leaf */ -#define	XFS_DIR_KTRACE_G_DUE	5	/* dp, uio, leaf entry */ -#define	XFS_DIR_KTRACE_G_DUC	6	/* dp, uio, cookie */ - -void xfs_dir_trace_g_du(char *where, struct xfs_inode *dp, struct uio *uio); -void xfs_dir_trace_g_dub(char *where, struct xfs_inode *dp, struct uio *uio, -			      xfs_dablk_t bno); -void xfs_dir_trace_g_dun(char *where, struct xfs_inode *dp, struct uio *uio, -			      struct xfs_da_intnode *node); -void xfs_dir_trace_g_dul(char *where, struct xfs_inode *dp, struct uio *uio, -			      struct xfs_dir_leafblock *leaf); -void xfs_dir_trace_g_due(char *where, struct xfs_inode *dp, struct uio *uio, -			      struct xfs_dir_leaf_entry *entry); -void xfs_dir_trace_g_duc(char *where, struct xfs_inode *dp, struct uio *uio, -			      xfs_off_t cookie); -void xfs_dir_trace_enter(int type, char *where, -			     void *a0, void *a1, void *a2, void *a3, -			     void *a4, void *a5, void *a6, void *a7, -			     void *a8, void *a9, void *a10, void *a11); -#else -#define	xfs_dir_trace_g_du(w,d,u) -#define	xfs_dir_trace_g_dub(w,d,u,b) -#define	xfs_dir_trace_g_dun(w,d,u,n) -#define	xfs_dir_trace_g_dul(w,d,u,l) -#define	xfs_dir_trace_g_due(w,d,u,e) -#define	xfs_dir_trace_g_duc(w,d,u,c) -#endif /* DEBUG */ - -#endif	/* __XFS_DIR_SF_H__ */ diff --git a/fs/xfs/xfs_dmops.c b/fs/xfs/xfs_dmops.c index 629795b3b3d..1e4a35ddf7f 100644 --- a/fs/xfs/xfs_dmops.c +++ b/fs/xfs/xfs_dmops.c @@ -23,7 +23,6 @@  #include "xfs_trans.h"  #include "xfs_sb.h"  #include "xfs_ag.h" -#include "xfs_dir.h"  #include "xfs_dir2.h"  #include "xfs_dmapi.h"  #include "xfs_mount.h" diff --git a/fs/xfs/xfs_error.c b/fs/xfs/xfs_error.c index 2a21c502401..b95681b03d8 100644 --- a/fs/xfs/xfs_error.c +++ b/fs/xfs/xfs_error.c @@ -22,12 +22,10 @@  #include "xfs_inum.h"  #include "xfs_trans.h"  #include "xfs_sb.h" -#include "xfs_dir.h"  #include "xfs_dir2.h"  #include "xfs_dmapi.h"  #include "xfs_mount.h"  #include "xfs_bmap_btree.h" -#include "xfs_dir_sf.h"  #include "xfs_dir2_sf.h"  #include "xfs_attr_sf.h"  #include "xfs_dinode.h" diff --git a/fs/xfs/xfs_extfree_item.c b/fs/xfs/xfs_extfree_item.c index 8b028f12854..6cf6d8769b9 100644 --- a/fs/xfs/xfs_extfree_item.c +++ b/fs/xfs/xfs_extfree_item.c @@ -23,7 +23,6 @@  #include "xfs_trans.h"  #include "xfs_buf_item.h"  #include "xfs_sb.h" -#include "xfs_dir.h"  #include "xfs_dmapi.h"  #include "xfs_mount.h"  #include "xfs_trans_priv.h" diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c index 650d35f537b..077629bab53 100644 --- a/fs/xfs/xfs_fsops.c +++ b/fs/xfs/xfs_fsops.c @@ -24,14 +24,12 @@  #include "xfs_trans.h"  #include "xfs_sb.h"  #include "xfs_ag.h" -#include "xfs_dir.h"  #include "xfs_dir2.h"  #include "xfs_dmapi.h"  #include "xfs_mount.h"  #include "xfs_bmap_btree.h"  #include "xfs_alloc_btree.h"  #include "xfs_ialloc_btree.h" -#include "xfs_dir_sf.h"  #include "xfs_dir2_sf.h"  #include "xfs_attr_sf.h"  #include "xfs_dinode.h" diff --git a/fs/xfs/xfs_ialloc.c b/fs/xfs/xfs_ialloc.c index 7e5ccfec92b..33164a85aa9 100644 --- a/fs/xfs/xfs_ialloc.c +++ b/fs/xfs/xfs_ialloc.c @@ -24,14 +24,12 @@  #include "xfs_trans.h"  #include "xfs_sb.h"  #include "xfs_ag.h" -#include "xfs_dir.h"  #include "xfs_dir2.h"  #include "xfs_dmapi.h"  #include "xfs_mount.h"  #include "xfs_bmap_btree.h"  #include "xfs_alloc_btree.h"  #include "xfs_ialloc_btree.h" -#include "xfs_dir_sf.h"  #include "xfs_dir2_sf.h"  #include "xfs_attr_sf.h"  #include "xfs_dinode.h" diff --git a/fs/xfs/xfs_ialloc_btree.c b/fs/xfs/xfs_ialloc_btree.c index 60c65683462..616eeeb6953 100644 --- a/fs/xfs/xfs_ialloc_btree.c +++ b/fs/xfs/xfs_ialloc_btree.c @@ -24,14 +24,12 @@  #include "xfs_trans.h"  #include "xfs_sb.h"  #include "xfs_ag.h" -#include "xfs_dir.h"  #include "xfs_dir2.h"  #include "xfs_dmapi.h"  #include "xfs_mount.h"  #include "xfs_bmap_btree.h"  #include "xfs_alloc_btree.h"  #include "xfs_ialloc_btree.h" -#include "xfs_dir_sf.h"  #include "xfs_dir2_sf.h"  #include "xfs_attr_sf.h"  #include "xfs_dinode.h" diff --git a/fs/xfs/xfs_iget.c b/fs/xfs/xfs_iget.c index 7894b72a717..0724df7fabb 100644 --- a/fs/xfs/xfs_iget.c +++ b/fs/xfs/xfs_iget.c @@ -24,14 +24,12 @@  #include "xfs_trans.h"  #include "xfs_sb.h"  #include "xfs_ag.h" -#include "xfs_dir.h"  #include "xfs_dir2.h"  #include "xfs_dmapi.h"  #include "xfs_mount.h"  #include "xfs_bmap_btree.h"  #include "xfs_alloc_btree.h"  #include "xfs_ialloc_btree.h" -#include "xfs_dir_sf.h"  #include "xfs_dir2_sf.h"  #include "xfs_attr_sf.h"  #include "xfs_dinode.h" diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index e799f0d0087..5fa0adb7e17 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -26,14 +26,12 @@  #include "xfs_trans_priv.h"  #include "xfs_sb.h"  #include "xfs_ag.h" -#include "xfs_dir.h"  #include "xfs_dir2.h"  #include "xfs_dmapi.h"  #include "xfs_mount.h"  #include "xfs_bmap_btree.h"  #include "xfs_alloc_btree.h"  #include "xfs_ialloc_btree.h" -#include "xfs_dir_sf.h"  #include "xfs_dir2_sf.h"  #include "xfs_attr_sf.h"  #include "xfs_dinode.h" @@ -2925,13 +2923,6 @@ xfs_iflush_fork(  			ASSERT(ifp->if_bytes <= XFS_IFORK_SIZE(ip, whichfork));  			memcpy(cp, ifp->if_u1.if_data, ifp->if_bytes);  		} -		if (whichfork == XFS_DATA_FORK) { -			if (unlikely(XFS_DIR_SHORTFORM_VALIDATE_ONDISK(mp, dip))) { -				XFS_ERROR_REPORT("xfs_iflush_fork", -						 XFS_ERRLEVEL_LOW, mp); -				return XFS_ERROR(EFSCORRUPTED); -			} -		}  		break;  	case XFS_DINODE_FMT_EXTENTS: diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c index 2caa91b8971..f8e80d8e723 100644 --- a/fs/xfs/xfs_inode_item.c +++ b/fs/xfs/xfs_inode_item.c @@ -25,7 +25,6 @@  #include "xfs_buf_item.h"  #include "xfs_sb.h"  #include "xfs_ag.h" -#include "xfs_dir.h"  #include "xfs_dir2.h"  #include "xfs_dmapi.h"  #include "xfs_mount.h" @@ -33,7 +32,6 @@  #include "xfs_bmap_btree.h"  #include "xfs_alloc_btree.h"  #include "xfs_ialloc_btree.h" -#include "xfs_dir_sf.h"  #include "xfs_dir2_sf.h"  #include "xfs_attr_sf.h"  #include "xfs_dinode.h" diff --git a/fs/xfs/xfs_iocore.c b/fs/xfs/xfs_iocore.c index 89441e69cdd..06d710c9ce4 100644 --- a/fs/xfs/xfs_iocore.c +++ b/fs/xfs/xfs_iocore.c @@ -24,7 +24,6 @@  #include "xfs_trans.h"  #include "xfs_sb.h"  #include "xfs_ag.h" -#include "xfs_dir.h"  #include "xfs_dir2.h"  #include "xfs_dfrag.h"  #include "xfs_dmapi.h" @@ -32,7 +31,6 @@  #include "xfs_bmap_btree.h"  #include "xfs_alloc_btree.h"  #include "xfs_ialloc_btree.h" -#include "xfs_dir_sf.h"  #include "xfs_dir2_sf.h"  #include "xfs_attr_sf.h"  #include "xfs_dinode.h" diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c index d79055207fb..f1949c16df1 100644 --- a/fs/xfs/xfs_iomap.c +++ b/fs/xfs/xfs_iomap.c @@ -23,7 +23,6 @@  #include "xfs_trans.h"  #include "xfs_sb.h"  #include "xfs_ag.h" -#include "xfs_dir.h"  #include "xfs_dir2.h"  #include "xfs_alloc.h"  #include "xfs_dmapi.h" @@ -32,7 +31,6 @@  #include "xfs_bmap_btree.h"  #include "xfs_alloc_btree.h"  #include "xfs_ialloc_btree.h" -#include "xfs_dir_sf.h"  #include "xfs_dir2_sf.h"  #include "xfs_attr_sf.h"  #include "xfs_dinode.h" diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c index a0182ced29c..46249e4d1fe 100644 --- a/fs/xfs/xfs_itable.c +++ b/fs/xfs/xfs_itable.c @@ -24,14 +24,12 @@  #include "xfs_trans.h"  #include "xfs_sb.h"  #include "xfs_ag.h" -#include "xfs_dir.h"  #include "xfs_dir2.h"  #include "xfs_dmapi.h"  #include "xfs_mount.h"  #include "xfs_bmap_btree.h"  #include "xfs_alloc_btree.h"  #include "xfs_ialloc_btree.h" -#include "xfs_dir_sf.h"  #include "xfs_dir2_sf.h"  #include "xfs_attr_sf.h"  #include "xfs_dinode.h" diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index 95d679cd4e7..d8f5d4cbe8b 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c @@ -24,7 +24,6 @@  #include "xfs_trans.h"  #include "xfs_sb.h"  #include "xfs_ag.h" -#include "xfs_dir.h"  #include "xfs_dir2.h"  #include "xfs_dmapi.h"  #include "xfs_mount.h" @@ -36,7 +35,6 @@  #include "xfs_ialloc_btree.h"  #include "xfs_log_recover.h"  #include "xfs_trans_priv.h" -#include "xfs_dir_sf.h"  #include "xfs_dir2_sf.h"  #include "xfs_attr_sf.h"  #include "xfs_dinode.h" diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index f952f9dbf74..55b4237c215 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -24,7 +24,6 @@  #include "xfs_trans.h"  #include "xfs_sb.h"  #include "xfs_ag.h" -#include "xfs_dir.h"  #include "xfs_dir2.h"  #include "xfs_dmapi.h"  #include "xfs_mount.h" @@ -32,7 +31,6 @@  #include "xfs_bmap_btree.h"  #include "xfs_alloc_btree.h"  #include "xfs_ialloc_btree.h" -#include "xfs_dir_sf.h"  #include "xfs_dir2_sf.h"  #include "xfs_attr_sf.h"  #include "xfs_dinode.h" diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index 5ce6416fbd3..10dbf203c62 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c @@ -24,14 +24,12 @@  #include "xfs_trans.h"  #include "xfs_sb.h"  #include "xfs_ag.h" -#include "xfs_dir.h"  #include "xfs_dir2.h"  #include "xfs_dmapi.h"  #include "xfs_mount.h"  #include "xfs_bmap_btree.h"  #include "xfs_alloc_btree.h"  #include "xfs_ialloc_btree.h" -#include "xfs_dir_sf.h"  #include "xfs_dir2_sf.h"  #include "xfs_attr_sf.h"  #include "xfs_dinode.h" @@ -934,18 +932,7 @@ xfs_mountfs(  	vfsp->vfs_altfsid = (xfs_fsid_t *)mp->m_fixedfsid;  	mp->m_dmevmask = 0;	/* not persistent; set after each mount */ -	/* -	 * Select the right directory manager. -	 */ -	mp->m_dirops = -		XFS_SB_VERSION_HASDIRV2(&mp->m_sb) ? -			xfsv2_dirops : -			xfsv1_dirops; - -	/* -	 * Initialize directory manager's entries. -	 */ -	XFS_DIR_MOUNT(mp); +	xfs_dir_mount(mp);  	/*  	 * Initialize the attribute manager's entries. diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index 761f42f989c..b2bd4be4200 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h @@ -403,8 +403,6 @@ typedef struct xfs_mount {  	__uint8_t		m_inode_quiesce;/* call quiesce on new inodes.  						   field governed by m_ilock */  	__uint8_t		m_sectbb_log;	/* sectlog - BBSHIFT */ -	__uint8_t		m_dirversion;	/* 1 or 2 */ -	xfs_dirops_t		m_dirops;	/* table of dir funcs */  	int			m_dirblksize;	/* directory block sz--bytes */  	int			m_dirblkfsbs;	/* directory block sz--fsbs */  	xfs_dablk_t		m_dirdatablk;	/* blockno of dir data v2 */ diff --git a/fs/xfs/xfs_qmops.c b/fs/xfs/xfs_qmops.c index 1408a32eef8..320d63ff9ca 100644 --- a/fs/xfs/xfs_qmops.c +++ b/fs/xfs/xfs_qmops.c @@ -23,7 +23,6 @@  #include "xfs_trans.h"  #include "xfs_sb.h"  #include "xfs_ag.h" -#include "xfs_dir.h"  #include "xfs_dir2.h"  #include "xfs_dmapi.h"  #include "xfs_mount.h" diff --git a/fs/xfs/xfs_rename.c b/fs/xfs/xfs_rename.c index 7d5f9b6ffdb..d98171deaa1 100644 --- a/fs/xfs/xfs_rename.c +++ b/fs/xfs/xfs_rename.c @@ -22,13 +22,11 @@  #include "xfs_inum.h"  #include "xfs_trans.h"  #include "xfs_sb.h" -#include "xfs_dir.h"  #include "xfs_dir2.h"  #include "xfs_dmapi.h"  #include "xfs_mount.h"  #include "xfs_da_btree.h"  #include "xfs_bmap_btree.h" -#include "xfs_dir_sf.h"  #include "xfs_dir2_sf.h"  #include "xfs_attr_sf.h"  #include "xfs_dinode.h" @@ -40,7 +38,6 @@  #include "xfs_refcache.h"  #include "xfs_utils.h"  #include "xfs_trans_space.h" -#include "xfs_dir_leaf.h"  /* @@ -398,34 +395,29 @@ xfs_rename(  		 * fit before actually inserting it.  		 */  		if (spaceres == 0 && -		    (error = XFS_DIR_CANENTER(mp, tp, target_dp, target_name, -				target_namelen))) { +		    (error = xfs_dir_canenter(tp, target_dp, target_name, +						target_namelen)))  			goto error_return; -		}  		/*  		 * If target does not exist and the rename crosses  		 * directories, adjust the target directory link count  		 * to account for the ".." reference from the new entry.  		 */ -		error = XFS_DIR_CREATENAME(mp, tp, target_dp, target_name, +		error = xfs_dir_createname(tp, target_dp, target_name,  					   target_namelen, src_ip->i_ino,  					   &first_block, &free_list, spaceres); -		if (error == ENOSPC) { +		if (error == ENOSPC)  			goto error_return; -		} -		if (error) { +		if (error)  			goto abort_return; -		}  		xfs_ichgtime(target_dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);  		if (new_parent && src_is_directory) {  			error = xfs_bumplink(tp, target_dp); -			if (error) { +			if (error)  				goto abort_return; -			}  		}  	} else { /* target_ip != NULL */ -  		/*  		 * If target exists and it's a directory, check that both  		 * target and source are directories and that target can be @@ -435,7 +427,7 @@ xfs_rename(  			/*  			 * Make sure target dir is empty.  			 */ -			if (!(XFS_DIR_ISEMPTY(target_ip->i_mount, target_ip)) || +			if (!(xfs_dir_isempty(target_ip)) ||  			    (target_ip->i_d.di_nlink > 2)) {  				error = XFS_ERROR(EEXIST);  				goto error_return; @@ -451,12 +443,11 @@ xfs_rename(  		 * In case there is already an entry with the same  		 * name at the destination directory, remove it first.  		 */ -		error = XFS_DIR_REPLACE(mp, tp, target_dp, target_name, -			target_namelen, src_ip->i_ino, &first_block, -			&free_list, spaceres); -		if (error) { +		error = xfs_dir_replace(tp, target_dp, target_name, +					target_namelen, src_ip->i_ino, +					&first_block, &free_list, spaceres); +		if (error)  			goto abort_return; -		}  		xfs_ichgtime(target_dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);  		/* @@ -464,9 +455,8 @@ xfs_rename(  		 * dir no longer points to it.  		 */  		error = xfs_droplink(tp, target_ip); -		if (error) { +		if (error)  			goto abort_return; -		}  		target_ip_dropped = 1;  		if (src_is_directory) { @@ -474,9 +464,8 @@ xfs_rename(  			 * Drop the link from the old "." entry.  			 */  			error = xfs_droplink(tp, target_ip); -			if (error) { +			if (error)  				goto abort_return; -			}  		}  		/* Do this test while we still hold the locks */ @@ -488,18 +477,15 @@ xfs_rename(  	 * Remove the source.  	 */  	if (new_parent && src_is_directory) { -  		/*  		 * Rewrite the ".." entry to point to the new  		 * directory.  		 */ -		error = XFS_DIR_REPLACE(mp, tp, src_ip, "..", 2, -					target_dp->i_ino, &first_block, -					&free_list, spaceres); +		error = xfs_dir_replace(tp, src_ip, "..", 2, target_dp->i_ino, +					&first_block, &free_list, spaceres);  		ASSERT(error != EEXIST); -		if (error) { +		if (error)  			goto abort_return; -		}  		xfs_ichgtime(src_ip, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);  	} else { @@ -527,16 +513,14 @@ xfs_rename(  		 * entry that's moved no longer points to it.  		 */  		error = xfs_droplink(tp, src_dp); -		if (error) { +		if (error)  			goto abort_return; -		}  	} -	error = XFS_DIR_REMOVENAME(mp, tp, src_dp, src_name, src_namelen, +	error = xfs_dir_removename(tp, src_dp, src_name, src_namelen,  			src_ip->i_ino, &first_block, &free_list, spaceres); -	if (error) { +	if (error)  		goto abort_return; -	}  	xfs_ichgtime(src_dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);  	/* diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c index af290cf37ac..0c1e42b037e 100644 --- a/fs/xfs/xfs_rtalloc.c +++ b/fs/xfs/xfs_rtalloc.c @@ -24,14 +24,12 @@  #include "xfs_trans.h"  #include "xfs_sb.h"  #include "xfs_ag.h" -#include "xfs_dir.h"  #include "xfs_dir2.h"  #include "xfs_dmapi.h"  #include "xfs_mount.h"  #include "xfs_bmap_btree.h"  #include "xfs_alloc_btree.h"  #include "xfs_ialloc_btree.h" -#include "xfs_dir_sf.h"  #include "xfs_dir2_sf.h"  #include "xfs_attr_sf.h"  #include "xfs_dinode.h" diff --git a/fs/xfs/xfs_rw.c b/fs/xfs/xfs_rw.c index c55e28189ab..defb2febaaf 100644 --- a/fs/xfs/xfs_rw.c +++ b/fs/xfs/xfs_rw.c @@ -24,14 +24,12 @@  #include "xfs_trans.h"  #include "xfs_sb.h"  #include "xfs_ag.h" -#include "xfs_dir.h"  #include "xfs_dir2.h"  #include "xfs_dmapi.h"  #include "xfs_mount.h"  #include "xfs_bmap_btree.h"  #include "xfs_alloc_btree.h"  #include "xfs_ialloc_btree.h" -#include "xfs_dir_sf.h"  #include "xfs_dir2_sf.h"  #include "xfs_attr_sf.h"  #include "xfs_dinode.h" diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c index 39f0b1ed322..ee2721e0de4 100644 --- a/fs/xfs/xfs_trans.c +++ b/fs/xfs/xfs_trans.c @@ -24,7 +24,6 @@  #include "xfs_trans.h"  #include "xfs_sb.h"  #include "xfs_ag.h" -#include "xfs_dir.h"  #include "xfs_dir2.h"  #include "xfs_dmapi.h"  #include "xfs_mount.h" @@ -33,7 +32,6 @@  #include "xfs_bmap_btree.h"  #include "xfs_alloc_btree.h"  #include "xfs_ialloc_btree.h" -#include "xfs_dir_sf.h"  #include "xfs_dir2_sf.h"  #include "xfs_attr_sf.h"  #include "xfs_dinode.h" diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h index 100d9a4b38e..cb65c3a603f 100644 --- a/fs/xfs/xfs_trans.h +++ b/fs/xfs/xfs_trans.h @@ -805,12 +805,9 @@ typedef struct xfs_trans {  	((mp)->m_sb.sb_inodesize + \  	 (mp)->m_sb.sb_sectsize * 2 + \  	 (mp)->m_dirblksize + \ -	 (XFS_DIR_IS_V1(mp) ? 0 : \ -	    XFS_FSB_TO_B(mp, (XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK) + 1))) + \ +	 XFS_FSB_TO_B(mp, (XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK) + 1)) + \  	 XFS_ALLOCFREE_LOG_RES(mp, 1) + \ -	 (128 * (4 + \ -		 (XFS_DIR_IS_V1(mp) ? 0 : \ -			 XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK) + 1) + \ +	 (128 * (4 + (XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK) + 1) + \  		 XFS_ALLOCFREE_LOG_COUNT(mp, 1))))  #define	XFS_ADDAFORK_LOG_RES(mp)	((mp)->m_reservations.tr_addafork) diff --git a/fs/xfs/xfs_trans_ail.c b/fs/xfs/xfs_trans_ail.c index e1ca7b6fde4..558c87ff0c4 100644 --- a/fs/xfs/xfs_trans_ail.c +++ b/fs/xfs/xfs_trans_ail.c @@ -22,7 +22,6 @@  #include "xfs_inum.h"  #include "xfs_trans.h"  #include "xfs_sb.h" -#include "xfs_dir.h"  #include "xfs_dmapi.h"  #include "xfs_mount.h"  #include "xfs_trans_priv.h" diff --git a/fs/xfs/xfs_trans_buf.c b/fs/xfs/xfs_trans_buf.c index 8cedd1583bc..60b6b898022 100644 --- a/fs/xfs/xfs_trans_buf.c +++ b/fs/xfs/xfs_trans_buf.c @@ -24,14 +24,12 @@  #include "xfs_trans.h"  #include "xfs_sb.h"  #include "xfs_ag.h" -#include "xfs_dir.h"  #include "xfs_dir2.h"  #include "xfs_dmapi.h"  #include "xfs_mount.h"  #include "xfs_bmap_btree.h"  #include "xfs_alloc_btree.h"  #include "xfs_ialloc_btree.h" -#include "xfs_dir_sf.h"  #include "xfs_dir2_sf.h"  #include "xfs_attr_sf.h"  #include "xfs_dinode.h" diff --git a/fs/xfs/xfs_trans_extfree.c b/fs/xfs/xfs_trans_extfree.c index 7d7d627f25d..b290270dd4a 100644 --- a/fs/xfs/xfs_trans_extfree.c +++ b/fs/xfs/xfs_trans_extfree.c @@ -22,7 +22,6 @@  #include "xfs_inum.h"  #include "xfs_trans.h"  #include "xfs_sb.h" -#include "xfs_dir.h"  #include "xfs_dmapi.h"  #include "xfs_mount.h"  #include "xfs_trans_priv.h" diff --git a/fs/xfs/xfs_trans_inode.c b/fs/xfs/xfs_trans_inode.c index 7c5894d59f8..b8db1d5cde5 100644 --- a/fs/xfs/xfs_trans_inode.c +++ b/fs/xfs/xfs_trans_inode.c @@ -24,14 +24,12 @@  #include "xfs_trans.h"  #include "xfs_sb.h"  #include "xfs_ag.h" -#include "xfs_dir.h"  #include "xfs_dir2.h"  #include "xfs_dmapi.h"  #include "xfs_mount.h"  #include "xfs_bmap_btree.h"  #include "xfs_alloc_btree.h"  #include "xfs_ialloc_btree.h" -#include "xfs_dir_sf.h"  #include "xfs_dir2_sf.h"  #include "xfs_attr_sf.h"  #include "xfs_dinode.h" diff --git a/fs/xfs/xfs_trans_space.h b/fs/xfs/xfs_trans_space.h index 7fe3792b18d..4ea2e5074bd 100644 --- a/fs/xfs/xfs_trans_space.h +++ b/fs/xfs/xfs_trans_space.h @@ -30,8 +30,7 @@  	  XFS_EXTENTADD_SPACE_RES(mp,w))  #define	XFS_DAENTER_1B(mp,w)	((w) == XFS_DATA_FORK ? (mp)->m_dirblkfsbs : 1)  #define	XFS_DAENTER_DBS(mp,w)	\ -	(XFS_DA_NODE_MAXDEPTH + \ -	 ((XFS_DIR_IS_V2(mp) && (w) == XFS_DATA_FORK) ? 2 : 0)) +	(XFS_DA_NODE_MAXDEPTH + (((w) == XFS_DATA_FORK) ? 2 : 0))  #define	XFS_DAENTER_BLOCKS(mp,w)	\  	(XFS_DAENTER_1B(mp,w) * XFS_DAENTER_DBS(mp,w))  #define	XFS_DAENTER_BMAP1B(mp,w)	\ @@ -41,10 +40,7 @@  #define	XFS_DAENTER_SPACE_RES(mp,w)	\  	(XFS_DAENTER_BLOCKS(mp,w) + XFS_DAENTER_BMAPS(mp,w))  #define	XFS_DAREMOVE_SPACE_RES(mp,w)	XFS_DAENTER_BMAPS(mp,w) -#define	XFS_DIRENTER_MAX_SPLIT(mp,nl)	\ -	(((mp)->m_sb.sb_blocksize == 512 && \ -	  XFS_DIR_IS_V1(mp) && \ -	  (nl) >= XFS_DIR_LEAF_CAN_DOUBLE_SPLIT_LEN) ? 2 : 1) +#define	XFS_DIRENTER_MAX_SPLIT(mp,nl)	1  #define	XFS_DIRENTER_SPACE_RES(mp,nl)	\  	(XFS_DAENTER_SPACE_RES(mp, XFS_DATA_FORK) * \  	 XFS_DIRENTER_MAX_SPLIT(mp,nl)) @@ -57,8 +53,7 @@   * Space reservation values for various transactions.   */  #define	XFS_ADDAFORK_SPACE_RES(mp)	\ -	((mp)->m_dirblkfsbs + \ -	 (XFS_DIR_IS_V1(mp) ? 0 : XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK))) +	((mp)->m_dirblkfsbs + XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK))  #define	XFS_ATTRRM_SPACE_RES(mp)	\  	XFS_DAREMOVE_SPACE_RES(mp, XFS_ATTR_FORK)  /* This macro is not used - see inline code in xfs_attr_set */ diff --git a/fs/xfs/xfs_utils.c b/fs/xfs/xfs_utils.c index 37fdc2dc00b..9014d7e4448 100644 --- a/fs/xfs/xfs_utils.c +++ b/fs/xfs/xfs_utils.c @@ -24,12 +24,10 @@  #include "xfs_trans.h"  #include "xfs_sb.h"  #include "xfs_ag.h" -#include "xfs_dir.h"  #include "xfs_dir2.h"  #include "xfs_dmapi.h"  #include "xfs_mount.h"  #include "xfs_bmap_btree.h" -#include "xfs_dir_sf.h"  #include "xfs_dir2_sf.h"  #include "xfs_attr_sf.h"  #include "xfs_dinode.h" @@ -82,8 +80,7 @@ xfs_dir_lookup_int(  	dp = XFS_BHVTOI(dir_bdp); -	error = XFS_DIR_LOOKUP(dp->i_mount, NULL, dp, -				VNAME(dentry), VNAMELEN(dentry), inum); +	error = xfs_dir_lookup(NULL, dp, VNAME(dentry), VNAMELEN(dentry), inum);  	if (!error) {  		/*  		 * Unlock the directory. We do this because we can't diff --git a/fs/xfs/xfs_vfsops.c b/fs/xfs/xfs_vfsops.c index 918531b6478..6c96391f3f1 100644 --- a/fs/xfs/xfs_vfsops.c +++ b/fs/xfs/xfs_vfsops.c @@ -24,7 +24,6 @@  #include "xfs_trans.h"  #include "xfs_sb.h"  #include "xfs_ag.h" -#include "xfs_dir.h"  #include "xfs_dir2.h"  #include "xfs_dmapi.h"  #include "xfs_mount.h" @@ -32,7 +31,6 @@  #include "xfs_bmap_btree.h"  #include "xfs_ialloc_btree.h"  #include "xfs_alloc_btree.h" -#include "xfs_dir_sf.h"  #include "xfs_dir2_sf.h"  #include "xfs_attr_sf.h"  #include "xfs_dinode.h" @@ -131,9 +129,6 @@ xfs_init(void)  #ifdef XFS_BMBT_TRACE  	xfs_bmbt_trace_buf = ktrace_alloc(XFS_BMBT_TRACE_SIZE, KM_SLEEP);  #endif -#ifdef XFS_DIR_TRACE -	xfs_dir_trace_buf = ktrace_alloc(XFS_DIR_TRACE_SIZE, KM_SLEEP); -#endif  #ifdef XFS_ATTR_TRACE  	xfs_attr_trace_buf = ktrace_alloc(XFS_ATTR_TRACE_SIZE, KM_SLEEP);  #endif @@ -177,9 +172,6 @@ xfs_cleanup(void)  #ifdef XFS_ATTR_TRACE  	ktrace_free(xfs_attr_trace_buf);  #endif -#ifdef XFS_DIR_TRACE -	ktrace_free(xfs_dir_trace_buf); -#endif  #ifdef XFS_BMBT_TRACE  	ktrace_free(xfs_bmbt_trace_buf);  #endif diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c index 26d96d1b25c..00a6b7dc24a 100644 --- a/fs/xfs/xfs_vnodeops.c +++ b/fs/xfs/xfs_vnodeops.c @@ -25,7 +25,6 @@  #include "xfs_trans.h"  #include "xfs_sb.h"  #include "xfs_ag.h" -#include "xfs_dir.h"  #include "xfs_dir2.h"  #include "xfs_dmapi.h"  #include "xfs_mount.h" @@ -33,13 +32,11 @@  #include "xfs_bmap_btree.h"  #include "xfs_alloc_btree.h"  #include "xfs_ialloc_btree.h" -#include "xfs_dir_sf.h"  #include "xfs_dir2_sf.h"  #include "xfs_attr_sf.h"  #include "xfs_dinode.h"  #include "xfs_inode.h"  #include "xfs_inode_item.h" -#include "xfs_dir_leaf.h"  #include "xfs_itable.h"  #include "xfs_btree.h"  #include "xfs_ialloc.h" @@ -1958,8 +1955,7 @@ xfs_create(  	if (error)  		goto error_return; -	if (resblks == 0 && -	    (error = XFS_DIR_CANENTER(mp, tp, dp, name, namelen))) +	if (resblks == 0 && (error = xfs_dir_canenter(tp, dp, name, namelen)))  		goto error_return;  	rdev = (vap->va_mask & XFS_AT_RDEV) ? vap->va_rdev : 0;  	error = xfs_dir_ialloc(&tp, dp, vap->va_mode, 1, @@ -1990,9 +1986,9 @@ xfs_create(  	xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL);  	dp_joined_to_trans = B_TRUE; -	error = XFS_DIR_CREATENAME(mp, tp, dp, name, namelen, ip->i_ino, -		&first_block, &free_list, -		resblks ? resblks - XFS_IALLOC_SPACE_RES(mp) : 0); +	error = xfs_dir_createname(tp, dp, name, namelen, ip->i_ino, +					&first_block, &free_list, resblks ? +					resblks - XFS_IALLOC_SPACE_RES(mp) : 0);  	if (error) {  		ASSERT(error != ENOSPC);  		goto abort_return; @@ -2468,8 +2464,8 @@ xfs_remove(  	 * Entry must exist since we did a lookup in xfs_lock_dir_and_entry.  	 */  	XFS_BMAP_INIT(&free_list, &first_block); -	error = XFS_DIR_REMOVENAME(mp, tp, dp, name, namelen, ip->i_ino, -		&first_block, &free_list, 0); +	error = xfs_dir_removename(tp, dp, name, namelen, ip->i_ino, +					&first_block, &free_list, 0);  	if (error) {  		ASSERT(error != ENOENT);  		REMOVE_DEBUG_TRACE(__LINE__); @@ -2688,13 +2684,12 @@ xfs_link(  	}  	if (resblks == 0 && -	    (error = XFS_DIR_CANENTER(mp, tp, tdp, target_name, -			target_namelen))) +	    (error = xfs_dir_canenter(tp, tdp, target_name, target_namelen)))  		goto error_return;  	XFS_BMAP_INIT(&free_list, &first_block); -	error = XFS_DIR_CREATENAME(mp, tp, tdp, target_name, target_namelen, +	error = xfs_dir_createname(tp, tdp, target_name, target_namelen,  				   sip->i_ino, &first_block, &free_list,  				   resblks);  	if (error) @@ -2860,7 +2855,7 @@ xfs_mkdir(  		goto error_return;  	if (resblks == 0 && -	    (error = XFS_DIR_CANENTER(mp, tp, dp, dir_name, dir_namelen))) +	    (error = xfs_dir_canenter(tp, dp, dir_name, dir_namelen)))  		goto error_return;  	/*  	 * create the directory inode. @@ -2887,9 +2882,9 @@ xfs_mkdir(  	XFS_BMAP_INIT(&free_list, &first_block); -	error = XFS_DIR_CREATENAME(mp, tp, dp, dir_name, dir_namelen, -			cdp->i_ino, &first_block, &free_list, -			resblks ? resblks - XFS_IALLOC_SPACE_RES(mp) : 0); +	error = xfs_dir_createname(tp, dp, dir_name, dir_namelen, cdp->i_ino, +				   &first_block, &free_list, resblks ? +				   resblks - XFS_IALLOC_SPACE_RES(mp) : 0);  	if (error) {  		ASSERT(error != ENOSPC);  		goto error1; @@ -2903,16 +2898,14 @@ xfs_mkdir(  	 */  	dp->i_gen++; -	error = XFS_DIR_INIT(mp, tp, cdp, dp); -	if (error) { +	error = xfs_dir_init(tp, cdp, dp); +	if (error)  		goto error2; -	}  	cdp->i_gen = 1;  	error = xfs_bumplink(tp, dp); -	if (error) { +	if (error)  		goto error2; -	}  	cvp = XFS_ITOV(cdp); @@ -3121,16 +3114,15 @@ xfs_rmdir(  		error = XFS_ERROR(ENOTEMPTY);  		goto error_return;  	} -	if (!XFS_DIR_ISEMPTY(mp, cdp)) { +	if (!xfs_dir_isempty(cdp)) {  		error = XFS_ERROR(ENOTEMPTY);  		goto error_return;  	} -	error = XFS_DIR_REMOVENAME(mp, tp, dp, name, namelen, cdp->i_ino, -		&first_block, &free_list, resblks); -	if (error) { +	error = xfs_dir_removename(tp, dp, name, namelen, cdp->i_ino, +					&first_block, &free_list, resblks); +	if (error)  		goto error1; -	}  	xfs_ichgtime(dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); @@ -3229,8 +3221,6 @@ xfs_rmdir(  /* - * xfs_readdir - *   * Read dp's entries starting at uiop->uio_offset and translate them into   * bufsize bytes worth of struct dirents starting at bufbase.   */ @@ -3250,21 +3240,16 @@ xfs_readdir(  					       (inst_t *)__return_address);  	dp = XFS_BHVTOI(dir_bdp); -	if (XFS_FORCED_SHUTDOWN(dp->i_mount)) { +	if (XFS_FORCED_SHUTDOWN(dp->i_mount))  		return XFS_ERROR(EIO); -	}  	lock_mode = xfs_ilock_map_shared(dp); -	error = XFS_DIR_GETDENTS(dp->i_mount, tp, dp, uiop, eofp); +	error = xfs_dir_getdents(tp, dp, uiop, eofp);  	xfs_iunlock_map_shared(dp, lock_mode);  	return error;  } -/* - * xfs_symlink - * - */  STATIC int  xfs_symlink(  	bhv_desc_t		*dir_bdp, @@ -3328,7 +3313,7 @@ xfs_symlink(  		int len, total;  		char *path; -		for(total = 0, path = target_path; total < pathlen;) { +		for (total = 0, path = target_path; total < pathlen;) {  			/*  			 * Skip any slashes.  			 */ @@ -3422,7 +3407,7 @@ xfs_symlink(  	 * Check for ability to enter directory entry, if no space reserved.  	 */  	if (resblks == 0 && -	    (error = XFS_DIR_CANENTER(mp, tp, dp, link_name, link_namelen))) +	    (error = xfs_dir_canenter(tp, dp, link_name, link_namelen)))  		goto error_return;  	/*  	 * Initialize the bmap freelist prior to calling either @@ -3509,11 +3494,10 @@ xfs_symlink(  	/*  	 * Create the directory entry for the symlink.  	 */ -	error = XFS_DIR_CREATENAME(mp, tp, dp, link_name, link_namelen, -			ip->i_ino, &first_block, &free_list, resblks); -	if (error) { +	error = xfs_dir_createname(tp, dp, link_name, link_namelen, ip->i_ino, +				   &first_block, &free_list, resblks); +	if (error)  		goto error1; -	}  	xfs_ichgtime(dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);  	xfs_trans_log_inode(tp, dp, XFS_ILOG_CORE);  |