Commit 5ba30919 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Darrick J. Wong
Browse files

xfs: devirtualize ->free_hdr_from_disk



Replace the ->free_hdr_from_disk dir ops method with a directly called
xfs_dir_free_hdr_from_disk helper that takes care of the differences
between the v4 and v5 on-disk format.

Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
parent 478c7835
Loading
Loading
Loading
Loading
+0 −30
Original line number Diff line number Diff line
@@ -468,18 +468,6 @@ xfs_dir3_db_to_fdindex(struct xfs_da_geometry *geo, xfs_dir2_db_t db)
	return db % xfs_dir3_free_max_bests(geo);
}

static void
xfs_dir2_free_hdr_from_disk(
	struct xfs_dir3_icfree_hdr	*to,
	struct xfs_dir2_free		*from)
{
	to->magic = be32_to_cpu(from->hdr.magic);
	to->firstdb = be32_to_cpu(from->hdr.firstdb);
	to->nvalid = be32_to_cpu(from->hdr.nvalid);
	to->nused = be32_to_cpu(from->hdr.nused);
	ASSERT(to->magic == XFS_DIR2_FREE_MAGIC);
}

static void
xfs_dir2_free_hdr_to_disk(
	struct xfs_dir2_free		*to,
@@ -493,21 +481,6 @@ xfs_dir2_free_hdr_to_disk(
	to->hdr.nused = cpu_to_be32(from->nused);
}

static void
xfs_dir3_free_hdr_from_disk(
	struct xfs_dir3_icfree_hdr	*to,
	struct xfs_dir2_free		*from)
{
	struct xfs_dir3_free_hdr *hdr3 = (struct xfs_dir3_free_hdr *)from;

	to->magic = be32_to_cpu(hdr3->hdr.magic);
	to->firstdb = be32_to_cpu(hdr3->firstdb);
	to->nvalid = be32_to_cpu(hdr3->nvalid);
	to->nused = be32_to_cpu(hdr3->nused);

	ASSERT(to->magic == XFS_DIR3_FREE_MAGIC);
}

static void
xfs_dir3_free_hdr_to_disk(
	struct xfs_dir2_free		*to,
@@ -555,7 +528,6 @@ static const struct xfs_dir_ops xfs_dir2_ops = {

	.free_hdr_size = sizeof(struct xfs_dir2_free_hdr),
	.free_hdr_to_disk = xfs_dir2_free_hdr_to_disk,
	.free_hdr_from_disk = xfs_dir2_free_hdr_from_disk,
	.free_max_bests = xfs_dir2_free_max_bests,
	.free_bests_p = xfs_dir2_free_bests_p,
	.db_to_fdb = xfs_dir2_db_to_fdb,
@@ -594,7 +566,6 @@ static const struct xfs_dir_ops xfs_dir2_ftype_ops = {

	.free_hdr_size = sizeof(struct xfs_dir2_free_hdr),
	.free_hdr_to_disk = xfs_dir2_free_hdr_to_disk,
	.free_hdr_from_disk = xfs_dir2_free_hdr_from_disk,
	.free_max_bests = xfs_dir2_free_max_bests,
	.free_bests_p = xfs_dir2_free_bests_p,
	.db_to_fdb = xfs_dir2_db_to_fdb,
@@ -633,7 +604,6 @@ static const struct xfs_dir_ops xfs_dir3_ops = {

	.free_hdr_size = sizeof(struct xfs_dir3_free_hdr),
	.free_hdr_to_disk = xfs_dir3_free_hdr_to_disk,
	.free_hdr_from_disk = xfs_dir3_free_hdr_from_disk,
	.free_max_bests = xfs_dir3_free_max_bests,
	.free_bests_p = xfs_dir3_free_bests_p,
	.db_to_fdb = xfs_dir3_db_to_fdb,
+0 −2
Original line number Diff line number Diff line
@@ -75,8 +75,6 @@ struct xfs_dir_ops {
	int	free_hdr_size;
	void	(*free_hdr_to_disk)(struct xfs_dir2_free *to,
				    struct xfs_dir3_icfree_hdr *from);
	void	(*free_hdr_from_disk)(struct xfs_dir3_icfree_hdr *to,
				      struct xfs_dir2_free *from);
	int	(*free_max_bests)(struct xfs_da_geometry *geo);
	__be16 * (*free_bests_p)(struct xfs_dir2_free *free);
	xfs_dir2_db_t (*db_to_fdb)(struct xfs_da_geometry *geo,
+3 −11
Original line number Diff line number Diff line
@@ -113,7 +113,7 @@ xfs_dir3_leaf1_check(
	} else if (leafhdr.magic != XFS_DIR2_LEAF1_MAGIC)
		return __this_address;

	return xfs_dir3_leaf_check_int(dp->i_mount, dp, &leafhdr, leaf);
	return xfs_dir3_leaf_check_int(dp->i_mount, &leafhdr, leaf);
}

static inline void
@@ -138,23 +138,15 @@ xfs_dir3_leaf_check(
xfs_failaddr_t
xfs_dir3_leaf_check_int(
	struct xfs_mount	*mp,
	struct xfs_inode	*dp,
	struct xfs_dir3_icleaf_hdr *hdr,
	struct xfs_dir2_leaf	*leaf)
{
	xfs_dir2_leaf_tail_t	*ltp;
	int			stale;
	int			i;
	const struct xfs_dir_ops *ops;
	struct xfs_dir3_icleaf_hdr leafhdr;
	struct xfs_da_geometry	*geo = mp->m_dir_geo;

	/*
	 * we can be passed a null dp here from a verifier, so we need to go the
	 * hard way to get them.
	 */
	ops = xfs_dir_get_ops(mp, dp);

	if (!hdr) {
		xfs_dir2_leaf_hdr_from_disk(mp, &leafhdr, leaf);
		hdr = &leafhdr;
@@ -208,7 +200,7 @@ xfs_dir3_leaf_verify(
	if (fa)
		return fa;

	return xfs_dir3_leaf_check_int(mp, NULL, NULL, leaf);
	return xfs_dir3_leaf_check_int(mp, NULL, leaf);
}

static void
@@ -1758,7 +1750,7 @@ xfs_dir2_node_to_leaf(
	if (error)
		return error;
	free = fbp->b_addr;
	dp->d_ops->free_hdr_from_disk(&freehdr, free);
	xfs_dir2_free_hdr_from_disk(mp, &freehdr, free);

	ASSERT(!freehdr.firstdb);

+36 −10
Original line number Diff line number Diff line
@@ -54,7 +54,7 @@ xfs_dir3_leafn_check(
	} else if (leafhdr.magic != XFS_DIR2_LEAFN_MAGIC)
		return __this_address;

	return xfs_dir3_leaf_check_int(dp->i_mount, dp, &leafhdr, leaf);
	return xfs_dir3_leaf_check_int(dp->i_mount, &leafhdr, leaf);
}

static inline void
@@ -220,6 +220,30 @@ __xfs_dir3_free_read(
	return 0;
}

void
xfs_dir2_free_hdr_from_disk(
	struct xfs_mount		*mp,
	struct xfs_dir3_icfree_hdr	*to,
	struct xfs_dir2_free		*from)
{
	if (xfs_sb_version_hascrc(&mp->m_sb)) {
		struct xfs_dir3_free	*from3 = (struct xfs_dir3_free *)from;

		to->magic = be32_to_cpu(from3->hdr.hdr.magic);
		to->firstdb = be32_to_cpu(from3->hdr.firstdb);
		to->nvalid = be32_to_cpu(from3->hdr.nvalid);
		to->nused = be32_to_cpu(from3->hdr.nused);

		ASSERT(to->magic == XFS_DIR3_FREE_MAGIC);
	} else {
		to->magic = be32_to_cpu(from->hdr.magic);
		to->firstdb = be32_to_cpu(from->hdr.firstdb);
		to->nvalid = be32_to_cpu(from->hdr.nvalid);
		to->nused = be32_to_cpu(from->hdr.nused);
		ASSERT(to->magic == XFS_DIR2_FREE_MAGIC);
	}
}

int
xfs_dir2_free_read(
	struct xfs_trans	*tp,
@@ -369,7 +393,7 @@ xfs_dir2_leaf_to_node(
		return error;

	free = fbp->b_addr;
	dp->d_ops->free_hdr_from_disk(&freehdr, free);
	xfs_dir2_free_hdr_from_disk(dp->i_mount, &freehdr, free);
	leaf = lbp->b_addr;
	ltp = xfs_dir2_leaf_tail_p(args->geo, leaf);
	if (be32_to_cpu(ltp->bestcount) >
@@ -513,7 +537,7 @@ xfs_dir2_free_hdr_check(
{
	struct xfs_dir3_icfree_hdr hdr;

	dp->d_ops->free_hdr_from_disk(&hdr, bp->b_addr);
	xfs_dir2_free_hdr_from_disk(dp->i_mount, &hdr, bp->b_addr);

	ASSERT((hdr.firstdb %
		dp->d_ops->free_max_bests(dp->i_mount->m_dir_geo)) == 0);
@@ -1123,7 +1147,7 @@ xfs_dir3_data_block_free(
	struct xfs_dir3_icfree_hdr freehdr;
	struct xfs_inode	*dp = args->dp;

	dp->d_ops->free_hdr_from_disk(&freehdr, free);
	xfs_dir2_free_hdr_from_disk(dp->i_mount, &freehdr, free);
	bests = dp->d_ops->free_bests_p(free);
	if (hdr) {
		/*
@@ -1292,7 +1316,8 @@ xfs_dir2_leafn_remove(
#ifdef DEBUG
	{
		struct xfs_dir3_icfree_hdr freehdr;
		dp->d_ops->free_hdr_from_disk(&freehdr, free);

		xfs_dir2_free_hdr_from_disk(dp->i_mount, &freehdr, free);
		ASSERT(freehdr.firstdb == dp->d_ops->free_max_bests(args->geo) *
			(fdb - xfs_dir2_byte_to_db(args->geo,
						   XFS_DIR2_FREE_OFFSET)));
@@ -1686,7 +1711,7 @@ xfs_dir2_node_add_datablk(
			return error;
		free = fbp->b_addr;
		bests = dp->d_ops->free_bests_p(free);
		dp->d_ops->free_hdr_from_disk(&freehdr, free);
		xfs_dir2_free_hdr_from_disk(mp, &freehdr, free);

		/* Remember the first slot as our empty slot. */
		freehdr.firstdb = (fbno - xfs_dir2_byte_to_db(args->geo,
@@ -1695,7 +1720,7 @@ xfs_dir2_node_add_datablk(
	} else {
		free = fbp->b_addr;
		bests = dp->d_ops->free_bests_p(free);
		dp->d_ops->free_hdr_from_disk(&freehdr, free);
		xfs_dir2_free_hdr_from_disk(mp, &freehdr, free);
	}

	/* Set the freespace block index from the data block number. */
@@ -1764,7 +1789,8 @@ xfs_dir2_node_find_freeblk(
		if (findex >= 0) {
			/* caller already found the freespace for us. */
			bests = dp->d_ops->free_bests_p(free);
			dp->d_ops->free_hdr_from_disk(&freehdr, free);
			xfs_dir2_free_hdr_from_disk(dp->i_mount, &freehdr,
						    free);

			ASSERT(findex < freehdr.nvalid);
			ASSERT(be16_to_cpu(bests[findex]) != NULLDATAOFF);
@@ -1813,7 +1839,7 @@ xfs_dir2_node_find_freeblk(

		free = fbp->b_addr;
		bests = dp->d_ops->free_bests_p(free);
		dp->d_ops->free_hdr_from_disk(&freehdr, free);
		xfs_dir2_free_hdr_from_disk(dp->i_mount, &freehdr, free);

		/* Scan the free entry array for a large enough free space. */
		for (findex = freehdr.nvalid - 1; findex >= 0; findex--) {
@@ -2266,7 +2292,7 @@ xfs_dir2_node_trim_free(
	if (!bp)
		return 0;
	free = bp->b_addr;
	dp->d_ops->free_hdr_from_disk(&freehdr, free);
	xfs_dir2_free_hdr_from_disk(dp->i_mount, &freehdr, free);

	/*
	 * If there are used entries, there's nothing to do.
+3 −2
Original line number Diff line number Diff line
@@ -109,10 +109,11 @@ xfs_dir3_leaf_find_entry(struct xfs_dir3_icleaf_hdr *leafhdr,
extern int xfs_dir2_node_to_leaf(struct xfs_da_state *state);

extern xfs_failaddr_t xfs_dir3_leaf_check_int(struct xfs_mount *mp,
		struct xfs_inode *dp, struct xfs_dir3_icleaf_hdr *hdr,
		struct xfs_dir2_leaf *leaf);
		struct xfs_dir3_icleaf_hdr *hdr, struct xfs_dir2_leaf *leaf);

/* xfs_dir2_node.c */
void xfs_dir2_free_hdr_from_disk(struct xfs_mount *mp,
		struct xfs_dir3_icfree_hdr *to, struct xfs_dir2_free *from);
extern int xfs_dir2_leaf_to_node(struct xfs_da_args *args,
		struct xfs_buf *lbp);
extern xfs_dahash_t xfs_dir2_leaf_lasthash(struct xfs_inode *dp,
Loading