diff options
Diffstat (limited to 'fs/xfs/xfs_dir2_readdir.c')
| -rw-r--r-- | fs/xfs/xfs_dir2_readdir.c | 199 | 
1 files changed, 102 insertions, 97 deletions
diff --git a/fs/xfs/xfs_dir2_readdir.c b/fs/xfs/xfs_dir2_readdir.c index 8993ec17452..48e99afb9cb 100644 --- a/fs/xfs/xfs_dir2_readdir.c +++ b/fs/xfs/xfs_dir2_readdir.c @@ -18,23 +18,23 @@   */  #include "xfs.h"  #include "xfs_fs.h" -#include "xfs_types.h" +#include "xfs_format.h" +#include "xfs_log_format.h" +#include "xfs_trans_resv.h"  #include "xfs_bit.h" -#include "xfs_log.h" -#include "xfs_trans.h"  #include "xfs_sb.h"  #include "xfs_ag.h"  #include "xfs_mount.h" +#include "xfs_da_format.h"  #include "xfs_da_btree.h" -#include "xfs_bmap_btree.h" -#include "xfs_dinode.h"  #include "xfs_inode.h" -#include "xfs_dir2_format.h"  #include "xfs_dir2.h"  #include "xfs_dir2_priv.h"  #include "xfs_error.h"  #include "xfs_trace.h"  #include "xfs_bmap.h" +#include "xfs_trans.h" +#include "xfs_dinode.h"  /*   * Directory file type support functions @@ -76,26 +76,25 @@ const unsigned char xfs_mode_to_ftype[S_IFMT >> S_SHIFT] = {  STATIC int  xfs_dir2_sf_getdents( -	xfs_inode_t		*dp,		/* incore directory inode */ +	struct xfs_da_args	*args,  	struct dir_context	*ctx)  {  	int			i;		/* shortform entry number */ -	xfs_mount_t		*mp;		/* filesystem mount point */ +	struct xfs_inode	*dp = args->dp;	/* incore directory inode */  	xfs_dir2_dataptr_t	off;		/* current entry's offset */  	xfs_dir2_sf_entry_t	*sfep;		/* shortform directory entry */  	xfs_dir2_sf_hdr_t	*sfp;		/* shortform structure */  	xfs_dir2_dataptr_t	dot_offset;  	xfs_dir2_dataptr_t	dotdot_offset;  	xfs_ino_t		ino; - -	mp = dp->i_mount; +	struct xfs_da_geometry	*geo = args->geo;  	ASSERT(dp->i_df.if_flags & XFS_IFINLINE);  	/*  	 * Give up if the directory is way too short.  	 */  	if (dp->i_d.di_size < offsetof(xfs_dir2_sf_hdr_t, parent)) { -		ASSERT(XFS_FORCED_SHUTDOWN(mp)); +		ASSERT(XFS_FORCED_SHUTDOWN(dp->i_mount));  		return XFS_ERROR(EIO);  	} @@ -109,19 +108,19 @@ xfs_dir2_sf_getdents(  	/*  	 * If the block number in the offset is out of range, we're done.  	 */ -	if (xfs_dir2_dataptr_to_db(mp, ctx->pos) > mp->m_dirdatablk) +	if (xfs_dir2_dataptr_to_db(geo, ctx->pos) > geo->datablk)  		return 0;  	/*  	 * Precalculate offsets for . and .. as we will always need them.  	 *  	 * XXX(hch): the second argument is sometimes 0 and sometimes -	 * mp->m_dirdatablk. +	 * geo->datablk  	 */ -	dot_offset = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk, -					     XFS_DIR3_DATA_DOT_OFFSET(mp)); -	dotdot_offset = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk, -						XFS_DIR3_DATA_DOTDOT_OFFSET(mp)); +	dot_offset = xfs_dir2_db_off_to_dataptr(geo, geo->datablk, +						dp->d_ops->data_dot_offset); +	dotdot_offset = xfs_dir2_db_off_to_dataptr(geo, geo->datablk, +						dp->d_ops->data_dotdot_offset);  	/*  	 * Put . entry unless we're starting past it. @@ -136,7 +135,7 @@ xfs_dir2_sf_getdents(  	 * Put .. entry unless we're starting past it.  	 */  	if (ctx->pos <= dotdot_offset) { -		ino = xfs_dir2_sf_get_parent_ino(sfp); +		ino = dp->d_ops->sf_get_parent_ino(sfp);  		ctx->pos = dotdot_offset & 0x7fffffff;  		if (!dir_emit(ctx, "..", 2, ino, DT_DIR))  			return 0; @@ -149,25 +148,25 @@ xfs_dir2_sf_getdents(  	for (i = 0; i < sfp->count; i++) {  		__uint8_t filetype; -		off = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk, +		off = xfs_dir2_db_off_to_dataptr(geo, geo->datablk,  				xfs_dir2_sf_get_offset(sfep));  		if (ctx->pos > off) { -			sfep = xfs_dir3_sf_nextentry(mp, sfp, sfep); +			sfep = dp->d_ops->sf_nextentry(sfp, sfep);  			continue;  		} -		ino = xfs_dir3_sfe_get_ino(mp, sfp, sfep); -		filetype = xfs_dir3_sfe_get_ftype(mp, sfp, sfep); +		ino = dp->d_ops->sf_get_ino(sfp, sfep); +		filetype = dp->d_ops->sf_get_ftype(sfep);  		ctx->pos = off & 0x7fffffff;  		if (!dir_emit(ctx, (char *)sfep->name, sfep->namelen, ino, -			    xfs_dir3_get_dtype(mp, filetype))) +			    xfs_dir3_get_dtype(dp->i_mount, filetype)))  			return 0; -		sfep = xfs_dir3_sf_nextentry(mp, sfp, sfep); +		sfep = dp->d_ops->sf_nextentry(sfp, sfep);  	} -	ctx->pos = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk + 1, 0) & -			0x7fffffff; +	ctx->pos = xfs_dir2_db_off_to_dataptr(geo, geo->datablk + 1, 0) & +								0x7fffffff;  	return 0;  } @@ -176,9 +175,10 @@ xfs_dir2_sf_getdents(   */  STATIC int  xfs_dir2_block_getdents( -	xfs_inode_t		*dp,		/* incore inode */ +	struct xfs_da_args	*args,  	struct dir_context	*ctx)  { +	struct xfs_inode	*dp = args->dp;	/* incore directory inode */  	xfs_dir2_data_hdr_t	*hdr;		/* block header */  	struct xfs_buf		*bp;		/* buffer for block */  	xfs_dir2_block_tail_t	*btp;		/* block tail */ @@ -186,16 +186,15 @@ xfs_dir2_block_getdents(  	xfs_dir2_data_unused_t	*dup;		/* block unused entry */  	char			*endptr;	/* end of the data entries */  	int			error;		/* error return value */ -	xfs_mount_t		*mp;		/* filesystem mount point */  	char			*ptr;		/* current data entry */  	int			wantoff;	/* starting block offset */  	xfs_off_t		cook; +	struct xfs_da_geometry	*geo = args->geo; -	mp = dp->i_mount;  	/*  	 * If the block number in the offset is out of range, we're done.  	 */ -	if (xfs_dir2_dataptr_to_db(mp, ctx->pos) > mp->m_dirdatablk) +	if (xfs_dir2_dataptr_to_db(geo, ctx->pos) > geo->datablk)  		return 0;  	error = xfs_dir3_block_read(NULL, dp, &bp); @@ -206,14 +205,14 @@ xfs_dir2_block_getdents(  	 * Extract the byte offset we start at from the seek pointer.  	 * We'll skip entries before this.  	 */ -	wantoff = xfs_dir2_dataptr_to_off(mp, ctx->pos); +	wantoff = xfs_dir2_dataptr_to_off(geo, ctx->pos);  	hdr = bp->b_addr;  	xfs_dir3_data_check(dp, bp);  	/*  	 * Set up values for the loop.  	 */ -	btp = xfs_dir2_block_tail_p(mp, hdr); -	ptr = (char *)xfs_dir3_data_entry_p(hdr); +	btp = xfs_dir2_block_tail_p(geo, hdr); +	ptr = (char *)dp->d_ops->data_entry_p(hdr);  	endptr = (char *)xfs_dir2_block_leaf_p(btp);  	/* @@ -237,24 +236,24 @@ xfs_dir2_block_getdents(  		/*  		 * Bump pointer for the next iteration.  		 */ -		ptr += xfs_dir3_data_entsize(mp, dep->namelen); +		ptr += dp->d_ops->data_entsize(dep->namelen);  		/*  		 * The entry is before the desired starting point, skip it.  		 */  		if ((char *)dep - (char *)hdr < wantoff)  			continue; -		cook = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk, +		cook = xfs_dir2_db_off_to_dataptr(geo, geo->datablk,  					    (char *)dep - (char *)hdr);  		ctx->pos = cook & 0x7fffffff; -		filetype = xfs_dir3_dirent_get_ftype(mp, dep); +		filetype = dp->d_ops->data_get_ftype(dep);  		/*  		 * If it didn't fit, set the final offset to here & return.  		 */  		if (!dir_emit(ctx, (char *)dep->name, dep->namelen,  			    be64_to_cpu(dep->inumber), -			    xfs_dir3_get_dtype(mp, filetype))) { +			    xfs_dir3_get_dtype(dp->i_mount, filetype))) {  			xfs_trans_brelse(NULL, bp);  			return 0;  		} @@ -264,8 +263,8 @@ xfs_dir2_block_getdents(  	 * Reached the end of the block.  	 * Set the offset to a non-existent block 1 and return.  	 */ -	ctx->pos = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk + 1, 0) & -			0x7fffffff; +	ctx->pos = xfs_dir2_db_off_to_dataptr(geo, geo->datablk + 1, 0) & +								0x7fffffff;  	xfs_trans_brelse(NULL, bp);  	return 0;  } @@ -286,13 +285,13 @@ struct xfs_dir2_leaf_map_info {  STATIC int  xfs_dir2_leaf_readbuf( -	struct xfs_inode	*dp, +	struct xfs_da_args	*args,  	size_t			bufsize,  	struct xfs_dir2_leaf_map_info *mip,  	xfs_dir2_off_t		*curoff,  	struct xfs_buf		**bpp)  { -	struct xfs_mount	*mp = dp->i_mount; +	struct xfs_inode	*dp = args->dp;  	struct xfs_buf		*bp = *bpp;  	struct xfs_bmbt_irec	*map = mip->map;  	struct blk_plug		plug; @@ -300,6 +299,7 @@ xfs_dir2_leaf_readbuf(  	int			length;  	int			i;  	int			j; +	struct xfs_da_geometry	*geo = args->geo;  	/*  	 * If we have a buffer, we need to release it and @@ -309,12 +309,12 @@ xfs_dir2_leaf_readbuf(  	if (bp) {  		xfs_trans_brelse(NULL, bp);  		bp = NULL; -		mip->map_blocks -= mp->m_dirblkfsbs; +		mip->map_blocks -= geo->fsbcount;  		/*  		 * Loop to get rid of the extents for the  		 * directory block.  		 */ -		for (i = mp->m_dirblkfsbs; i > 0; ) { +		for (i = geo->fsbcount; i > 0; ) {  			j = min_t(int, map->br_blockcount, i);  			map->br_blockcount -= j;  			map->br_startblock += j; @@ -333,8 +333,7 @@ xfs_dir2_leaf_readbuf(  	/*  	 * Recalculate the readahead blocks wanted.  	 */ -	mip->ra_want = howmany(bufsize + mp->m_dirblksize, -			       mp->m_sb.sb_blocksize) - 1; +	mip->ra_want = howmany(bufsize + geo->blksize, (1 << geo->fsblog)) - 1;  	ASSERT(mip->ra_want >= 0);  	/* @@ -342,14 +341,14 @@ xfs_dir2_leaf_readbuf(  	 * run out of data blocks, get some more mappings.  	 */  	if (1 + mip->ra_want > mip->map_blocks && -	    mip->map_off < xfs_dir2_byte_to_da(mp, XFS_DIR2_LEAF_OFFSET)) { +	    mip->map_off < xfs_dir2_byte_to_da(geo, XFS_DIR2_LEAF_OFFSET)) {  		/*  		 * Get more bmaps, fill in after the ones  		 * we already have in the table.  		 */  		mip->nmap = mip->map_size - mip->map_valid;  		error = xfs_bmapi_read(dp, mip->map_off, -				xfs_dir2_byte_to_da(mp, XFS_DIR2_LEAF_OFFSET) - +				xfs_dir2_byte_to_da(geo, XFS_DIR2_LEAF_OFFSET) -  								mip->map_off,  				&map[mip->map_valid], &mip->nmap, 0); @@ -370,7 +369,7 @@ xfs_dir2_leaf_readbuf(  			i = mip->map_valid + mip->nmap - 1;  			mip->map_off = map[i].br_startoff + map[i].br_blockcount;  		} else -			mip->map_off = xfs_dir2_byte_to_da(mp, +			mip->map_off = xfs_dir2_byte_to_da(geo,  							XFS_DIR2_LEAF_OFFSET);  		/* @@ -396,18 +395,18 @@ xfs_dir2_leaf_readbuf(  	 * No valid mappings, so no more data blocks.  	 */  	if (!mip->map_valid) { -		*curoff = xfs_dir2_da_to_byte(mp, mip->map_off); +		*curoff = xfs_dir2_da_to_byte(geo, mip->map_off);  		goto out;  	}  	/*  	 * Read the directory block starting at the first mapping.  	 */ -	mip->curdb = xfs_dir2_da_to_db(mp, map->br_startoff); +	mip->curdb = xfs_dir2_da_to_db(geo, map->br_startoff);  	error = xfs_dir3_data_read(NULL, dp, map->br_startoff, -			map->br_blockcount >= mp->m_dirblkfsbs ? -			    XFS_FSB_TO_DADDR(mp, map->br_startblock) : -1, &bp); - +			map->br_blockcount >= geo->fsbcount ? +			    XFS_FSB_TO_DADDR(dp->i_mount, map->br_startblock) : +			    -1, &bp);  	/*  	 * Should just skip over the data block instead of giving up.  	 */ @@ -419,7 +418,7 @@ xfs_dir2_leaf_readbuf(  	 * was previously ra.  	 */  	if (mip->ra_current) -		mip->ra_current -= mp->m_dirblkfsbs; +		mip->ra_current -= geo->fsbcount;  	/*  	 * Do we need more readahead? @@ -427,16 +426,16 @@ xfs_dir2_leaf_readbuf(  	blk_start_plug(&plug);  	for (mip->ra_index = mip->ra_offset = i = 0;  	     mip->ra_want > mip->ra_current && i < mip->map_blocks; -	     i += mp->m_dirblkfsbs) { +	     i += geo->fsbcount) {  		ASSERT(mip->ra_index < mip->map_valid);  		/*  		 * Read-ahead a contiguous directory block.  		 */  		if (i > mip->ra_current && -		    map[mip->ra_index].br_blockcount >= mp->m_dirblkfsbs) { -			xfs_dir3_data_readahead(NULL, dp, +		    map[mip->ra_index].br_blockcount >= geo->fsbcount) { +			xfs_dir3_data_readahead(dp,  				map[mip->ra_index].br_startoff + mip->ra_offset, -				XFS_FSB_TO_DADDR(mp, +				XFS_FSB_TO_DADDR(dp->i_mount,  					map[mip->ra_index].br_startblock +  							mip->ra_offset));  			mip->ra_current = i; @@ -447,7 +446,7 @@ xfs_dir2_leaf_readbuf(  		 * use our mapping, but this is a very rare case.  		 */  		else if (i > mip->ra_current) { -			xfs_dir3_data_readahead(NULL, dp, +			xfs_dir3_data_readahead(dp,  					map[mip->ra_index].br_startoff +  							mip->ra_offset, -1);  			mip->ra_current = i; @@ -456,15 +455,14 @@ xfs_dir2_leaf_readbuf(  		/*  		 * Advance offset through the mapping table.  		 */ -		for (j = 0; j < mp->m_dirblkfsbs; j++) { +		for (j = 0; j < geo->fsbcount; j += length ) {  			/*  			 * The rest of this extent but not more than a dir  			 * block.  			 */ -			length = min_t(int, mp->m_dirblkfsbs, +			length = min_t(int, geo->fsbcount,  					map[mip->ra_index].br_blockcount -  							mip->ra_offset); -			j += length;  			mip->ra_offset += length;  			/* @@ -489,22 +487,23 @@ out:   */  STATIC int  xfs_dir2_leaf_getdents( -	xfs_inode_t		*dp,		/* incore directory inode */ +	struct xfs_da_args	*args,  	struct dir_context	*ctx,  	size_t			bufsize)  { +	struct xfs_inode	*dp = args->dp;  	struct xfs_buf		*bp = NULL;	/* data block buffer */  	xfs_dir2_data_hdr_t	*hdr;		/* data block header */  	xfs_dir2_data_entry_t	*dep;		/* data entry */  	xfs_dir2_data_unused_t	*dup;		/* unused entry */  	int			error = 0;	/* error return value */  	int			length;		/* temporary length value */ -	xfs_mount_t		*mp;		/* filesystem mount point */  	int			byteoff;	/* offset in current block */  	xfs_dir2_off_t		curoff;		/* current overall offset */  	xfs_dir2_off_t		newoff;		/* new curoff after new blk */  	char			*ptr = NULL;	/* pointer to current data */  	struct xfs_dir2_leaf_map_info *map_info; +	struct xfs_da_geometry	*geo = args->geo;  	/*  	 * If the offset is at or past the largest allowed value, @@ -513,15 +512,12 @@ xfs_dir2_leaf_getdents(  	if (ctx->pos >= XFS_DIR2_MAX_DATAPTR)  		return 0; -	mp = dp->i_mount; -  	/*  	 * Set up to bmap a number of blocks based on the caller's  	 * buffer size, the directory block size, and the filesystem  	 * block size.  	 */ -	length = howmany(bufsize + mp->m_dirblksize, -				     mp->m_sb.sb_blocksize); +	length = howmany(bufsize + geo->blksize, (1 << geo->fsblog));  	map_info = kmem_zalloc(offsetof(struct xfs_dir2_leaf_map_info, map) +  				(length * sizeof(struct xfs_bmbt_irec)),  			       KM_SLEEP | KM_NOFS); @@ -531,14 +527,14 @@ xfs_dir2_leaf_getdents(  	 * Inside the loop we keep the main offset value as a byte offset  	 * in the directory file.  	 */ -	curoff = xfs_dir2_dataptr_to_byte(mp, ctx->pos); +	curoff = xfs_dir2_dataptr_to_byte(ctx->pos);  	/*  	 * Force this conversion through db so we truncate the offset  	 * down to get the start of the data block.  	 */ -	map_info->map_off = xfs_dir2_db_to_da(mp, -					      xfs_dir2_byte_to_db(mp, curoff)); +	map_info->map_off = xfs_dir2_db_to_da(geo, +					      xfs_dir2_byte_to_db(geo, curoff));  	/*  	 * Loop over directory entries until we reach the end offset. @@ -551,9 +547,9 @@ xfs_dir2_leaf_getdents(  		 * If we have no buffer, or we're off the end of the  		 * current buffer, need to get another one.  		 */ -		if (!bp || ptr >= (char *)bp->b_addr + mp->m_dirblksize) { +		if (!bp || ptr >= (char *)bp->b_addr + geo->blksize) { -			error = xfs_dir2_leaf_readbuf(dp, bufsize, map_info, +			error = xfs_dir2_leaf_readbuf(args, bufsize, map_info,  						      &curoff, &bp);  			if (error || !map_info->map_valid)  				break; @@ -561,7 +557,8 @@ xfs_dir2_leaf_getdents(  			/*  			 * Having done a read, we need to set a new offset.  			 */ -			newoff = xfs_dir2_db_off_to_byte(mp, map_info->curdb, 0); +			newoff = xfs_dir2_db_off_to_byte(geo, +							 map_info->curdb, 0);  			/*  			 * Start of the current block.  			 */ @@ -571,20 +568,20 @@ xfs_dir2_leaf_getdents(  			 * Make sure we're in the right block.  			 */  			else if (curoff > newoff) -				ASSERT(xfs_dir2_byte_to_db(mp, curoff) == +				ASSERT(xfs_dir2_byte_to_db(geo, curoff) ==  				       map_info->curdb);  			hdr = bp->b_addr;  			xfs_dir3_data_check(dp, bp);  			/*  			 * Find our position in the block.  			 */ -			ptr = (char *)xfs_dir3_data_entry_p(hdr); -			byteoff = xfs_dir2_byte_to_off(mp, curoff); +			ptr = (char *)dp->d_ops->data_entry_p(hdr); +			byteoff = xfs_dir2_byte_to_off(geo, curoff);  			/*  			 * Skip past the header.  			 */  			if (byteoff == 0) -				curoff += xfs_dir3_data_entry_offset(hdr); +				curoff += dp->d_ops->data_entry_offset;  			/*  			 * Skip past entries until we reach our offset.  			 */ @@ -601,17 +598,17 @@ xfs_dir2_leaf_getdents(  					}  					dep = (xfs_dir2_data_entry_t *)ptr;  					length = -					   xfs_dir3_data_entsize(mp, dep->namelen); +					   dp->d_ops->data_entsize(dep->namelen);  					ptr += length;  				}  				/*  				 * Now set our real offset.  				 */  				curoff = -					xfs_dir2_db_off_to_byte(mp, -					    xfs_dir2_byte_to_db(mp, curoff), +					xfs_dir2_db_off_to_byte(geo, +					    xfs_dir2_byte_to_db(geo, curoff),  					    (char *)ptr - (char *)hdr); -				if (ptr >= (char *)hdr + mp->m_dirblksize) { +				if (ptr >= (char *)hdr + geo->blksize) {  					continue;  				}  			} @@ -632,13 +629,13 @@ xfs_dir2_leaf_getdents(  		}  		dep = (xfs_dir2_data_entry_t *)ptr; -		length = xfs_dir3_data_entsize(mp, dep->namelen); -		filetype = xfs_dir3_dirent_get_ftype(mp, dep); +		length = dp->d_ops->data_entsize(dep->namelen); +		filetype = dp->d_ops->data_get_ftype(dep); -		ctx->pos = xfs_dir2_byte_to_dataptr(mp, curoff) & 0x7fffffff; +		ctx->pos = xfs_dir2_byte_to_dataptr(curoff) & 0x7fffffff;  		if (!dir_emit(ctx, (char *)dep->name, dep->namelen,  			    be64_to_cpu(dep->inumber), -			    xfs_dir3_get_dtype(mp, filetype))) +			    xfs_dir3_get_dtype(dp->i_mount, filetype)))  			break;  		/* @@ -653,10 +650,10 @@ xfs_dir2_leaf_getdents(  	/*  	 * All done.  Set output offset value to current offset.  	 */ -	if (curoff > xfs_dir2_dataptr_to_byte(mp, XFS_DIR2_MAX_DATAPTR)) +	if (curoff > xfs_dir2_dataptr_to_byte(XFS_DIR2_MAX_DATAPTR))  		ctx->pos = XFS_DIR2_MAX_DATAPTR & 0x7fffffff;  	else -		ctx->pos = xfs_dir2_byte_to_dataptr(mp, curoff) & 0x7fffffff; +		ctx->pos = xfs_dir2_byte_to_dataptr(curoff) & 0x7fffffff;  	kmem_free(map_info);  	if (bp)  		xfs_trans_brelse(NULL, bp); @@ -668,12 +665,14 @@ xfs_dir2_leaf_getdents(   */  int  xfs_readdir( -	xfs_inode_t	*dp, -	struct dir_context *ctx, -	size_t		bufsize) +	struct xfs_inode	*dp, +	struct dir_context	*ctx, +	size_t			bufsize)  { -	int		rval;		/* return value */ -	int		v;		/* type-checking value */ +	struct xfs_da_args	args = { NULL }; +	int			rval; +	int			v; +	uint			lock_mode;  	trace_xfs_readdir(dp); @@ -683,13 +682,19 @@ xfs_readdir(  	ASSERT(S_ISDIR(dp->i_d.di_mode));  	XFS_STATS_INC(xs_dir_getdents); +	args.dp = dp; +	args.geo = dp->i_mount->m_dir_geo; + +	lock_mode = xfs_ilock_data_map_shared(dp);  	if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) -		rval = xfs_dir2_sf_getdents(dp, ctx); -	else if ((rval = xfs_dir2_isblock(NULL, dp, &v))) +		rval = xfs_dir2_sf_getdents(&args, ctx); +	else if ((rval = xfs_dir2_isblock(&args, &v)))  		;  	else if (v) -		rval = xfs_dir2_block_getdents(dp, ctx); +		rval = xfs_dir2_block_getdents(&args, ctx);  	else -		rval = xfs_dir2_leaf_getdents(dp, ctx, bufsize); +		rval = xfs_dir2_leaf_getdents(&args, ctx, bufsize); +	xfs_iunlock(dp, lock_mode); +  	return rval;  }  | 
