Re: [PATCH 10/46] xfs: add a entries pointer to struct xfs_dir3_icleaf_hdr

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, Nov 07, 2019 at 07:23:34PM +0100, Christoph Hellwig wrote:
> All callers of the ->node_tree_p dir operation already have a struct
> xfs_dir3_icleaf_hdr from a previous call to xfs_da_leaf_hdr_from_disk at
> hand, or just need slight changes to the calling conventions to do so.
> Add a pointer to the entries to struct xfs_dir3_icleaf_hdr to clean up
> this pattern.  To make this possible the xfs_dir3_leaf_log_ents function
> grow a new argument to pass the xfs_dir3_icleaf_hdr that call callers
> already have, and xfs_dir2_leaf_lookup_int returns the
> xfs_dir3_icleaf_hdr to the callers so that they can later use it.
> 
> Signed-off-by: Christoph Hellwig <hch@xxxxxx>

Looks ok,
Reviewed-by: Darrick J. Wong <darrick.wong@xxxxxxxxxx>

--D

> ---
>  fs/xfs/libxfs/xfs_da_btree.c   |   7 +--
>  fs/xfs/libxfs/xfs_da_format.c  |  15 -----
>  fs/xfs/libxfs/xfs_dir2.h       |   2 -
>  fs/xfs/libxfs/xfs_dir2_block.c |   7 +--
>  fs/xfs/libxfs/xfs_dir2_leaf.c  | 101 +++++++++++++++------------------
>  fs/xfs/libxfs/xfs_dir2_node.c  |  64 +++++++++------------
>  fs/xfs/libxfs/xfs_dir2_priv.h  |   9 ++-
>  fs/xfs/scrub/dir.c             |  14 ++---
>  8 files changed, 93 insertions(+), 126 deletions(-)
> 
> diff --git a/fs/xfs/libxfs/xfs_da_btree.c b/fs/xfs/libxfs/xfs_da_btree.c
> index 1742e8293574..46b1c3fb305c 100644
> --- a/fs/xfs/libxfs/xfs_da_btree.c
> +++ b/fs/xfs/libxfs/xfs_da_btree.c
> @@ -640,15 +640,14 @@ xfs_da3_root_split(
>  		xfs_trans_buf_set_type(tp, bp, XFS_BLFT_DA_NODE_BUF);
>  	} else {
>  		struct xfs_dir3_icleaf_hdr leafhdr;
> -		struct xfs_dir2_leaf_entry *ents;
>  
>  		leaf = (xfs_dir2_leaf_t *)oldroot;
>  		xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &leafhdr, leaf);
> -		ents = dp->d_ops->leaf_ents_p(leaf);
>  
>  		ASSERT(leafhdr.magic == XFS_DIR2_LEAFN_MAGIC ||
>  		       leafhdr.magic == XFS_DIR3_LEAFN_MAGIC);
> -		size = (int)((char *)&ents[leafhdr.count] - (char *)leaf);
> +		size = (int)((char *)&leafhdr.ents[leafhdr.count] -
> +			(char *)leaf);
>  		level = 0;
>  
>  		/*
> @@ -2297,7 +2296,7 @@ xfs_da3_swap_lastblock(
>  		dead_leaf2 = (xfs_dir2_leaf_t *)dead_info;
>  		xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &leafhdr,
>  					    dead_leaf2);
> -		ents = dp->d_ops->leaf_ents_p(dead_leaf2);
> +		ents = leafhdr.ents;
>  		dead_level = 0;
>  		dead_hash = be32_to_cpu(ents[leafhdr.count - 1].hashval);
>  	} else {
> diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c
> index 193708d12459..ed21ce01502f 100644
> --- a/fs/xfs/libxfs/xfs_da_format.c
> +++ b/fs/xfs/libxfs/xfs_da_format.c
> @@ -411,12 +411,6 @@ xfs_dir2_max_leaf_ents(struct xfs_da_geometry *geo)
>  		(uint)sizeof(struct xfs_dir2_leaf_entry);
>  }
>  
> -static struct xfs_dir2_leaf_entry *
> -xfs_dir2_leaf_ents_p(struct xfs_dir2_leaf *lp)
> -{
> -	return lp->__ents;
> -}
> -
>  static int
>  xfs_dir3_max_leaf_ents(struct xfs_da_geometry *geo)
>  {
> @@ -424,12 +418,6 @@ xfs_dir3_max_leaf_ents(struct xfs_da_geometry *geo)
>  		(uint)sizeof(struct xfs_dir2_leaf_entry);
>  }
>  
> -static struct xfs_dir2_leaf_entry *
> -xfs_dir3_leaf_ents_p(struct xfs_dir2_leaf *lp)
> -{
> -	return ((struct xfs_dir3_leaf *)lp)->__ents;
> -}
> -
>  /*
>   * Directory free space block operations
>   */
> @@ -584,7 +572,6 @@ static const struct xfs_dir_ops xfs_dir2_ops = {
>  
>  	.leaf_hdr_size = sizeof(struct xfs_dir2_leaf_hdr),
>  	.leaf_max_ents = xfs_dir2_max_leaf_ents,
> -	.leaf_ents_p = xfs_dir2_leaf_ents_p,
>  
>  	.free_hdr_size = sizeof(struct xfs_dir2_free_hdr),
>  	.free_hdr_to_disk = xfs_dir2_free_hdr_to_disk,
> @@ -627,7 +614,6 @@ static const struct xfs_dir_ops xfs_dir2_ftype_ops = {
>  
>  	.leaf_hdr_size = sizeof(struct xfs_dir2_leaf_hdr),
>  	.leaf_max_ents = xfs_dir2_max_leaf_ents,
> -	.leaf_ents_p = xfs_dir2_leaf_ents_p,
>  
>  	.free_hdr_size = sizeof(struct xfs_dir2_free_hdr),
>  	.free_hdr_to_disk = xfs_dir2_free_hdr_to_disk,
> @@ -670,7 +656,6 @@ static const struct xfs_dir_ops xfs_dir3_ops = {
>  
>  	.leaf_hdr_size = sizeof(struct xfs_dir3_leaf_hdr),
>  	.leaf_max_ents = xfs_dir3_max_leaf_ents,
> -	.leaf_ents_p = xfs_dir3_leaf_ents_p,
>  
>  	.free_hdr_size = sizeof(struct xfs_dir3_free_hdr),
>  	.free_hdr_to_disk = xfs_dir3_free_hdr_to_disk,
> diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h
> index 15a1a72dc126..b46657974134 100644
> --- a/fs/xfs/libxfs/xfs_dir2.h
> +++ b/fs/xfs/libxfs/xfs_dir2.h
> @@ -74,8 +74,6 @@ struct xfs_dir_ops {
>  
>  	int	leaf_hdr_size;
>  	int	(*leaf_max_ents)(struct xfs_da_geometry *geo);
> -	struct xfs_dir2_leaf_entry *
> -		(*leaf_ents_p)(struct xfs_dir2_leaf *lp);
>  
>  	int	free_hdr_size;
>  	void	(*free_hdr_to_disk)(struct xfs_dir2_free *to,
> diff --git a/fs/xfs/libxfs/xfs_dir2_block.c b/fs/xfs/libxfs/xfs_dir2_block.c
> index d9ad89f6fd79..065fe10a842b 100644
> --- a/fs/xfs/libxfs/xfs_dir2_block.c
> +++ b/fs/xfs/libxfs/xfs_dir2_block.c
> @@ -914,7 +914,6 @@ xfs_dir2_leaf_to_block(
>  	__be16			*tagp;		/* end of entry (tag) */
>  	int			to;		/* block/leaf to index */
>  	xfs_trans_t		*tp;		/* transaction pointer */
> -	struct xfs_dir2_leaf_entry *ents;
>  	struct xfs_dir3_icleaf_hdr leafhdr;
>  
>  	trace_xfs_dir2_leaf_to_block(args);
> @@ -924,7 +923,6 @@ xfs_dir2_leaf_to_block(
>  	mp = dp->i_mount;
>  	leaf = lbp->b_addr;
>  	xfs_dir2_leaf_hdr_from_disk(mp, &leafhdr, leaf);
> -	ents = dp->d_ops->leaf_ents_p(leaf);
>  	ltp = xfs_dir2_leaf_tail_p(args->geo, leaf);
>  
>  	ASSERT(leafhdr.magic == XFS_DIR2_LEAF1_MAGIC ||
> @@ -1004,9 +1002,10 @@ xfs_dir2_leaf_to_block(
>  	 */
>  	lep = xfs_dir2_block_leaf_p(btp);
>  	for (from = to = 0; from < leafhdr.count; from++) {
> -		if (ents[from].address == cpu_to_be32(XFS_DIR2_NULL_DATAPTR))
> +		if (leafhdr.ents[from].address ==
> +		    cpu_to_be32(XFS_DIR2_NULL_DATAPTR))
>  			continue;
> -		lep[to++] = ents[from];
> +		lep[to++] = leafhdr.ents[from];
>  	}
>  	ASSERT(to == be32_to_cpu(btp->count));
>  	xfs_dir2_block_log_leaf(tp, dbp, 0, be32_to_cpu(btp->count) - 1);
> diff --git a/fs/xfs/libxfs/xfs_dir2_leaf.c b/fs/xfs/libxfs/xfs_dir2_leaf.c
> index 07734c0fe8a7..5e3e96efdaca 100644
> --- a/fs/xfs/libxfs/xfs_dir2_leaf.c
> +++ b/fs/xfs/libxfs/xfs_dir2_leaf.c
> @@ -24,7 +24,8 @@
>   * Local function declarations.
>   */
>  static int xfs_dir2_leaf_lookup_int(xfs_da_args_t *args, struct xfs_buf **lbpp,
> -				    int *indexp, struct xfs_buf **dbpp);
> +				    int *indexp, struct xfs_buf **dbpp,
> +				    struct xfs_dir3_icleaf_hdr *leafhdr);
>  static void xfs_dir3_leaf_log_bests(struct xfs_da_args *args,
>  				    struct xfs_buf *bp, int first, int last);
>  static void xfs_dir3_leaf_log_tail(struct xfs_da_args *args,
> @@ -44,6 +45,7 @@ xfs_dir2_leaf_hdr_from_disk(
>  		to->magic = be16_to_cpu(from3->hdr.info.hdr.magic);
>  		to->count = be16_to_cpu(from3->hdr.count);
>  		to->stale = be16_to_cpu(from3->hdr.stale);
> +		to->ents = from3->__ents;
>  
>  		ASSERT(to->magic == XFS_DIR3_LEAF1_MAGIC ||
>  		       to->magic == XFS_DIR3_LEAFN_MAGIC);
> @@ -53,6 +55,7 @@ xfs_dir2_leaf_hdr_from_disk(
>  		to->magic = be16_to_cpu(from->hdr.info.magic);
>  		to->count = be16_to_cpu(from->hdr.count);
>  		to->stale = be16_to_cpu(from->hdr.stale);
> +		to->ents = from->__ents;
>  
>  		ASSERT(to->magic == XFS_DIR2_LEAF1_MAGIC ||
>  		       to->magic == XFS_DIR2_LEAFN_MAGIC);
> @@ -139,7 +142,6 @@ xfs_dir3_leaf_check_int(
>  	struct xfs_dir3_icleaf_hdr *hdr,
>  	struct xfs_dir2_leaf	*leaf)
>  {
> -	struct xfs_dir2_leaf_entry *ents;
>  	xfs_dir2_leaf_tail_t	*ltp;
>  	int			stale;
>  	int			i;
> @@ -158,7 +160,6 @@ xfs_dir3_leaf_check_int(
>  		hdr = &leafhdr;
>  	}
>  
> -	ents = ops->leaf_ents_p(leaf);
>  	ltp = xfs_dir2_leaf_tail_p(geo, leaf);
>  
>  	/*
> @@ -172,17 +173,17 @@ xfs_dir3_leaf_check_int(
>  	/* Leaves and bests don't overlap in leaf format. */
>  	if ((hdr->magic == XFS_DIR2_LEAF1_MAGIC ||
>  	     hdr->magic == XFS_DIR3_LEAF1_MAGIC) &&
> -	    (char *)&ents[hdr->count] > (char *)xfs_dir2_leaf_bests_p(ltp))
> +	    (char *)&hdr->ents[hdr->count] > (char *)xfs_dir2_leaf_bests_p(ltp))
>  		return __this_address;
>  
>  	/* Check hash value order, count stale entries.  */
>  	for (i = stale = 0; i < hdr->count; i++) {
>  		if (i + 1 < hdr->count) {
> -			if (be32_to_cpu(ents[i].hashval) >
> -					be32_to_cpu(ents[i + 1].hashval))
> +			if (be32_to_cpu(hdr->ents[i].hashval) >
> +					be32_to_cpu(hdr->ents[i + 1].hashval))
>  				return __this_address;
>  		}
> -		if (ents[i].address == cpu_to_be32(XFS_DIR2_NULL_DATAPTR))
> +		if (hdr->ents[i].address == cpu_to_be32(XFS_DIR2_NULL_DATAPTR))
>  			stale++;
>  	}
>  	if (hdr->stale != stale)
> @@ -404,7 +405,6 @@ xfs_dir2_block_to_leaf(
>  	int			needscan;	/* need to rescan bestfree */
>  	xfs_trans_t		*tp;		/* transaction pointer */
>  	struct xfs_dir2_data_free *bf;
> -	struct xfs_dir2_leaf_entry *ents;
>  	struct xfs_dir3_icleaf_hdr leafhdr;
>  
>  	trace_xfs_dir2_block_to_leaf(args);
> @@ -434,7 +434,6 @@ xfs_dir2_block_to_leaf(
>  	btp = xfs_dir2_block_tail_p(args->geo, hdr);
>  	blp = xfs_dir2_block_leaf_p(btp);
>  	bf = dp->d_ops->data_bestfree_p(hdr);
> -	ents = dp->d_ops->leaf_ents_p(leaf);
>  
>  	/*
>  	 * Set the counts in the leaf header.
> @@ -449,8 +448,9 @@ xfs_dir2_block_to_leaf(
>  	 * Could compact these but I think we always do the conversion
>  	 * after squeezing out stale entries.
>  	 */
> -	memcpy(ents, blp, be32_to_cpu(btp->count) * sizeof(xfs_dir2_leaf_entry_t));
> -	xfs_dir3_leaf_log_ents(args, lbp, 0, leafhdr.count - 1);
> +	memcpy(leafhdr.ents, blp,
> +		be32_to_cpu(btp->count) * sizeof(struct xfs_dir2_leaf_entry));
> +	xfs_dir3_leaf_log_ents(args, &leafhdr, lbp, 0, leafhdr.count - 1);
>  	needscan = 0;
>  	needlog = 1;
>  	/*
> @@ -665,8 +665,8 @@ xfs_dir2_leaf_addname(
>  	index = xfs_dir2_leaf_search_hash(args, lbp);
>  	leaf = lbp->b_addr;
>  	ltp = xfs_dir2_leaf_tail_p(args->geo, leaf);
> -	ents = dp->d_ops->leaf_ents_p(leaf);
>  	xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &leafhdr, leaf);
> +	ents = leafhdr.ents;
>  	bestsp = xfs_dir2_leaf_bests_p(ltp);
>  	length = dp->d_ops->data_entsize(args->namelen);
>  
> @@ -912,7 +912,7 @@ xfs_dir2_leaf_addname(
>  	 */
>  	xfs_dir2_leaf_hdr_to_disk(dp->i_mount, leaf, &leafhdr);
>  	xfs_dir3_leaf_log_header(args, lbp);
> -	xfs_dir3_leaf_log_ents(args, lbp, lfloglow, lfloghigh);
> +	xfs_dir3_leaf_log_ents(args, &leafhdr, lbp, lfloglow, lfloghigh);
>  	xfs_dir3_leaf_check(dp, lbp);
>  	xfs_dir3_data_check(dp, dbp);
>  	return 0;
> @@ -932,7 +932,6 @@ xfs_dir3_leaf_compact(
>  	xfs_dir2_leaf_t	*leaf;		/* leaf structure */
>  	int		loglow;		/* first leaf entry to log */
>  	int		to;		/* target leaf index */
> -	struct xfs_dir2_leaf_entry *ents;
>  	struct xfs_inode *dp = args->dp;
>  
>  	leaf = bp->b_addr;
> @@ -942,9 +941,9 @@ xfs_dir3_leaf_compact(
>  	/*
>  	 * Compress out the stale entries in place.
>  	 */
> -	ents = dp->d_ops->leaf_ents_p(leaf);
>  	for (from = to = 0, loglow = -1; from < leafhdr->count; from++) {
> -		if (ents[from].address == cpu_to_be32(XFS_DIR2_NULL_DATAPTR))
> +		if (leafhdr->ents[from].address ==
> +		    cpu_to_be32(XFS_DIR2_NULL_DATAPTR))
>  			continue;
>  		/*
>  		 * Only actually copy the entries that are different.
> @@ -952,7 +951,7 @@ xfs_dir3_leaf_compact(
>  		if (from > to) {
>  			if (loglow == -1)
>  				loglow = to;
> -			ents[to] = ents[from];
> +			leafhdr->ents[to] = leafhdr->ents[from];
>  		}
>  		to++;
>  	}
> @@ -966,7 +965,7 @@ xfs_dir3_leaf_compact(
>  	xfs_dir2_leaf_hdr_to_disk(dp->i_mount, leaf, leafhdr);
>  	xfs_dir3_leaf_log_header(args, bp);
>  	if (loglow != -1)
> -		xfs_dir3_leaf_log_ents(args, bp, loglow, to - 1);
> +		xfs_dir3_leaf_log_ents(args, leafhdr, bp, loglow, to - 1);
>  }
>  
>  /*
> @@ -1095,6 +1094,7 @@ xfs_dir3_leaf_log_bests(
>  void
>  xfs_dir3_leaf_log_ents(
>  	struct xfs_da_args	*args,
> +	struct xfs_dir3_icleaf_hdr *hdr,
>  	struct xfs_buf		*bp,
>  	int			first,
>  	int			last)
> @@ -1102,16 +1102,14 @@ xfs_dir3_leaf_log_ents(
>  	xfs_dir2_leaf_entry_t	*firstlep;	/* pointer to first entry */
>  	xfs_dir2_leaf_entry_t	*lastlep;	/* pointer to last entry */
>  	struct xfs_dir2_leaf	*leaf = bp->b_addr;
> -	struct xfs_dir2_leaf_entry *ents;
>  
>  	ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAF1_MAGIC) ||
>  	       leaf->hdr.info.magic == cpu_to_be16(XFS_DIR3_LEAF1_MAGIC) ||
>  	       leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC) ||
>  	       leaf->hdr.info.magic == cpu_to_be16(XFS_DIR3_LEAFN_MAGIC));
>  
> -	ents = args->dp->d_ops->leaf_ents_p(leaf);
> -	firstlep = &ents[first];
> -	lastlep = &ents[last];
> +	firstlep = &hdr->ents[first];
> +	lastlep = &hdr->ents[last];
>  	xfs_trans_log_buf(args->trans, bp,
>  		(uint)((char *)firstlep - (char *)leaf),
>  		(uint)((char *)lastlep - (char *)leaf + sizeof(*lastlep) - 1));
> @@ -1173,28 +1171,27 @@ xfs_dir2_leaf_lookup(
>  	int			error;		/* error return code */
>  	int			index;		/* found entry index */
>  	struct xfs_buf		*lbp;		/* leaf buffer */
> -	xfs_dir2_leaf_t		*leaf;		/* leaf structure */
>  	xfs_dir2_leaf_entry_t	*lep;		/* leaf entry */
>  	xfs_trans_t		*tp;		/* transaction pointer */
> -	struct xfs_dir2_leaf_entry *ents;
> +	struct xfs_dir3_icleaf_hdr leafhdr;
>  
>  	trace_xfs_dir2_leaf_lookup(args);
>  
>  	/*
>  	 * Look up name in the leaf block, returning both buffers and index.
>  	 */
> -	if ((error = xfs_dir2_leaf_lookup_int(args, &lbp, &index, &dbp))) {
> +	error = xfs_dir2_leaf_lookup_int(args, &lbp, &index, &dbp, &leafhdr);
> +	if (error)
>  		return error;
> -	}
> +
>  	tp = args->trans;
>  	dp = args->dp;
>  	xfs_dir3_leaf_check(dp, lbp);
> -	leaf = lbp->b_addr;
> -	ents = dp->d_ops->leaf_ents_p(leaf);
> +
>  	/*
>  	 * Get to the leaf entry and contained data entry address.
>  	 */
> -	lep = &ents[index];
> +	lep = &leafhdr.ents[index];
>  
>  	/*
>  	 * Point to the data entry.
> @@ -1224,7 +1221,8 @@ xfs_dir2_leaf_lookup_int(
>  	xfs_da_args_t		*args,		/* operation arguments */
>  	struct xfs_buf		**lbpp,		/* out: leaf buffer */
>  	int			*indexp,	/* out: index in leaf block */
> -	struct xfs_buf		**dbpp)		/* out: data buffer */
> +	struct xfs_buf		**dbpp,		/* out: data buffer */
> +	struct xfs_dir3_icleaf_hdr *leafhdr)
>  {
>  	xfs_dir2_db_t		curdb = -1;	/* current data block number */
>  	struct xfs_buf		*dbp = NULL;	/* data buffer */
> @@ -1240,8 +1238,6 @@ xfs_dir2_leaf_lookup_int(
>  	xfs_trans_t		*tp;		/* transaction pointer */
>  	xfs_dir2_db_t		cidb = -1;	/* case match data block no. */
>  	enum xfs_dacmp		cmp;		/* name compare result */
> -	struct xfs_dir2_leaf_entry *ents;
> -	struct xfs_dir3_icleaf_hdr leafhdr;
>  
>  	dp = args->dp;
>  	tp = args->trans;
> @@ -1254,8 +1250,7 @@ xfs_dir2_leaf_lookup_int(
>  	*lbpp = lbp;
>  	leaf = lbp->b_addr;
>  	xfs_dir3_leaf_check(dp, lbp);
> -	ents = dp->d_ops->leaf_ents_p(leaf);
> -	xfs_dir2_leaf_hdr_from_disk(mp, &leafhdr, leaf);
> +	xfs_dir2_leaf_hdr_from_disk(mp, leafhdr, leaf);
>  
>  	/*
>  	 * Look for the first leaf entry with our hash value.
> @@ -1265,8 +1260,9 @@ xfs_dir2_leaf_lookup_int(
>  	 * Loop over all the entries with the right hash value
>  	 * looking to match the name.
>  	 */
> -	for (lep = &ents[index];
> -	     index < leafhdr.count && be32_to_cpu(lep->hashval) == args->hashval;
> +	for (lep = &leafhdr->ents[index];
> +	     index < leafhdr->count &&
> +			be32_to_cpu(lep->hashval) == args->hashval;
>  	     lep++, index++) {
>  		/*
>  		 * Skip over stale leaf entries.
> @@ -1372,7 +1368,6 @@ xfs_dir2_leaf_removename(
>  	int			needscan;	/* need to rescan data frees */
>  	xfs_dir2_data_off_t	oldbest;	/* old value of best free */
>  	struct xfs_dir2_data_free *bf;		/* bestfree table */
> -	struct xfs_dir2_leaf_entry *ents;
>  	struct xfs_dir3_icleaf_hdr leafhdr;
>  
>  	trace_xfs_dir2_leaf_removename(args);
> @@ -1380,20 +1375,20 @@ xfs_dir2_leaf_removename(
>  	/*
>  	 * Lookup the leaf entry, get the leaf and data blocks read in.
>  	 */
> -	if ((error = xfs_dir2_leaf_lookup_int(args, &lbp, &index, &dbp))) {
> +	error = xfs_dir2_leaf_lookup_int(args, &lbp, &index, &dbp, &leafhdr);
> +	if (error)
>  		return error;
> -	}
> +
>  	dp = args->dp;
>  	leaf = lbp->b_addr;
>  	hdr = dbp->b_addr;
>  	xfs_dir3_data_check(dp, dbp);
>  	bf = dp->d_ops->data_bestfree_p(hdr);
> -	xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &leafhdr, leaf);
> -	ents = dp->d_ops->leaf_ents_p(leaf);
> +
>  	/*
>  	 * Point to the leaf entry, use that to point to the data entry.
>  	 */
> -	lep = &ents[index];
> +	lep = &leafhdr.ents[index];
>  	db = xfs_dir2_dataptr_to_db(args->geo, be32_to_cpu(lep->address));
>  	dep = (xfs_dir2_data_entry_t *)((char *)hdr +
>  		xfs_dir2_dataptr_to_off(args->geo, be32_to_cpu(lep->address)));
> @@ -1419,7 +1414,7 @@ xfs_dir2_leaf_removename(
>  	xfs_dir3_leaf_log_header(args, lbp);
>  
>  	lep->address = cpu_to_be32(XFS_DIR2_NULL_DATAPTR);
> -	xfs_dir3_leaf_log_ents(args, lbp, index, index);
> +	xfs_dir3_leaf_log_ents(args, &leafhdr, lbp, index, index);
>  
>  	/*
>  	 * Scan the freespace in the data block again if necessary,
> @@ -1508,26 +1503,24 @@ xfs_dir2_leaf_replace(
>  	int			error;		/* error return code */
>  	int			index;		/* index of leaf entry */
>  	struct xfs_buf		*lbp;		/* leaf buffer */
> -	xfs_dir2_leaf_t		*leaf;		/* leaf structure */
>  	xfs_dir2_leaf_entry_t	*lep;		/* leaf entry */
>  	xfs_trans_t		*tp;		/* transaction pointer */
> -	struct xfs_dir2_leaf_entry *ents;
> +	struct xfs_dir3_icleaf_hdr leafhdr;
>  
>  	trace_xfs_dir2_leaf_replace(args);
>  
>  	/*
>  	 * Look up the entry.
>  	 */
> -	if ((error = xfs_dir2_leaf_lookup_int(args, &lbp, &index, &dbp))) {
> +	error = xfs_dir2_leaf_lookup_int(args, &lbp, &index, &dbp, &leafhdr);
> +	if (error)
>  		return error;
> -	}
> +
>  	dp = args->dp;
> -	leaf = lbp->b_addr;
> -	ents = dp->d_ops->leaf_ents_p(leaf);
>  	/*
>  	 * Point to the leaf entry, get data address from it.
>  	 */
> -	lep = &ents[index];
> +	lep = &leafhdr.ents[index];
>  	/*
>  	 * Point to the data entry.
>  	 */
> @@ -1561,21 +1554,17 @@ xfs_dir2_leaf_search_hash(
>  	xfs_dahash_t		hashwant;	/* hash value looking for */
>  	int			high;		/* high leaf index */
>  	int			low;		/* low leaf index */
> -	xfs_dir2_leaf_t		*leaf;		/* leaf structure */
>  	xfs_dir2_leaf_entry_t	*lep;		/* leaf entry */
>  	int			mid=0;		/* current leaf index */
> -	struct xfs_dir2_leaf_entry *ents;
>  	struct xfs_dir3_icleaf_hdr leafhdr;
>  
> -	leaf = lbp->b_addr;
> -	ents = args->dp->d_ops->leaf_ents_p(leaf);
> -	xfs_dir2_leaf_hdr_from_disk(args->dp->i_mount, &leafhdr, leaf);
> +	xfs_dir2_leaf_hdr_from_disk(args->dp->i_mount, &leafhdr, lbp->b_addr);
>  
>  	/*
>  	 * Note, the table cannot be empty, so we have to go through the loop.
>  	 * Binary search the leaf entries looking for our hash value.
>  	 */
> -	for (lep = ents, low = 0, high = leafhdr.count - 1,
> +	for (lep = leafhdr.ents, low = 0, high = leafhdr.count - 1,
>  		hashwant = args->hashval;
>  	     low <= high; ) {
>  		mid = (low + high) >> 1;
> diff --git a/fs/xfs/libxfs/xfs_dir2_node.c b/fs/xfs/libxfs/xfs_dir2_node.c
> index 98cd645a8c99..721dd2dcba8d 100644
> --- a/fs/xfs/libxfs/xfs_dir2_node.c
> +++ b/fs/xfs/libxfs/xfs_dir2_node.c
> @@ -441,7 +441,7 @@ xfs_dir2_leafn_add(
>  	trace_xfs_dir2_leafn_add(args, index);
>  
>  	xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &leafhdr, leaf);
> -	ents = dp->d_ops->leaf_ents_p(leaf);
> +	ents = leafhdr.ents;
>  
>  	/*
>  	 * Quick check just to make sure we are not going to index
> @@ -499,7 +499,7 @@ xfs_dir2_leafn_add(
>  
>  	xfs_dir2_leaf_hdr_to_disk(dp->i_mount, leaf, &leafhdr);
>  	xfs_dir3_leaf_log_header(args, bp);
> -	xfs_dir3_leaf_log_ents(args, bp, lfloglow, lfloghigh);
> +	xfs_dir3_leaf_log_ents(args, &leafhdr, bp, lfloglow, lfloghigh);
>  	xfs_dir3_leaf_check(dp, bp);
>  	return 0;
>  }
> @@ -534,11 +534,9 @@ xfs_dir2_leaf_lasthash(
>  	struct xfs_buf	*bp,			/* leaf buffer */
>  	int		*count)			/* count of entries in leaf */
>  {
> -	struct xfs_dir2_leaf	*leaf = bp->b_addr;
> -	struct xfs_dir2_leaf_entry *ents;
>  	struct xfs_dir3_icleaf_hdr leafhdr;
>  
> -	xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &leafhdr, leaf);
> +	xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &leafhdr, bp->b_addr);
>  
>  	ASSERT(leafhdr.magic == XFS_DIR2_LEAFN_MAGIC ||
>  	       leafhdr.magic == XFS_DIR3_LEAFN_MAGIC ||
> @@ -549,9 +547,7 @@ xfs_dir2_leaf_lasthash(
>  		*count = leafhdr.count;
>  	if (!leafhdr.count)
>  		return 0;
> -
> -	ents = dp->d_ops->leaf_ents_p(leaf);
> -	return be32_to_cpu(ents[leafhdr.count - 1].hashval);
> +	return be32_to_cpu(leafhdr.ents[leafhdr.count - 1].hashval);
>  }
>  
>  /*
> @@ -580,7 +576,6 @@ xfs_dir2_leafn_lookup_for_addname(
>  	xfs_dir2_db_t		newdb;		/* new data block number */
>  	xfs_dir2_db_t		newfdb;		/* new free block number */
>  	xfs_trans_t		*tp;		/* transaction pointer */
> -	struct xfs_dir2_leaf_entry *ents;
>  	struct xfs_dir3_icleaf_hdr leafhdr;
>  
>  	dp = args->dp;
> @@ -588,7 +583,6 @@ xfs_dir2_leafn_lookup_for_addname(
>  	mp = dp->i_mount;
>  	leaf = bp->b_addr;
>  	xfs_dir2_leaf_hdr_from_disk(mp, &leafhdr, leaf);
> -	ents = dp->d_ops->leaf_ents_p(leaf);
>  
>  	xfs_dir3_leaf_check(dp, bp);
>  	ASSERT(leafhdr.count > 0);
> @@ -612,7 +606,7 @@ xfs_dir2_leafn_lookup_for_addname(
>  	/*
>  	 * Loop over leaf entries with the right hash value.
>  	 */
> -	for (lep = &ents[index];
> +	for (lep = &leafhdr.ents[index];
>  	     index < leafhdr.count && be32_to_cpu(lep->hashval) == args->hashval;
>  	     lep++, index++) {
>  		/*
> @@ -732,7 +726,6 @@ xfs_dir2_leafn_lookup_for_entry(
>  	xfs_dir2_db_t		newdb;		/* new data block number */
>  	xfs_trans_t		*tp;		/* transaction pointer */
>  	enum xfs_dacmp		cmp;		/* comparison result */
> -	struct xfs_dir2_leaf_entry *ents;
>  	struct xfs_dir3_icleaf_hdr leafhdr;
>  
>  	dp = args->dp;
> @@ -740,7 +733,6 @@ xfs_dir2_leafn_lookup_for_entry(
>  	mp = dp->i_mount;
>  	leaf = bp->b_addr;
>  	xfs_dir2_leaf_hdr_from_disk(mp, &leafhdr, leaf);
> -	ents = dp->d_ops->leaf_ents_p(leaf);
>  
>  	xfs_dir3_leaf_check(dp, bp);
>  	if (leafhdr.count <= 0) {
> @@ -762,7 +754,7 @@ xfs_dir2_leafn_lookup_for_entry(
>  	/*
>  	 * Loop over leaf entries with the right hash value.
>  	 */
> -	for (lep = &ents[index];
> +	for (lep = &leafhdr.ents[index];
>  	     index < leafhdr.count && be32_to_cpu(lep->hashval) == args->hashval;
>  	     lep++, index++) {
>  		/*
> @@ -917,7 +909,7 @@ xfs_dir3_leafn_moveents(
>  	if (start_d < dhdr->count) {
>  		memmove(&dents[start_d + count], &dents[start_d],
>  			(dhdr->count - start_d) * sizeof(xfs_dir2_leaf_entry_t));
> -		xfs_dir3_leaf_log_ents(args, bp_d, start_d + count,
> +		xfs_dir3_leaf_log_ents(args, dhdr, bp_d, start_d + count,
>  				       count + dhdr->count - 1);
>  	}
>  	/*
> @@ -939,7 +931,7 @@ xfs_dir3_leafn_moveents(
>  	 */
>  	memcpy(&dents[start_d], &sents[start_s],
>  		count * sizeof(xfs_dir2_leaf_entry_t));
> -	xfs_dir3_leaf_log_ents(args, bp_d, start_d, start_d + count - 1);
> +	xfs_dir3_leaf_log_ents(args, dhdr, bp_d, start_d, start_d + count - 1);
>  
>  	/*
>  	 * If there are source entries after the ones we copied,
> @@ -948,7 +940,8 @@ xfs_dir3_leafn_moveents(
>  	if (start_s + count < shdr->count) {
>  		memmove(&sents[start_s], &sents[start_s + count],
>  			count * sizeof(xfs_dir2_leaf_entry_t));
> -		xfs_dir3_leaf_log_ents(args, bp_s, start_s, start_s + count - 1);
> +		xfs_dir3_leaf_log_ents(args, shdr, bp_s, start_s,
> +				       start_s + count - 1);
>  	}
>  
>  	/*
> @@ -979,8 +972,8 @@ xfs_dir2_leafn_order(
>  
>  	xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &hdr1, leaf1);
>  	xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &hdr2, leaf2);
> -	ents1 = dp->d_ops->leaf_ents_p(leaf1);
> -	ents2 = dp->d_ops->leaf_ents_p(leaf2);
> +	ents1 = hdr1.ents;
> +	ents2 = hdr2.ents;
>  
>  	if (hdr1.count > 0 && hdr2.count > 0 &&
>  	    (be32_to_cpu(ents2[0].hashval) < be32_to_cpu(ents1[0].hashval) ||
> @@ -1032,8 +1025,8 @@ xfs_dir2_leafn_rebalance(
>  	leaf2 = blk2->bp->b_addr;
>  	xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &hdr1, leaf1);
>  	xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &hdr2, leaf2);
> -	ents1 = dp->d_ops->leaf_ents_p(leaf1);
> -	ents2 = dp->d_ops->leaf_ents_p(leaf2);
> +	ents1 = hdr1.ents;
> +	ents2 = hdr2.ents;
>  
>  	oldsum = hdr1.count + hdr2.count;
>  #if defined(DEBUG) || defined(XFS_WARN)
> @@ -1221,7 +1214,6 @@ xfs_dir2_leafn_remove(
>  	xfs_trans_t		*tp;		/* transaction pointer */
>  	struct xfs_dir2_data_free *bf;		/* bestfree table */
>  	struct xfs_dir3_icleaf_hdr leafhdr;
> -	struct xfs_dir2_leaf_entry *ents;
>  
>  	trace_xfs_dir2_leafn_remove(args, index);
>  
> @@ -1229,12 +1221,11 @@ xfs_dir2_leafn_remove(
>  	tp = args->trans;
>  	leaf = bp->b_addr;
>  	xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &leafhdr, leaf);
> -	ents = dp->d_ops->leaf_ents_p(leaf);
>  
>  	/*
>  	 * Point to the entry we're removing.
>  	 */
> -	lep = &ents[index];
> +	lep = &leafhdr.ents[index];
>  
>  	/*
>  	 * Extract the data block and offset from the entry.
> @@ -1253,7 +1244,7 @@ xfs_dir2_leafn_remove(
>  	xfs_dir3_leaf_log_header(args, bp);
>  
>  	lep->address = cpu_to_be32(XFS_DIR2_NULL_DATAPTR);
> -	xfs_dir3_leaf_log_ents(args, bp, index, index);
> +	xfs_dir3_leaf_log_ents(args, &leafhdr, bp, index, index);
>  
>  	/*
>  	 * Make the data entry free.  Keep track of the longest freespace
> @@ -1350,7 +1341,7 @@ xfs_dir2_leafn_remove(
>  	 * to justify trying to join it with a neighbor.
>  	 */
>  	*rval = (dp->d_ops->leaf_hdr_size +
> -		 (uint)sizeof(ents[0]) * (leafhdr.count - leafhdr.stale)) <
> +		 (uint)sizeof(leafhdr.ents) * (leafhdr.count - leafhdr.stale)) <
>  		args->geo->magicpct;
>  	return 0;
>  }
> @@ -1451,7 +1442,7 @@ xfs_dir2_leafn_toosmall(
>  	blk = &state->path.blk[state->path.active - 1];
>  	leaf = blk->bp->b_addr;
>  	xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &leafhdr, leaf);
> -	ents = dp->d_ops->leaf_ents_p(leaf);
> +	ents = leafhdr.ents;
>  	xfs_dir3_leaf_check(dp, blk->bp);
>  
>  	count = leafhdr.count - leafhdr.stale;
> @@ -1514,7 +1505,7 @@ xfs_dir2_leafn_toosmall(
>  
>  		leaf = bp->b_addr;
>  		xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &hdr2, leaf);
> -		ents = dp->d_ops->leaf_ents_p(leaf);
> +		ents = hdr2.ents;
>  		count += hdr2.count - hdr2.stale;
>  		bytes -= count * sizeof(ents[0]);
>  
> @@ -1578,8 +1569,8 @@ xfs_dir2_leafn_unbalance(
>  
>  	xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &savehdr, save_leaf);
>  	xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &drophdr, drop_leaf);
> -	sents = dp->d_ops->leaf_ents_p(save_leaf);
> -	dents = dp->d_ops->leaf_ents_p(drop_leaf);
> +	sents = savehdr.ents;
> +	dents = drophdr.ents;
>  
>  	/*
>  	 * If there are any stale leaf entries, take this opportunity
> @@ -2161,8 +2152,6 @@ xfs_dir2_node_replace(
>  	int			i;		/* btree level */
>  	xfs_ino_t		inum;		/* new inode number */
>  	int			ftype;		/* new file type */
> -	xfs_dir2_leaf_t		*leaf;		/* leaf structure */
> -	xfs_dir2_leaf_entry_t	*lep;		/* leaf entry being changed */
>  	int			rval;		/* internal return value */
>  	xfs_da_state_t		*state;		/* btree cursor */
>  
> @@ -2194,16 +2183,17 @@ xfs_dir2_node_replace(
>  	 * and locked it.  But paranoia is good.
>  	 */
>  	if (rval == -EEXIST) {
> -		struct xfs_dir2_leaf_entry *ents;
> +		struct xfs_dir3_icleaf_hdr	leafhdr;
> +
>  		/*
>  		 * Find the leaf entry.
>  		 */
>  		blk = &state->path.blk[state->path.active - 1];
>  		ASSERT(blk->magic == XFS_DIR2_LEAFN_MAGIC);
> -		leaf = blk->bp->b_addr;
> -		ents = args->dp->d_ops->leaf_ents_p(leaf);
> -		lep = &ents[blk->index];
>  		ASSERT(state->extravalid);
> +
> +		xfs_dir2_leaf_hdr_from_disk(state->mp, &leafhdr,
> +					    blk->bp->b_addr);
>  		/*
>  		 * Point to the data entry.
>  		 */
> @@ -2213,7 +2203,7 @@ xfs_dir2_node_replace(
>  		dep = (xfs_dir2_data_entry_t *)
>  		      ((char *)hdr +
>  		       xfs_dir2_dataptr_to_off(args->geo,
> -					       be32_to_cpu(lep->address)));
> +				be32_to_cpu(leafhdr.ents[blk->index].address)));
>  		ASSERT(inum != be64_to_cpu(dep->inumber));
>  		/*
>  		 * Fill in the new inode number and log the entry.
> diff --git a/fs/xfs/libxfs/xfs_dir2_priv.h b/fs/xfs/libxfs/xfs_dir2_priv.h
> index af96e3faefaf..1f068812c453 100644
> --- a/fs/xfs/libxfs/xfs_dir2_priv.h
> +++ b/fs/xfs/libxfs/xfs_dir2_priv.h
> @@ -18,6 +18,12 @@ struct xfs_dir3_icleaf_hdr {
>  	uint16_t		magic;
>  	uint16_t		count;
>  	uint16_t		stale;
> +
> +	/*
> +	 * Pointer to the on-disk format entries, which are behind the
> +	 * variable size (v4 vs v5) header in the on-disk block.
> +	 */
> +	struct xfs_dir2_leaf_entry *ents;
>  };
>  
>  struct xfs_dir3_icfree_hdr {
> @@ -85,7 +91,8 @@ extern void xfs_dir3_leaf_compact_x1(struct xfs_dir3_icleaf_hdr *leafhdr,
>  extern int xfs_dir3_leaf_get_buf(struct xfs_da_args *args, xfs_dir2_db_t bno,
>  		struct xfs_buf **bpp, uint16_t magic);
>  extern void xfs_dir3_leaf_log_ents(struct xfs_da_args *args,
> -		struct xfs_buf *bp, int first, int last);
> +		struct xfs_dir3_icleaf_hdr *hdr, struct xfs_buf *bp, int first,
> +		int last);
>  extern void xfs_dir3_leaf_log_header(struct xfs_da_args *args,
>  		struct xfs_buf *bp);
>  extern int xfs_dir2_leaf_lookup(struct xfs_da_args *args);
> diff --git a/fs/xfs/scrub/dir.c b/fs/xfs/scrub/dir.c
> index 5b004d1f6bef..6754e1477661 100644
> --- a/fs/xfs/scrub/dir.c
> +++ b/fs/xfs/scrub/dir.c
> @@ -195,14 +195,15 @@ xchk_dir_rec(
>  	xfs_dir2_dataptr_t		ptr;
>  	xfs_dahash_t			calc_hash;
>  	xfs_dahash_t			hash;
> +	struct xfs_dir3_icleaf_hdr	hdr;
>  	unsigned int			tag;
>  	int				error;
>  
>  	ASSERT(blk->magic == XFS_DIR2_LEAF1_MAGIC ||
>  	       blk->magic == XFS_DIR2_LEAFN_MAGIC);
>  
> -	ent = (void *)ds->dargs.dp->d_ops->leaf_ents_p(blk->bp->b_addr) +
> -		(blk->index * sizeof(struct xfs_dir2_leaf_entry));
> +	xfs_dir2_leaf_hdr_from_disk(mp, &hdr, blk->bp->b_addr);
> +	ent = hdr.ents + blk->index;
>  
>  	/* Check the hash of the entry. */
>  	error = xchk_da_btree_hash(ds, level, &ent->hashval);
> @@ -481,7 +482,6 @@ xchk_directory_leaf1_bestfree(
>  	xfs_dablk_t			lblk)
>  {
>  	struct xfs_dir3_icleaf_hdr	leafhdr;
> -	struct xfs_dir2_leaf_entry	*ents;
>  	struct xfs_dir2_leaf_tail	*ltp;
>  	struct xfs_dir2_leaf		*leaf;
>  	struct xfs_buf			*dbp;
> @@ -505,7 +505,6 @@ xchk_directory_leaf1_bestfree(
>  
>  	leaf = bp->b_addr;
>  	xfs_dir2_leaf_hdr_from_disk(sc->ip->i_mount, &leafhdr, leaf);
> -	ents = d_ops->leaf_ents_p(leaf);
>  	ltp = xfs_dir2_leaf_tail_p(geo, leaf);
>  	bestcount = be32_to_cpu(ltp->bestcount);
>  	bestp = xfs_dir2_leaf_bests_p(ltp);
> @@ -533,18 +532,19 @@ xchk_directory_leaf1_bestfree(
>  	}
>  
>  	/* Leaves and bests don't overlap in leaf format. */
> -	if ((char *)&ents[leafhdr.count] > (char *)bestp) {
> +	if ((char *)&leafhdr.ents[leafhdr.count] > (char *)bestp) {
>  		xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk);
>  		goto out;
>  	}
>  
>  	/* Check hash value order, count stale entries.  */
>  	for (i = 0; i < leafhdr.count; i++) {
> -		hash = be32_to_cpu(ents[i].hashval);
> +		hash = be32_to_cpu(leafhdr.ents[i].hashval);
>  		if (i > 0 && lasthash > hash)
>  			xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk);
>  		lasthash = hash;
> -		if (ents[i].address == cpu_to_be32(XFS_DIR2_NULL_DATAPTR))
> +		if (leafhdr.ents[i].address ==
> +		    cpu_to_be32(XFS_DIR2_NULL_DATAPTR))
>  			stale++;
>  	}
>  	if (leafhdr.stale != stale)
> -- 
> 2.20.1
> 



[Index of Archives]     [XFS Filesystem Development (older mail)]     [Linux Filesystem Development]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux RAID]     [Linux SCSI]


  Powered by Linux