All of lore.kernel.org
 help / color / mirror / Atom feed
* remove m_dirops
@ 2019-11-01 22:06 Christoph Hellwig
  2019-11-01 22:06 ` [PATCH 01/34] xfs: move incore structures out of xfs_da_format.h Christoph Hellwig
                   ` (33 more replies)
  0 siblings, 34 replies; 81+ messages in thread
From: Christoph Hellwig @ 2019-11-01 22:06 UTC (permalink / raw)
  To: linux-xfs

Hi all,

this series removes the indirect call to distinguish between the v4 and v5
formats for dir and attrs btree blocks, and for file type enabled vs not
enabled formats.  Indirect calls have always been rather expensive, and
gotten even more so with the spectre workarounds.

This series removes almost 700 lines of code and shaves almost 6KB off
the size of the xfs module.



^ permalink raw reply	[flat|nested] 81+ messages in thread

* [PATCH 01/34] xfs: move incore structures out of xfs_da_format.h
  2019-11-01 22:06 remove m_dirops Christoph Hellwig
@ 2019-11-01 22:06 ` Christoph Hellwig
  2019-11-04 18:21   ` Darrick J. Wong
  2019-11-01 22:06 ` [PATCH 02/34] xfs: refactor btree node scrubbing Christoph Hellwig
                   ` (32 subsequent siblings)
  33 siblings, 1 reply; 81+ messages in thread
From: Christoph Hellwig @ 2019-11-01 22:06 UTC (permalink / raw)
  To: linux-xfs

Move the abstract in-memory version of various btree block headers
out of xfs_da_format.h as they aren't on-disk formats.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 fs/xfs/libxfs/xfs_attr_leaf.h | 23 ++++++++++++++
 fs/xfs/libxfs/xfs_da_btree.h  | 13 ++++++++
 fs/xfs/libxfs/xfs_da_format.c |  1 +
 fs/xfs/libxfs/xfs_da_format.h | 57 -----------------------------------
 fs/xfs/libxfs/xfs_dir2.h      |  2 ++
 fs/xfs/libxfs/xfs_dir2_priv.h | 20 ++++++++++++
 6 files changed, 59 insertions(+), 57 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_attr_leaf.h b/fs/xfs/libxfs/xfs_attr_leaf.h
index bb0880057ee3..16208a7743df 100644
--- a/fs/xfs/libxfs/xfs_attr_leaf.h
+++ b/fs/xfs/libxfs/xfs_attr_leaf.h
@@ -16,6 +16,29 @@ struct xfs_da_state_blk;
 struct xfs_inode;
 struct xfs_trans;
 
+/*
+ * Incore version of the attribute leaf header.
+ */
+struct xfs_attr3_icleaf_hdr {
+	uint32_t	forw;
+	uint32_t	back;
+	uint16_t	magic;
+	uint16_t	count;
+	uint16_t	usedbytes;
+	/*
+	 * Firstused is 32-bit here instead of 16-bit like the on-disk variant
+	 * to support maximum fsb size of 64k without overflow issues throughout
+	 * the attr code. Instead, the overflow condition is handled on
+	 * conversion to/from disk.
+	 */
+	uint32_t	firstused;
+	__u8		holes;
+	struct {
+		uint16_t	base;
+		uint16_t	size;
+	} freemap[XFS_ATTR_LEAF_MAPSIZE];
+};
+
 /*
  * Used to keep a list of "remote value" extents when unlinking an inode.
  */
diff --git a/fs/xfs/libxfs/xfs_da_btree.h b/fs/xfs/libxfs/xfs_da_btree.h
index ae0bbd20d9ca..02f7a21ab3a5 100644
--- a/fs/xfs/libxfs/xfs_da_btree.h
+++ b/fs/xfs/libxfs/xfs_da_btree.h
@@ -124,6 +124,19 @@ typedef struct xfs_da_state {
 						/* for dirv2 extrablk is data */
 } xfs_da_state_t;
 
+/*
+ * In-core version of the node header to abstract the differences in the v2 and
+ * v3 disk format of the headers. Callers need to convert to/from disk format as
+ * appropriate.
+ */
+struct xfs_da3_icnode_hdr {
+	uint32_t		forw;
+	uint32_t		back;
+	uint16_t		magic;
+	uint16_t		count;
+	uint16_t		level;
+};
+
 /*
  * Utility macros to aid in logging changed structure fields.
  */
diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c
index b1ae572496b6..31bb250c1899 100644
--- a/fs/xfs/libxfs/xfs_da_format.c
+++ b/fs/xfs/libxfs/xfs_da_format.c
@@ -13,6 +13,7 @@
 #include "xfs_mount.h"
 #include "xfs_inode.h"
 #include "xfs_dir2.h"
+#include "xfs_dir2_priv.h"
 
 /*
  * Shortform directory ops
diff --git a/fs/xfs/libxfs/xfs_da_format.h b/fs/xfs/libxfs/xfs_da_format.h
index ae654e06b2fb..548806060f45 100644
--- a/fs/xfs/libxfs/xfs_da_format.h
+++ b/fs/xfs/libxfs/xfs_da_format.h
@@ -93,19 +93,6 @@ struct xfs_da3_intnode {
 	struct xfs_da_node_entry __btree[];
 };
 
-/*
- * In-core version of the node header to abstract the differences in the v2 and
- * v3 disk format of the headers. Callers need to convert to/from disk format as
- * appropriate.
- */
-struct xfs_da3_icnode_hdr {
-	uint32_t	forw;
-	uint32_t	back;
-	uint16_t	magic;
-	uint16_t	count;
-	uint16_t	level;
-};
-
 /*
  * Directory version 2.
  *
@@ -434,14 +421,6 @@ struct xfs_dir3_leaf_hdr {
 	__be32			pad;		/* 64 bit alignment */
 };
 
-struct xfs_dir3_icleaf_hdr {
-	uint32_t		forw;
-	uint32_t		back;
-	uint16_t		magic;
-	uint16_t		count;
-	uint16_t		stale;
-};
-
 /*
  * Leaf block entry.
  */
@@ -520,19 +499,6 @@ struct xfs_dir3_free {
 
 #define XFS_DIR3_FREE_CRC_OFF  offsetof(struct xfs_dir3_free, hdr.hdr.crc)
 
-/*
- * In core version of the free block header, abstracted away from on-disk format
- * differences. Use this in the code, and convert to/from the disk version using
- * xfs_dir3_free_hdr_from_disk/xfs_dir3_free_hdr_to_disk.
- */
-struct xfs_dir3_icfree_hdr {
-	uint32_t	magic;
-	uint32_t	firstdb;
-	uint32_t	nvalid;
-	uint32_t	nused;
-
-};
-
 /*
  * Single block format.
  *
@@ -709,29 +675,6 @@ struct xfs_attr3_leafblock {
 	 */
 };
 
-/*
- * incore, neutral version of the attribute leaf header
- */
-struct xfs_attr3_icleaf_hdr {
-	uint32_t	forw;
-	uint32_t	back;
-	uint16_t	magic;
-	uint16_t	count;
-	uint16_t	usedbytes;
-	/*
-	 * firstused is 32-bit here instead of 16-bit like the on-disk variant
-	 * to support maximum fsb size of 64k without overflow issues throughout
-	 * the attr code. Instead, the overflow condition is handled on
-	 * conversion to/from disk.
-	 */
-	uint32_t	firstused;
-	__u8		holes;
-	struct {
-		uint16_t	base;
-		uint16_t	size;
-	} freemap[XFS_ATTR_LEAF_MAPSIZE];
-};
-
 /*
  * Special value to represent fs block size in the leaf header firstused field.
  * Only used when block size overflows the 2-bytes available on disk.
diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h
index f54244779492..e170792c0acc 100644
--- a/fs/xfs/libxfs/xfs_dir2.h
+++ b/fs/xfs/libxfs/xfs_dir2.h
@@ -18,6 +18,8 @@ struct xfs_dir2_sf_entry;
 struct xfs_dir2_data_hdr;
 struct xfs_dir2_data_entry;
 struct xfs_dir2_data_unused;
+struct xfs_dir3_icfree_hdr;
+struct xfs_dir3_icleaf_hdr;
 
 extern struct xfs_name	xfs_name_dotdot;
 
diff --git a/fs/xfs/libxfs/xfs_dir2_priv.h b/fs/xfs/libxfs/xfs_dir2_priv.h
index 59f9fb2241a5..973b1527b7ba 100644
--- a/fs/xfs/libxfs/xfs_dir2_priv.h
+++ b/fs/xfs/libxfs/xfs_dir2_priv.h
@@ -8,6 +8,26 @@
 
 struct dir_context;
 
+/*
+ * In-core version of the leaf and free block headers to abstract the
+ * differences in the v2 and v3 disk format of the headers.
+ */
+struct xfs_dir3_icleaf_hdr {
+	uint32_t		forw;
+	uint32_t		back;
+	uint16_t		magic;
+	uint16_t		count;
+	uint16_t		stale;
+};
+
+struct xfs_dir3_icfree_hdr {
+	uint32_t		magic;
+	uint32_t		firstdb;
+	uint32_t		nvalid;
+	uint32_t		nused;
+
+};
+
 /* xfs_dir2.c */
 extern int xfs_dir2_grow_inode(struct xfs_da_args *args, int space,
 				xfs_dir2_db_t *dbp);
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 02/34] xfs: refactor btree node scrubbing
  2019-11-01 22:06 remove m_dirops Christoph Hellwig
  2019-11-01 22:06 ` [PATCH 01/34] xfs: move incore structures out of xfs_da_format.h Christoph Hellwig
@ 2019-11-01 22:06 ` Christoph Hellwig
  2019-11-04 18:36   ` Darrick J. Wong
  2019-11-01 22:06 ` [PATCH 03/34] xfs: devirtualize ->node_hdr_from_disk Christoph Hellwig
                   ` (31 subsequent siblings)
  33 siblings, 1 reply; 81+ messages in thread
From: Christoph Hellwig @ 2019-11-01 22:06 UTC (permalink / raw)
  To: linux-xfs

Break up xchk_da_btree_entry and handle looking up leaf node entries
in the attr / dir callbacks, so that only the generic node handling
is left in the common core code.  Note that the checks for the crc
enabled blocks are removed, as the scrubbing code already remaps the
magic numbers earlier.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 fs/xfs/scrub/attr.c    | 12 ++++++-----
 fs/xfs/scrub/dabtree.c | 48 ++++++++++--------------------------------
 fs/xfs/scrub/dabtree.h |  3 +--
 fs/xfs/scrub/dir.c     | 12 ++++++++---
 4 files changed, 28 insertions(+), 47 deletions(-)

diff --git a/fs/xfs/scrub/attr.c b/fs/xfs/scrub/attr.c
index 0edc7f8eb96e..035d5734e0af 100644
--- a/fs/xfs/scrub/attr.c
+++ b/fs/xfs/scrub/attr.c
@@ -398,15 +398,14 @@ xchk_xattr_block(
 STATIC int
 xchk_xattr_rec(
 	struct xchk_da_btree		*ds,
-	int				level,
-	void				*rec)
+	int				level)
 {
 	struct xfs_mount		*mp = ds->state->mp;
-	struct xfs_attr_leaf_entry	*ent = rec;
-	struct xfs_da_state_blk		*blk;
+	struct xfs_da_state_blk		*blk = &ds->state->path.blk[level];
 	struct xfs_attr_leaf_name_local	*lentry;
 	struct xfs_attr_leaf_name_remote	*rentry;
 	struct xfs_buf			*bp;
+	struct xfs_attr_leaf_entry	*ent;
 	xfs_dahash_t			calc_hash;
 	xfs_dahash_t			hash;
 	int				nameidx;
@@ -414,7 +413,10 @@ xchk_xattr_rec(
 	unsigned int			badflags;
 	int				error;
 
-	blk = &ds->state->path.blk[level];
+	ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC);
+
+	ent = (void *)xfs_attr3_leaf_entryp(blk->bp->b_addr) +
+		(blk->index * sizeof(struct xfs_attr_leaf_entry));
 
 	/* Check the whole block, if necessary. */
 	error = xchk_xattr_block(ds, level);
diff --git a/fs/xfs/scrub/dabtree.c b/fs/xfs/scrub/dabtree.c
index 77ff9f97bcda..d1248c223c7f 100644
--- a/fs/xfs/scrub/dabtree.c
+++ b/fs/xfs/scrub/dabtree.c
@@ -77,40 +77,17 @@ xchk_da_set_corrupt(
 			__return_address);
 }
 
-/* Find an entry at a certain level in a da btree. */
-STATIC void *
-xchk_da_btree_entry(
-	struct xchk_da_btree	*ds,
-	int			level,
-	int			rec)
+static struct xfs_da_node_entry *
+xchk_da_btree_node_entry(
+	struct xchk_da_btree		*ds,
+	int				level)
 {
-	char			*ents;
-	struct xfs_da_state_blk	*blk;
-	void			*baddr;
+	struct xfs_da_state_blk		*blk = &ds->state->path.blk[level];
 
-	/* Dispatch the entry finding function. */
-	blk = &ds->state->path.blk[level];
-	baddr = blk->bp->b_addr;
-	switch (blk->magic) {
-	case XFS_ATTR_LEAF_MAGIC:
-	case XFS_ATTR3_LEAF_MAGIC:
-		ents = (char *)xfs_attr3_leaf_entryp(baddr);
-		return ents + (rec * sizeof(struct xfs_attr_leaf_entry));
-	case XFS_DIR2_LEAFN_MAGIC:
-	case XFS_DIR3_LEAFN_MAGIC:
-		ents = (char *)ds->dargs.dp->d_ops->leaf_ents_p(baddr);
-		return ents + (rec * sizeof(struct xfs_dir2_leaf_entry));
-	case XFS_DIR2_LEAF1_MAGIC:
-	case XFS_DIR3_LEAF1_MAGIC:
-		ents = (char *)ds->dargs.dp->d_ops->leaf_ents_p(baddr);
-		return ents + (rec * sizeof(struct xfs_dir2_leaf_entry));
-	case XFS_DA_NODE_MAGIC:
-	case XFS_DA3_NODE_MAGIC:
-		ents = (char *)ds->dargs.dp->d_ops->node_tree_p(baddr);
-		return ents + (rec * sizeof(struct xfs_da_node_entry));
-	}
+	ASSERT(blk->magic == XFS_DA_NODE_MAGIC);
 
-	return NULL;
+	return (void *)ds->dargs.dp->d_ops->node_tree_p(blk->bp->b_addr) +
+		(blk->index * sizeof(struct xfs_da_node_entry));
 }
 
 /* Scrub a da btree hash (key). */
@@ -136,7 +113,7 @@ xchk_da_btree_hash(
 
 	/* Is this hash no larger than the parent hash? */
 	blks = ds->state->path.blk;
-	entry = xchk_da_btree_entry(ds, level - 1, blks[level - 1].index);
+	entry = xchk_da_btree_node_entry(ds, level - 1);
 	parent_hash = be32_to_cpu(entry->hashval);
 	if (parent_hash < hash)
 		xchk_da_set_corrupt(ds, level);
@@ -479,7 +456,6 @@ xchk_da_btree(
 	struct xfs_mount		*mp = sc->mp;
 	struct xfs_da_state_blk		*blks;
 	struct xfs_da_node_entry	*key;
-	void				*rec;
 	xfs_dablk_t			blkno;
 	int				level;
 	int				error;
@@ -538,9 +514,7 @@ xchk_da_btree(
 			}
 
 			/* Dispatch record scrubbing. */
-			rec = xchk_da_btree_entry(&ds, level,
-					blks[level].index);
-			error = scrub_fn(&ds, level, rec);
+			error = scrub_fn(&ds, level);
 			if (error)
 				break;
 			if (xchk_should_terminate(sc, &error) ||
@@ -562,7 +536,7 @@ xchk_da_btree(
 		}
 
 		/* Hashes in order for scrub? */
-		key = xchk_da_btree_entry(&ds, level, blks[level].index);
+		key = xchk_da_btree_node_entry(&ds, level);
 		error = xchk_da_btree_hash(&ds, level, &key->hashval);
 		if (error)
 			goto out;
diff --git a/fs/xfs/scrub/dabtree.h b/fs/xfs/scrub/dabtree.h
index cb3f0003245b..1f3515c6d5a8 100644
--- a/fs/xfs/scrub/dabtree.h
+++ b/fs/xfs/scrub/dabtree.h
@@ -28,8 +28,7 @@ struct xchk_da_btree {
 	int			tree_level;
 };
 
-typedef int (*xchk_da_btree_rec_fn)(struct xchk_da_btree *ds,
-		int level, void *rec);
+typedef int (*xchk_da_btree_rec_fn)(struct xchk_da_btree *ds, int level);
 
 /* Check for da btree operation errors. */
 bool xchk_da_process_error(struct xchk_da_btree *ds, int level, int *error);
diff --git a/fs/xfs/scrub/dir.c b/fs/xfs/scrub/dir.c
index 1e2e11721eb9..97f274f7cd38 100644
--- a/fs/xfs/scrub/dir.c
+++ b/fs/xfs/scrub/dir.c
@@ -179,14 +179,14 @@ xchk_dir_actor(
 STATIC int
 xchk_dir_rec(
 	struct xchk_da_btree		*ds,
-	int				level,
-	void				*rec)
+	int				level)
 {
+	struct xfs_da_state_blk		*blk = &ds->state->path.blk[level];
 	struct xfs_mount		*mp = ds->state->mp;
-	struct xfs_dir2_leaf_entry	*ent = rec;
 	struct xfs_inode		*dp = ds->dargs.dp;
 	struct xfs_dir2_data_entry	*dent;
 	struct xfs_buf			*bp;
+	struct xfs_dir2_leaf_entry	*ent;
 	char				*p, *endp;
 	xfs_ino_t			ino;
 	xfs_dablk_t			rec_bno;
@@ -198,6 +198,12 @@ xchk_dir_rec(
 	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));
+
 	/* Check the hash of the entry. */
 	error = xchk_da_btree_hash(ds, level, &ent->hashval);
 	if (error)
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 03/34] xfs: devirtualize ->node_hdr_from_disk
  2019-11-01 22:06 remove m_dirops Christoph Hellwig
  2019-11-01 22:06 ` [PATCH 01/34] xfs: move incore structures out of xfs_da_format.h Christoph Hellwig
  2019-11-01 22:06 ` [PATCH 02/34] xfs: refactor btree node scrubbing Christoph Hellwig
@ 2019-11-01 22:06 ` Christoph Hellwig
  2019-11-04 18:37   ` Darrick J. Wong
  2019-11-01 22:06 ` [PATCH 04/34] xfs: devirtualize ->node_hdr_to_disk Christoph Hellwig
                   ` (30 subsequent siblings)
  33 siblings, 1 reply; 81+ messages in thread
From: Christoph Hellwig @ 2019-11-01 22:06 UTC (permalink / raw)
  To: linux-xfs

Replace the ->node_hdr_from_disk dir ops method with a directly called
xfs_da_node_hdr_from_disk helper that takes care of the v4 vs v5
difference.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 fs/xfs/libxfs/xfs_attr_leaf.c |  2 +-
 fs/xfs/libxfs/xfs_da_btree.c  | 84 ++++++++++++++++++++++-------------
 fs/xfs/libxfs/xfs_da_btree.h  |  3 ++
 fs/xfs/libxfs/xfs_da_format.c | 33 --------------
 fs/xfs/libxfs/xfs_dir2.h      |  2 -
 fs/xfs/scrub/dabtree.c        |  2 +-
 fs/xfs/xfs_attr_inactive.c    |  2 +-
 fs/xfs/xfs_attr_list.c        |  2 +-
 8 files changed, 60 insertions(+), 70 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_attr_leaf.c b/fs/xfs/libxfs/xfs_attr_leaf.c
index 56e62b3d9bb7..131fef677896 100644
--- a/fs/xfs/libxfs/xfs_attr_leaf.c
+++ b/fs/xfs/libxfs/xfs_attr_leaf.c
@@ -1185,7 +1185,7 @@ xfs_attr3_leaf_to_node(
 	if (error)
 		goto out;
 	node = bp1->b_addr;
-	dp->d_ops->node_hdr_from_disk(&icnodehdr, node);
+	xfs_da3_node_hdr_from_disk(mp, &icnodehdr, node);
 	btree = dp->d_ops->node_tree_p(node);
 
 	leaf = bp2->b_addr;
diff --git a/fs/xfs/libxfs/xfs_da_btree.c b/fs/xfs/libxfs/xfs_da_btree.c
index 4fd1223c1bd5..f7ddc91ed099 100644
--- a/fs/xfs/libxfs/xfs_da_btree.c
+++ b/fs/xfs/libxfs/xfs_da_btree.c
@@ -110,6 +110,31 @@ xfs_da_state_free(xfs_da_state_t *state)
 	kmem_zone_free(xfs_da_state_zone, state);
 }
 
+void
+xfs_da3_node_hdr_from_disk(
+	struct xfs_mount		*mp,
+	struct xfs_da3_icnode_hdr	*to,
+	struct xfs_da_intnode		*from)
+{
+	if (xfs_sb_version_hascrc(&mp->m_sb)) {
+		struct xfs_da3_intnode	*from3 = (struct xfs_da3_intnode *)from;
+
+		to->forw = be32_to_cpu(from3->hdr.info.hdr.forw);
+		to->back = be32_to_cpu(from3->hdr.info.hdr.back);
+		to->magic = be16_to_cpu(from3->hdr.info.hdr.magic);
+		to->count = be16_to_cpu(from3->hdr.__count);
+		to->level = be16_to_cpu(from3->hdr.__level);
+		ASSERT(to->magic == XFS_DA3_NODE_MAGIC);
+	} else {
+		to->forw = be32_to_cpu(from->hdr.info.forw);
+		to->back = be32_to_cpu(from->hdr.info.back);
+		to->magic = be16_to_cpu(from->hdr.info.magic);
+		to->count = be16_to_cpu(from->hdr.__count);
+		to->level = be16_to_cpu(from->hdr.__level);
+		ASSERT(to->magic == XFS_DA_NODE_MAGIC);
+	}
+}
+
 /*
  * Verify an xfs_da3_blkinfo structure. Note that the da3 fields are only
  * accessible on v5 filesystems. This header format is common across da node,
@@ -145,12 +170,9 @@ xfs_da3_node_verify(
 	struct xfs_mount	*mp = bp->b_mount;
 	struct xfs_da_intnode	*hdr = bp->b_addr;
 	struct xfs_da3_icnode_hdr ichdr;
-	const struct xfs_dir_ops *ops;
 	xfs_failaddr_t		fa;
 
-	ops = xfs_dir_get_ops(mp, NULL);
-
-	ops->node_hdr_from_disk(&ichdr, hdr);
+	xfs_da3_node_hdr_from_disk(mp, &ichdr, hdr);
 
 	fa = xfs_da3_blkinfo_verify(bp, bp->b_addr);
 	if (fa)
@@ -577,7 +599,7 @@ xfs_da3_root_split(
 	    oldroot->hdr.info.magic == cpu_to_be16(XFS_DA3_NODE_MAGIC)) {
 		struct xfs_da3_icnode_hdr icnodehdr;
 
-		dp->d_ops->node_hdr_from_disk(&icnodehdr, oldroot);
+		xfs_da3_node_hdr_from_disk(dp->i_mount, &icnodehdr, oldroot);
 		btree = dp->d_ops->node_tree_p(oldroot);
 		size = (int)((char *)&btree[icnodehdr.count] - (char *)oldroot);
 		level = icnodehdr.level;
@@ -637,7 +659,7 @@ xfs_da3_root_split(
 		return error;
 
 	node = bp->b_addr;
-	dp->d_ops->node_hdr_from_disk(&nodehdr, node);
+	xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr, node);
 	btree = dp->d_ops->node_tree_p(node);
 	btree[0].hashval = cpu_to_be32(blk1->hashval);
 	btree[0].before = cpu_to_be32(blk1->blkno);
@@ -686,7 +708,7 @@ xfs_da3_node_split(
 	trace_xfs_da_node_split(state->args);
 
 	node = oldblk->bp->b_addr;
-	dp->d_ops->node_hdr_from_disk(&nodehdr, node);
+	xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr, node);
 
 	/*
 	 * With V2 dirs the extra block is data or freespace.
@@ -733,7 +755,7 @@ xfs_da3_node_split(
 	 * If we had double-split op below us, then add the extra block too.
 	 */
 	node = oldblk->bp->b_addr;
-	dp->d_ops->node_hdr_from_disk(&nodehdr, node);
+	xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr, node);
 	if (oldblk->index <= nodehdr.count) {
 		oldblk->index++;
 		xfs_da3_node_add(state, oldblk, addblk);
@@ -788,8 +810,8 @@ xfs_da3_node_rebalance(
 
 	node1 = blk1->bp->b_addr;
 	node2 = blk2->bp->b_addr;
-	dp->d_ops->node_hdr_from_disk(&nodehdr1, node1);
-	dp->d_ops->node_hdr_from_disk(&nodehdr2, node2);
+	xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr1, node1);
+	xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr2, node2);
 	btree1 = dp->d_ops->node_tree_p(node1);
 	btree2 = dp->d_ops->node_tree_p(node2);
 
@@ -804,8 +826,8 @@ xfs_da3_node_rebalance(
 		tmpnode = node1;
 		node1 = node2;
 		node2 = tmpnode;
-		dp->d_ops->node_hdr_from_disk(&nodehdr1, node1);
-		dp->d_ops->node_hdr_from_disk(&nodehdr2, node2);
+		xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr1, node1);
+		xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr2, node2);
 		btree1 = dp->d_ops->node_tree_p(node1);
 		btree2 = dp->d_ops->node_tree_p(node2);
 		swap = 1;
@@ -886,8 +908,8 @@ xfs_da3_node_rebalance(
 	if (swap) {
 		node1 = blk1->bp->b_addr;
 		node2 = blk2->bp->b_addr;
-		dp->d_ops->node_hdr_from_disk(&nodehdr1, node1);
-		dp->d_ops->node_hdr_from_disk(&nodehdr2, node2);
+		xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr1, node1);
+		xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr2, node2);
 		btree1 = dp->d_ops->node_tree_p(node1);
 		btree2 = dp->d_ops->node_tree_p(node2);
 	}
@@ -921,7 +943,7 @@ xfs_da3_node_add(
 	trace_xfs_da_node_add(state->args);
 
 	node = oldblk->bp->b_addr;
-	dp->d_ops->node_hdr_from_disk(&nodehdr, node);
+	xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr, node);
 	btree = dp->d_ops->node_tree_p(node);
 
 	ASSERT(oldblk->index >= 0 && oldblk->index <= nodehdr.count);
@@ -1092,7 +1114,7 @@ xfs_da3_root_join(
 
 	args = state->args;
 	oldroot = root_blk->bp->b_addr;
-	dp->d_ops->node_hdr_from_disk(&oldroothdr, oldroot);
+	xfs_da3_node_hdr_from_disk(dp->i_mount, &oldroothdr, oldroot);
 	ASSERT(oldroothdr.forw == 0);
 	ASSERT(oldroothdr.back == 0);
 
@@ -1172,7 +1194,7 @@ xfs_da3_node_toosmall(
 	blk = &state->path.blk[ state->path.active-1 ];
 	info = blk->bp->b_addr;
 	node = (xfs_da_intnode_t *)info;
-	dp->d_ops->node_hdr_from_disk(&nodehdr, node);
+	xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr, node);
 	if (nodehdr.count > (state->args->geo->node_ents >> 1)) {
 		*action = 0;	/* blk over 50%, don't try to join */
 		return 0;	/* blk over 50%, don't try to join */
@@ -1230,7 +1252,7 @@ xfs_da3_node_toosmall(
 			return error;
 
 		node = bp->b_addr;
-		dp->d_ops->node_hdr_from_disk(&thdr, node);
+		xfs_da3_node_hdr_from_disk(dp->i_mount, &thdr, node);
 		xfs_trans_brelse(state->args->trans, bp);
 
 		if (count - thdr.count >= 0)
@@ -1277,7 +1299,7 @@ xfs_da3_node_lasthash(
 	struct xfs_da3_icnode_hdr nodehdr;
 
 	node = bp->b_addr;
-	dp->d_ops->node_hdr_from_disk(&nodehdr, node);
+	xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr, node);
 	if (count)
 		*count = nodehdr.count;
 	if (!nodehdr.count)
@@ -1328,7 +1350,7 @@ xfs_da3_fixhashpath(
 		struct xfs_da3_icnode_hdr nodehdr;
 
 		node = blk->bp->b_addr;
-		dp->d_ops->node_hdr_from_disk(&nodehdr, node);
+		xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr, node);
 		btree = dp->d_ops->node_tree_p(node);
 		if (be32_to_cpu(btree[blk->index].hashval) == lasthash)
 			break;
@@ -1360,7 +1382,7 @@ xfs_da3_node_remove(
 	trace_xfs_da_node_remove(state->args);
 
 	node = drop_blk->bp->b_addr;
-	dp->d_ops->node_hdr_from_disk(&nodehdr, node);
+	xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr, node);
 	ASSERT(drop_blk->index < nodehdr.count);
 	ASSERT(drop_blk->index >= 0);
 
@@ -1416,8 +1438,8 @@ xfs_da3_node_unbalance(
 
 	drop_node = drop_blk->bp->b_addr;
 	save_node = save_blk->bp->b_addr;
-	dp->d_ops->node_hdr_from_disk(&drop_hdr, drop_node);
-	dp->d_ops->node_hdr_from_disk(&save_hdr, save_node);
+	xfs_da3_node_hdr_from_disk(dp->i_mount, &drop_hdr, drop_node);
+	xfs_da3_node_hdr_from_disk(dp->i_mount, &save_hdr, save_node);
 	drop_btree = dp->d_ops->node_tree_p(drop_node);
 	save_btree = dp->d_ops->node_tree_p(save_node);
 	tp = state->args->trans;
@@ -1550,7 +1572,7 @@ xfs_da3_node_lookup_int(
 		 * Search an intermediate node for a match.
 		 */
 		node = blk->bp->b_addr;
-		dp->d_ops->node_hdr_from_disk(&nodehdr, node);
+		xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr, node);
 		btree = dp->d_ops->node_tree_p(node);
 
 		/* Tree taller than we can handle; bail out! */
@@ -1678,8 +1700,8 @@ xfs_da3_node_order(
 
 	node1 = node1_bp->b_addr;
 	node2 = node2_bp->b_addr;
-	dp->d_ops->node_hdr_from_disk(&node1hdr, node1);
-	dp->d_ops->node_hdr_from_disk(&node2hdr, node2);
+	xfs_da3_node_hdr_from_disk(dp->i_mount, &node1hdr, node1);
+	xfs_da3_node_hdr_from_disk(dp->i_mount, &node2hdr, node2);
 	btree1 = dp->d_ops->node_tree_p(node1);
 	btree2 = dp->d_ops->node_tree_p(node2);
 
@@ -1902,7 +1924,7 @@ xfs_da3_path_shift(
 	level = (path->active-1) - 1;	/* skip bottom layer in path */
 	for (blk = &path->blk[level]; level >= 0; blk--, level--) {
 		node = blk->bp->b_addr;
-		dp->d_ops->node_hdr_from_disk(&nodehdr, node);
+		xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr, node);
 		btree = dp->d_ops->node_tree_p(node);
 
 		if (forward && (blk->index < nodehdr.count - 1)) {
@@ -1963,7 +1985,7 @@ xfs_da3_path_shift(
 		case XFS_DA3_NODE_MAGIC:
 			blk->magic = XFS_DA_NODE_MAGIC;
 			node = (xfs_da_intnode_t *)info;
-			dp->d_ops->node_hdr_from_disk(&nodehdr, node);
+			xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr, node);
 			btree = dp->d_ops->node_tree_p(node);
 			blk->hashval = be32_to_cpu(btree[nodehdr.count - 1].hashval);
 			if (forward)
@@ -2248,7 +2270,7 @@ xfs_da3_swap_lastblock(
 		struct xfs_da3_icnode_hdr deadhdr;
 
 		dead_node = (xfs_da_intnode_t *)dead_info;
-		dp->d_ops->node_hdr_from_disk(&deadhdr, dead_node);
+		xfs_da3_node_hdr_from_disk(dp->i_mount, &deadhdr, dead_node);
 		btree = dp->d_ops->node_tree_p(dead_node);
 		dead_level = deadhdr.level;
 		dead_hash = be32_to_cpu(btree[deadhdr.count - 1].hashval);
@@ -2308,7 +2330,7 @@ xfs_da3_swap_lastblock(
 		if (error)
 			goto done;
 		par_node = par_buf->b_addr;
-		dp->d_ops->node_hdr_from_disk(&par_hdr, par_node);
+		xfs_da3_node_hdr_from_disk(dp->i_mount, &par_hdr, par_node);
 		if (level >= 0 && level != par_hdr.level + 1) {
 			XFS_ERROR_REPORT("xfs_da_swap_lastblock(4)",
 					 XFS_ERRLEVEL_LOW, mp);
@@ -2359,7 +2381,7 @@ xfs_da3_swap_lastblock(
 		if (error)
 			goto done;
 		par_node = par_buf->b_addr;
-		dp->d_ops->node_hdr_from_disk(&par_hdr, par_node);
+		xfs_da3_node_hdr_from_disk(dp->i_mount, &par_hdr, par_node);
 		if (par_hdr.level != level) {
 			XFS_ERROR_REPORT("xfs_da_swap_lastblock(7)",
 					 XFS_ERRLEVEL_LOW, mp);
diff --git a/fs/xfs/libxfs/xfs_da_btree.h b/fs/xfs/libxfs/xfs_da_btree.h
index 02f7a21ab3a5..eb15b9e76bc8 100644
--- a/fs/xfs/libxfs/xfs_da_btree.h
+++ b/fs/xfs/libxfs/xfs_da_btree.h
@@ -215,6 +215,9 @@ enum xfs_dacmp xfs_da_compname(struct xfs_da_args *args,
 xfs_da_state_t *xfs_da_state_alloc(void);
 void xfs_da_state_free(xfs_da_state_t *state);
 
+void	xfs_da3_node_hdr_from_disk(struct xfs_mount *mp,
+		struct xfs_da3_icnode_hdr *to, struct xfs_da_intnode *from);
+
 extern struct kmem_zone *xfs_da_state_zone;
 extern const struct xfs_nameops xfs_default_nameops;
 
diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c
index 31bb250c1899..267aca857126 100644
--- a/fs/xfs/libxfs/xfs_da_format.c
+++ b/fs/xfs/libxfs/xfs_da_format.c
@@ -510,19 +510,6 @@ xfs_da3_node_tree_p(struct xfs_da_intnode *dap)
 	return ((struct xfs_da3_intnode *)dap)->__btree;
 }
 
-static void
-xfs_da2_node_hdr_from_disk(
-	struct xfs_da3_icnode_hdr	*to,
-	struct xfs_da_intnode		*from)
-{
-	ASSERT(from->hdr.info.magic == cpu_to_be16(XFS_DA_NODE_MAGIC));
-	to->forw = be32_to_cpu(from->hdr.info.forw);
-	to->back = be32_to_cpu(from->hdr.info.back);
-	to->magic = be16_to_cpu(from->hdr.info.magic);
-	to->count = be16_to_cpu(from->hdr.__count);
-	to->level = be16_to_cpu(from->hdr.__level);
-}
-
 static void
 xfs_da2_node_hdr_to_disk(
 	struct xfs_da_intnode		*to,
@@ -536,21 +523,6 @@ xfs_da2_node_hdr_to_disk(
 	to->hdr.__level = cpu_to_be16(from->level);
 }
 
-static void
-xfs_da3_node_hdr_from_disk(
-	struct xfs_da3_icnode_hdr	*to,
-	struct xfs_da_intnode		*from)
-{
-	struct xfs_da3_node_hdr *hdr3 = (struct xfs_da3_node_hdr *)from;
-
-	ASSERT(from->hdr.info.magic == cpu_to_be16(XFS_DA3_NODE_MAGIC));
-	to->forw = be32_to_cpu(hdr3->info.hdr.forw);
-	to->back = be32_to_cpu(hdr3->info.hdr.back);
-	to->magic = be16_to_cpu(hdr3->info.hdr.magic);
-	to->count = be16_to_cpu(hdr3->__count);
-	to->level = be16_to_cpu(hdr3->__level);
-}
-
 static void
 xfs_da3_node_hdr_to_disk(
 	struct xfs_da_intnode		*to,
@@ -727,7 +699,6 @@ static const struct xfs_dir_ops xfs_dir2_ops = {
 
 	.node_hdr_size = sizeof(struct xfs_da_node_hdr),
 	.node_hdr_to_disk = xfs_da2_node_hdr_to_disk,
-	.node_hdr_from_disk = xfs_da2_node_hdr_from_disk,
 	.node_tree_p = xfs_da2_node_tree_p,
 
 	.free_hdr_size = sizeof(struct xfs_dir2_free_hdr),
@@ -777,7 +748,6 @@ static const struct xfs_dir_ops xfs_dir2_ftype_ops = {
 
 	.node_hdr_size = sizeof(struct xfs_da_node_hdr),
 	.node_hdr_to_disk = xfs_da2_node_hdr_to_disk,
-	.node_hdr_from_disk = xfs_da2_node_hdr_from_disk,
 	.node_tree_p = xfs_da2_node_tree_p,
 
 	.free_hdr_size = sizeof(struct xfs_dir2_free_hdr),
@@ -827,7 +797,6 @@ static const struct xfs_dir_ops xfs_dir3_ops = {
 
 	.node_hdr_size = sizeof(struct xfs_da3_node_hdr),
 	.node_hdr_to_disk = xfs_da3_node_hdr_to_disk,
-	.node_hdr_from_disk = xfs_da3_node_hdr_from_disk,
 	.node_tree_p = xfs_da3_node_tree_p,
 
 	.free_hdr_size = sizeof(struct xfs_dir3_free_hdr),
@@ -842,14 +811,12 @@ static const struct xfs_dir_ops xfs_dir3_ops = {
 static const struct xfs_dir_ops xfs_dir2_nondir_ops = {
 	.node_hdr_size = sizeof(struct xfs_da_node_hdr),
 	.node_hdr_to_disk = xfs_da2_node_hdr_to_disk,
-	.node_hdr_from_disk = xfs_da2_node_hdr_from_disk,
 	.node_tree_p = xfs_da2_node_tree_p,
 };
 
 static const struct xfs_dir_ops xfs_dir3_nondir_ops = {
 	.node_hdr_size = sizeof(struct xfs_da3_node_hdr),
 	.node_hdr_to_disk = xfs_da3_node_hdr_to_disk,
-	.node_hdr_from_disk = xfs_da3_node_hdr_from_disk,
 	.node_tree_p = xfs_da3_node_tree_p,
 };
 
diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h
index e170792c0acc..573043f59c85 100644
--- a/fs/xfs/libxfs/xfs_dir2.h
+++ b/fs/xfs/libxfs/xfs_dir2.h
@@ -84,8 +84,6 @@ struct xfs_dir_ops {
 	int	node_hdr_size;
 	void	(*node_hdr_to_disk)(struct xfs_da_intnode *to,
 				    struct xfs_da3_icnode_hdr *from);
-	void	(*node_hdr_from_disk)(struct xfs_da3_icnode_hdr *to,
-				      struct xfs_da_intnode *from);
 	struct xfs_da_node_entry *
 		(*node_tree_p)(struct xfs_da_intnode *dap);
 
diff --git a/fs/xfs/scrub/dabtree.c b/fs/xfs/scrub/dabtree.c
index d1248c223c7f..be19a48716b7 100644
--- a/fs/xfs/scrub/dabtree.c
+++ b/fs/xfs/scrub/dabtree.c
@@ -410,7 +410,7 @@ xchk_da_btree_block(
 				XFS_BLFT_DA_NODE_BUF);
 		blk->magic = XFS_DA_NODE_MAGIC;
 		node = blk->bp->b_addr;
-		ip->d_ops->node_hdr_from_disk(&nodehdr, node);
+		xfs_da3_node_hdr_from_disk(ip->i_mount, &nodehdr, node);
 		btree = ip->d_ops->node_tree_p(node);
 		*pmaxrecs = nodehdr.count;
 		blk->hashval = be32_to_cpu(btree[*pmaxrecs - 1].hashval);
diff --git a/fs/xfs/xfs_attr_inactive.c b/fs/xfs/xfs_attr_inactive.c
index f83f11d929e4..c1ce06ccfab0 100644
--- a/fs/xfs/xfs_attr_inactive.c
+++ b/fs/xfs/xfs_attr_inactive.c
@@ -213,7 +213,7 @@ xfs_attr3_node_inactive(
 	}
 
 	node = bp->b_addr;
-	dp->d_ops->node_hdr_from_disk(&ichdr, node);
+	xfs_da3_node_hdr_from_disk(dp->i_mount, &ichdr, node);
 	parent_blkno = bp->b_bn;
 	if (!ichdr.count) {
 		xfs_trans_brelse(*trans, bp);
diff --git a/fs/xfs/xfs_attr_list.c b/fs/xfs/xfs_attr_list.c
index c02f22d50e45..5b5a3772ed24 100644
--- a/fs/xfs/xfs_attr_list.c
+++ b/fs/xfs/xfs_attr_list.c
@@ -240,7 +240,7 @@ xfs_attr_node_list_lookup(
 			goto out_corruptbuf;
 		}
 
-		dp->d_ops->node_hdr_from_disk(&nodehdr, node);
+		xfs_da3_node_hdr_from_disk(mp, &nodehdr, node);
 
 		/* Tree taller than we can handle; bail out! */
 		if (nodehdr.level >= XFS_DA_NODE_MAXDEPTH)
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 04/34] xfs: devirtualize ->node_hdr_to_disk
  2019-11-01 22:06 remove m_dirops Christoph Hellwig
                   ` (2 preceding siblings ...)
  2019-11-01 22:06 ` [PATCH 03/34] xfs: devirtualize ->node_hdr_from_disk Christoph Hellwig
@ 2019-11-01 22:06 ` Christoph Hellwig
  2019-11-04 18:39   ` Darrick J. Wong
  2019-11-01 22:06 ` [PATCH 05/34] xfs: add a btree entries pointer to struct xfs_da3_icnode_hdr Christoph Hellwig
                   ` (29 subsequent siblings)
  33 siblings, 1 reply; 81+ messages in thread
From: Christoph Hellwig @ 2019-11-01 22:06 UTC (permalink / raw)
  To: linux-xfs

Replace the ->node_hdr_to_disk dir ops method with a directly called
xfs_da_node_hdr_to_disk helper that takes care of the v4 vs v5
difference.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 fs/xfs/libxfs/xfs_attr_leaf.c |  2 +-
 fs/xfs/libxfs/xfs_da_btree.c  | 39 ++++++++++++++++++++++++++++-------
 fs/xfs/libxfs/xfs_da_btree.h  |  2 ++
 fs/xfs/libxfs/xfs_da_format.c | 34 ------------------------------
 fs/xfs/libxfs/xfs_dir2.h      |  2 --
 5 files changed, 35 insertions(+), 44 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_attr_leaf.c b/fs/xfs/libxfs/xfs_attr_leaf.c
index 131fef677896..1b0fbee21e14 100644
--- a/fs/xfs/libxfs/xfs_attr_leaf.c
+++ b/fs/xfs/libxfs/xfs_attr_leaf.c
@@ -1196,7 +1196,7 @@ xfs_attr3_leaf_to_node(
 	btree[0].hashval = entries[icleafhdr.count - 1].hashval;
 	btree[0].before = cpu_to_be32(blkno);
 	icnodehdr.count = 1;
-	dp->d_ops->node_hdr_to_disk(node, &icnodehdr);
+	xfs_da3_node_hdr_to_disk(dp->i_mount, node, &icnodehdr);
 	xfs_trans_log_buf(args->trans, bp1, 0, args->geo->blksize - 1);
 	error = 0;
 out:
diff --git a/fs/xfs/libxfs/xfs_da_btree.c b/fs/xfs/libxfs/xfs_da_btree.c
index f7ddc91ed099..462a245fdad7 100644
--- a/fs/xfs/libxfs/xfs_da_btree.c
+++ b/fs/xfs/libxfs/xfs_da_btree.c
@@ -135,6 +135,31 @@ xfs_da3_node_hdr_from_disk(
 	}
 }
 
+void
+xfs_da3_node_hdr_to_disk(
+	struct xfs_mount		*mp,
+	struct xfs_da_intnode		*to,
+	struct xfs_da3_icnode_hdr	*from)
+{
+	if (xfs_sb_version_hascrc(&mp->m_sb)) {
+		struct xfs_da3_intnode	*to3 = (struct xfs_da3_intnode *)to;
+
+		ASSERT(from->magic == XFS_DA3_NODE_MAGIC);
+		to3->hdr.info.hdr.forw = cpu_to_be32(from->forw);
+		to3->hdr.info.hdr.back = cpu_to_be32(from->back);
+		to3->hdr.info.hdr.magic = cpu_to_be16(from->magic);
+		to3->hdr.__count = cpu_to_be16(from->count);
+		to3->hdr.__level = cpu_to_be16(from->level);
+	} else {
+		ASSERT(from->magic == XFS_DA_NODE_MAGIC);
+		to->hdr.info.forw = cpu_to_be32(from->forw);
+		to->hdr.info.back = cpu_to_be32(from->back);
+		to->hdr.info.magic = cpu_to_be16(from->magic);
+		to->hdr.__count = cpu_to_be16(from->count);
+		to->hdr.__level = cpu_to_be16(from->level);
+	}
+}
+
 /*
  * Verify an xfs_da3_blkinfo structure. Note that the da3 fields are only
  * accessible on v5 filesystems. This header format is common across da node,
@@ -385,7 +410,7 @@ xfs_da3_node_create(
 	}
 	ichdr.level = level;
 
-	dp->d_ops->node_hdr_to_disk(node, &ichdr);
+	xfs_da3_node_hdr_to_disk(dp->i_mount, node, &ichdr);
 	xfs_trans_log_buf(tp, bp,
 		XFS_DA_LOGRANGE(node, &node->hdr, dp->d_ops->node_hdr_size));
 
@@ -666,7 +691,7 @@ xfs_da3_root_split(
 	btree[1].hashval = cpu_to_be32(blk2->hashval);
 	btree[1].before = cpu_to_be32(blk2->blkno);
 	nodehdr.count = 2;
-	dp->d_ops->node_hdr_to_disk(node, &nodehdr);
+	xfs_da3_node_hdr_to_disk(dp->i_mount, node, &nodehdr);
 
 #ifdef DEBUG
 	if (oldroot->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC) ||
@@ -891,11 +916,11 @@ xfs_da3_node_rebalance(
 	/*
 	 * Log header of node 1 and all current bits of node 2.
 	 */
-	dp->d_ops->node_hdr_to_disk(node1, &nodehdr1);
+	xfs_da3_node_hdr_to_disk(dp->i_mount, node1, &nodehdr1);
 	xfs_trans_log_buf(tp, blk1->bp,
 		XFS_DA_LOGRANGE(node1, &node1->hdr, dp->d_ops->node_hdr_size));
 
-	dp->d_ops->node_hdr_to_disk(node2, &nodehdr2);
+	xfs_da3_node_hdr_to_disk(dp->i_mount, node2, &nodehdr2);
 	xfs_trans_log_buf(tp, blk2->bp,
 		XFS_DA_LOGRANGE(node2, &node2->hdr,
 				dp->d_ops->node_hdr_size +
@@ -967,7 +992,7 @@ xfs_da3_node_add(
 				tmp + sizeof(*btree)));
 
 	nodehdr.count += 1;
-	dp->d_ops->node_hdr_to_disk(node, &nodehdr);
+	xfs_da3_node_hdr_to_disk(dp->i_mount, node, &nodehdr);
 	xfs_trans_log_buf(state->args->trans, oldblk->bp,
 		XFS_DA_LOGRANGE(node, &node->hdr, dp->d_ops->node_hdr_size));
 
@@ -1403,7 +1428,7 @@ xfs_da3_node_remove(
 	xfs_trans_log_buf(state->args->trans, drop_blk->bp,
 	    XFS_DA_LOGRANGE(node, &btree[index], sizeof(btree[index])));
 	nodehdr.count -= 1;
-	dp->d_ops->node_hdr_to_disk(node, &nodehdr);
+	xfs_da3_node_hdr_to_disk(dp->i_mount, node, &nodehdr);
 	xfs_trans_log_buf(state->args->trans, drop_blk->bp,
 	    XFS_DA_LOGRANGE(node, &node->hdr, dp->d_ops->node_hdr_size));
 
@@ -1475,7 +1500,7 @@ xfs_da3_node_unbalance(
 	memcpy(&save_btree[sindex], &drop_btree[0], tmp);
 	save_hdr.count += drop_hdr.count;
 
-	dp->d_ops->node_hdr_to_disk(save_node, &save_hdr);
+	xfs_da3_node_hdr_to_disk(dp->i_mount, save_node, &save_hdr);
 	xfs_trans_log_buf(tp, save_blk->bp,
 		XFS_DA_LOGRANGE(save_node, &save_node->hdr,
 				dp->d_ops->node_hdr_size));
diff --git a/fs/xfs/libxfs/xfs_da_btree.h b/fs/xfs/libxfs/xfs_da_btree.h
index eb15b9e76bc8..69ebf6a50d85 100644
--- a/fs/xfs/libxfs/xfs_da_btree.h
+++ b/fs/xfs/libxfs/xfs_da_btree.h
@@ -217,6 +217,8 @@ void xfs_da_state_free(xfs_da_state_t *state);
 
 void	xfs_da3_node_hdr_from_disk(struct xfs_mount *mp,
 		struct xfs_da3_icnode_hdr *to, struct xfs_da_intnode *from);
+void	xfs_da3_node_hdr_to_disk(struct xfs_mount *mp,
+		struct xfs_da_intnode *to, struct xfs_da3_icnode_hdr *from);
 
 extern struct kmem_zone *xfs_da_state_zone;
 extern const struct xfs_nameops xfs_default_nameops;
diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c
index 267aca857126..912096416a86 100644
--- a/fs/xfs/libxfs/xfs_da_format.c
+++ b/fs/xfs/libxfs/xfs_da_format.c
@@ -510,35 +510,6 @@ xfs_da3_node_tree_p(struct xfs_da_intnode *dap)
 	return ((struct xfs_da3_intnode *)dap)->__btree;
 }
 
-static void
-xfs_da2_node_hdr_to_disk(
-	struct xfs_da_intnode		*to,
-	struct xfs_da3_icnode_hdr	*from)
-{
-	ASSERT(from->magic == XFS_DA_NODE_MAGIC);
-	to->hdr.info.forw = cpu_to_be32(from->forw);
-	to->hdr.info.back = cpu_to_be32(from->back);
-	to->hdr.info.magic = cpu_to_be16(from->magic);
-	to->hdr.__count = cpu_to_be16(from->count);
-	to->hdr.__level = cpu_to_be16(from->level);
-}
-
-static void
-xfs_da3_node_hdr_to_disk(
-	struct xfs_da_intnode		*to,
-	struct xfs_da3_icnode_hdr	*from)
-{
-	struct xfs_da3_node_hdr *hdr3 = (struct xfs_da3_node_hdr *)to;
-
-	ASSERT(from->magic == XFS_DA3_NODE_MAGIC);
-	hdr3->info.hdr.forw = cpu_to_be32(from->forw);
-	hdr3->info.hdr.back = cpu_to_be32(from->back);
-	hdr3->info.hdr.magic = cpu_to_be16(from->magic);
-	hdr3->__count = cpu_to_be16(from->count);
-	hdr3->__level = cpu_to_be16(from->level);
-}
-
-
 /*
  * Directory free space block operations
  */
@@ -698,7 +669,6 @@ static const struct xfs_dir_ops xfs_dir2_ops = {
 	.leaf_ents_p = xfs_dir2_leaf_ents_p,
 
 	.node_hdr_size = sizeof(struct xfs_da_node_hdr),
-	.node_hdr_to_disk = xfs_da2_node_hdr_to_disk,
 	.node_tree_p = xfs_da2_node_tree_p,
 
 	.free_hdr_size = sizeof(struct xfs_dir2_free_hdr),
@@ -747,7 +717,6 @@ static const struct xfs_dir_ops xfs_dir2_ftype_ops = {
 	.leaf_ents_p = xfs_dir2_leaf_ents_p,
 
 	.node_hdr_size = sizeof(struct xfs_da_node_hdr),
-	.node_hdr_to_disk = xfs_da2_node_hdr_to_disk,
 	.node_tree_p = xfs_da2_node_tree_p,
 
 	.free_hdr_size = sizeof(struct xfs_dir2_free_hdr),
@@ -796,7 +765,6 @@ static const struct xfs_dir_ops xfs_dir3_ops = {
 	.leaf_ents_p = xfs_dir3_leaf_ents_p,
 
 	.node_hdr_size = sizeof(struct xfs_da3_node_hdr),
-	.node_hdr_to_disk = xfs_da3_node_hdr_to_disk,
 	.node_tree_p = xfs_da3_node_tree_p,
 
 	.free_hdr_size = sizeof(struct xfs_dir3_free_hdr),
@@ -810,13 +778,11 @@ static const struct xfs_dir_ops xfs_dir3_ops = {
 
 static const struct xfs_dir_ops xfs_dir2_nondir_ops = {
 	.node_hdr_size = sizeof(struct xfs_da_node_hdr),
-	.node_hdr_to_disk = xfs_da2_node_hdr_to_disk,
 	.node_tree_p = xfs_da2_node_tree_p,
 };
 
 static const struct xfs_dir_ops xfs_dir3_nondir_ops = {
 	.node_hdr_size = sizeof(struct xfs_da3_node_hdr),
-	.node_hdr_to_disk = xfs_da3_node_hdr_to_disk,
 	.node_tree_p = xfs_da3_node_tree_p,
 };
 
diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h
index 573043f59c85..c16efeae0f2b 100644
--- a/fs/xfs/libxfs/xfs_dir2.h
+++ b/fs/xfs/libxfs/xfs_dir2.h
@@ -82,8 +82,6 @@ struct xfs_dir_ops {
 		(*leaf_ents_p)(struct xfs_dir2_leaf *lp);
 
 	int	node_hdr_size;
-	void	(*node_hdr_to_disk)(struct xfs_da_intnode *to,
-				    struct xfs_da3_icnode_hdr *from);
 	struct xfs_da_node_entry *
 		(*node_tree_p)(struct xfs_da_intnode *dap);
 
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 05/34] xfs: add a btree entries pointer to struct xfs_da3_icnode_hdr
  2019-11-01 22:06 remove m_dirops Christoph Hellwig
                   ` (3 preceding siblings ...)
  2019-11-01 22:06 ` [PATCH 04/34] xfs: devirtualize ->node_hdr_to_disk Christoph Hellwig
@ 2019-11-01 22:06 ` Christoph Hellwig
  2019-11-04 19:52   ` Darrick J. Wong
  2019-11-01 22:06 ` [PATCH 06/34] xfs: move the node header size to struct xfs_da_geometry Christoph Hellwig
                   ` (28 subsequent siblings)
  33 siblings, 1 reply; 81+ messages in thread
From: Christoph Hellwig @ 2019-11-01 22:06 UTC (permalink / raw)
  To: linux-xfs

All but two callers of the ->node_tree_p dir operation already have a
xfs_da3_icnode_hdr from a previous call to xfs_da3_node_hdr_from_disk at
hand.  Add a pointer to the btree entries to struct xfs_da3_icnode_hdr
to clean up this pattern.  The two remaining callers now expand the
whole header as well, but that isn't very expensive and not in a super
hot path anyway.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 fs/xfs/libxfs/xfs_attr_leaf.c |  6 ++--
 fs/xfs/libxfs/xfs_da_btree.c  | 68 ++++++++++++++++-------------------
 fs/xfs/libxfs/xfs_da_btree.h  |  1 +
 fs/xfs/libxfs/xfs_da_format.c | 21 -----------
 fs/xfs/libxfs/xfs_dir2.h      |  2 --
 fs/xfs/scrub/dabtree.c        |  6 ++--
 fs/xfs/xfs_attr_inactive.c    | 34 +++++++++---------
 fs/xfs/xfs_attr_list.c        |  2 +-
 8 files changed, 55 insertions(+), 85 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_attr_leaf.c b/fs/xfs/libxfs/xfs_attr_leaf.c
index 1b0fbee21e14..2ba2d657d42d 100644
--- a/fs/xfs/libxfs/xfs_attr_leaf.c
+++ b/fs/xfs/libxfs/xfs_attr_leaf.c
@@ -1145,7 +1145,6 @@ xfs_attr3_leaf_to_node(
 	struct xfs_attr_leafblock *leaf;
 	struct xfs_attr3_icleaf_hdr icleafhdr;
 	struct xfs_attr_leaf_entry *entries;
-	struct xfs_da_node_entry *btree;
 	struct xfs_da3_icnode_hdr icnodehdr;
 	struct xfs_da_intnode	*node;
 	struct xfs_inode	*dp = args->dp;
@@ -1186,15 +1185,14 @@ xfs_attr3_leaf_to_node(
 		goto out;
 	node = bp1->b_addr;
 	xfs_da3_node_hdr_from_disk(mp, &icnodehdr, node);
-	btree = dp->d_ops->node_tree_p(node);
 
 	leaf = bp2->b_addr;
 	xfs_attr3_leaf_hdr_from_disk(args->geo, &icleafhdr, leaf);
 	entries = xfs_attr3_leaf_entryp(leaf);
 
 	/* both on-disk, don't endian-flip twice */
-	btree[0].hashval = entries[icleafhdr.count - 1].hashval;
-	btree[0].before = cpu_to_be32(blkno);
+	icnodehdr.btree[0].hashval = entries[icleafhdr.count - 1].hashval;
+	icnodehdr.btree[0].before = cpu_to_be32(blkno);
 	icnodehdr.count = 1;
 	xfs_da3_node_hdr_to_disk(dp->i_mount, node, &icnodehdr);
 	xfs_trans_log_buf(args->trans, bp1, 0, args->geo->blksize - 1);
diff --git a/fs/xfs/libxfs/xfs_da_btree.c b/fs/xfs/libxfs/xfs_da_btree.c
index 462a245fdad7..d8f062343bab 100644
--- a/fs/xfs/libxfs/xfs_da_btree.c
+++ b/fs/xfs/libxfs/xfs_da_btree.c
@@ -124,6 +124,7 @@ xfs_da3_node_hdr_from_disk(
 		to->magic = be16_to_cpu(from3->hdr.info.hdr.magic);
 		to->count = be16_to_cpu(from3->hdr.__count);
 		to->level = be16_to_cpu(from3->hdr.__level);
+		to->btree = from3->__btree;
 		ASSERT(to->magic == XFS_DA3_NODE_MAGIC);
 	} else {
 		to->forw = be32_to_cpu(from->hdr.info.forw);
@@ -131,6 +132,7 @@ xfs_da3_node_hdr_from_disk(
 		to->magic = be16_to_cpu(from->hdr.info.magic);
 		to->count = be16_to_cpu(from->hdr.__count);
 		to->level = be16_to_cpu(from->hdr.__level);
+		to->btree = from->__btree;
 		ASSERT(to->magic == XFS_DA_NODE_MAGIC);
 	}
 }
@@ -625,7 +627,7 @@ xfs_da3_root_split(
 		struct xfs_da3_icnode_hdr icnodehdr;
 
 		xfs_da3_node_hdr_from_disk(dp->i_mount, &icnodehdr, oldroot);
-		btree = dp->d_ops->node_tree_p(oldroot);
+		btree = icnodehdr.btree;
 		size = (int)((char *)&btree[icnodehdr.count] - (char *)oldroot);
 		level = icnodehdr.level;
 
@@ -685,7 +687,7 @@ xfs_da3_root_split(
 
 	node = bp->b_addr;
 	xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr, node);
-	btree = dp->d_ops->node_tree_p(node);
+	btree = nodehdr.btree;
 	btree[0].hashval = cpu_to_be32(blk1->hashval);
 	btree[0].before = cpu_to_be32(blk1->blkno);
 	btree[1].hashval = cpu_to_be32(blk2->hashval);
@@ -837,8 +839,8 @@ xfs_da3_node_rebalance(
 	node2 = blk2->bp->b_addr;
 	xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr1, node1);
 	xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr2, node2);
-	btree1 = dp->d_ops->node_tree_p(node1);
-	btree2 = dp->d_ops->node_tree_p(node2);
+	btree1 = nodehdr1.btree;
+	btree2 = nodehdr2.btree;
 
 	/*
 	 * Figure out how many entries need to move, and in which direction.
@@ -853,8 +855,8 @@ xfs_da3_node_rebalance(
 		node2 = tmpnode;
 		xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr1, node1);
 		xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr2, node2);
-		btree1 = dp->d_ops->node_tree_p(node1);
-		btree2 = dp->d_ops->node_tree_p(node2);
+		btree1 = nodehdr1.btree;
+		btree2 = nodehdr2.btree;
 		swap = 1;
 	}
 
@@ -935,8 +937,8 @@ xfs_da3_node_rebalance(
 		node2 = blk2->bp->b_addr;
 		xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr1, node1);
 		xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr2, node2);
-		btree1 = dp->d_ops->node_tree_p(node1);
-		btree2 = dp->d_ops->node_tree_p(node2);
+		btree1 = nodehdr1.btree;
+		btree2 = nodehdr2.btree;
 	}
 	blk1->hashval = be32_to_cpu(btree1[nodehdr1.count - 1].hashval);
 	blk2->hashval = be32_to_cpu(btree2[nodehdr2.count - 1].hashval);
@@ -969,7 +971,7 @@ xfs_da3_node_add(
 
 	node = oldblk->bp->b_addr;
 	xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr, node);
-	btree = dp->d_ops->node_tree_p(node);
+	btree = nodehdr.btree;
 
 	ASSERT(oldblk->index >= 0 && oldblk->index <= nodehdr.count);
 	ASSERT(newblk->blkno != 0);
@@ -1129,7 +1131,6 @@ xfs_da3_root_join(
 	xfs_dablk_t		child;
 	struct xfs_buf		*bp;
 	struct xfs_da3_icnode_hdr oldroothdr;
-	struct xfs_da_node_entry *btree;
 	int			error;
 	struct xfs_inode	*dp = state->args->dp;
 
@@ -1153,8 +1154,7 @@ xfs_da3_root_join(
 	 * Read in the (only) child block, then copy those bytes into
 	 * the root block's buffer and free the original child block.
 	 */
-	btree = dp->d_ops->node_tree_p(oldroot);
-	child = be32_to_cpu(btree[0].before);
+	child = be32_to_cpu(oldroothdr.btree[0].before);
 	ASSERT(child != 0);
 	error = xfs_da3_node_read(args->trans, dp, child, -1, &bp,
 					     args->whichfork);
@@ -1319,18 +1319,14 @@ xfs_da3_node_lasthash(
 	struct xfs_buf		*bp,
 	int			*count)
 {
-	struct xfs_da_intnode	 *node;
-	struct xfs_da_node_entry *btree;
 	struct xfs_da3_icnode_hdr nodehdr;
 
-	node = bp->b_addr;
-	xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr, node);
+	xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr, bp->b_addr);
 	if (count)
 		*count = nodehdr.count;
 	if (!nodehdr.count)
 		return 0;
-	btree = dp->d_ops->node_tree_p(node);
-	return be32_to_cpu(btree[nodehdr.count - 1].hashval);
+	return be32_to_cpu(nodehdr.btree[nodehdr.count - 1].hashval);
 }
 
 /*
@@ -1376,7 +1372,7 @@ xfs_da3_fixhashpath(
 
 		node = blk->bp->b_addr;
 		xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr, node);
-		btree = dp->d_ops->node_tree_p(node);
+		btree = nodehdr.btree;
 		if (be32_to_cpu(btree[blk->index].hashval) == lasthash)
 			break;
 		blk->hashval = lasthash;
@@ -1415,7 +1411,7 @@ xfs_da3_node_remove(
 	 * Copy over the offending entry, or just zero it out.
 	 */
 	index = drop_blk->index;
-	btree = dp->d_ops->node_tree_p(node);
+	btree = nodehdr.btree;
 	if (index < nodehdr.count - 1) {
 		tmp  = nodehdr.count - index - 1;
 		tmp *= (uint)sizeof(xfs_da_node_entry_t);
@@ -1465,8 +1461,8 @@ xfs_da3_node_unbalance(
 	save_node = save_blk->bp->b_addr;
 	xfs_da3_node_hdr_from_disk(dp->i_mount, &drop_hdr, drop_node);
 	xfs_da3_node_hdr_from_disk(dp->i_mount, &save_hdr, save_node);
-	drop_btree = dp->d_ops->node_tree_p(drop_node);
-	save_btree = dp->d_ops->node_tree_p(save_node);
+	drop_btree = drop_hdr.btree;
+	save_btree = save_hdr.btree;
 	tp = state->args->trans;
 
 	/*
@@ -1598,7 +1594,7 @@ xfs_da3_node_lookup_int(
 		 */
 		node = blk->bp->b_addr;
 		xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr, node);
-		btree = dp->d_ops->node_tree_p(node);
+		btree = nodehdr.btree;
 
 		/* Tree taller than we can handle; bail out! */
 		if (nodehdr.level >= XFS_DA_NODE_MAXDEPTH)
@@ -1727,8 +1723,8 @@ xfs_da3_node_order(
 	node2 = node2_bp->b_addr;
 	xfs_da3_node_hdr_from_disk(dp->i_mount, &node1hdr, node1);
 	xfs_da3_node_hdr_from_disk(dp->i_mount, &node2hdr, node2);
-	btree1 = dp->d_ops->node_tree_p(node1);
-	btree2 = dp->d_ops->node_tree_p(node2);
+	btree1 = node1hdr.btree;
+	btree2 = node2hdr.btree;
 
 	if (node1hdr.count > 0 && node2hdr.count > 0 &&
 	    ((be32_to_cpu(btree2[0].hashval) < be32_to_cpu(btree1[0].hashval)) ||
@@ -1925,7 +1921,6 @@ xfs_da3_path_shift(
 {
 	struct xfs_da_state_blk	*blk;
 	struct xfs_da_blkinfo	*info;
-	struct xfs_da_intnode	*node;
 	struct xfs_da_args	*args;
 	struct xfs_da_node_entry *btree;
 	struct xfs_da3_icnode_hdr nodehdr;
@@ -1948,17 +1943,16 @@ xfs_da3_path_shift(
 	ASSERT((path->active > 0) && (path->active < XFS_DA_NODE_MAXDEPTH));
 	level = (path->active-1) - 1;	/* skip bottom layer in path */
 	for (blk = &path->blk[level]; level >= 0; blk--, level--) {
-		node = blk->bp->b_addr;
-		xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr, node);
-		btree = dp->d_ops->node_tree_p(node);
+		xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr,
+					   blk->bp->b_addr);
 
 		if (forward && (blk->index < nodehdr.count - 1)) {
 			blk->index++;
-			blkno = be32_to_cpu(btree[blk->index].before);
+			blkno = be32_to_cpu(nodehdr.btree[blk->index].before);
 			break;
 		} else if (!forward && (blk->index > 0)) {
 			blk->index--;
-			blkno = be32_to_cpu(btree[blk->index].before);
+			blkno = be32_to_cpu(nodehdr.btree[blk->index].before);
 			break;
 		}
 	}
@@ -2009,9 +2003,9 @@ xfs_da3_path_shift(
 		case XFS_DA_NODE_MAGIC:
 		case XFS_DA3_NODE_MAGIC:
 			blk->magic = XFS_DA_NODE_MAGIC;
-			node = (xfs_da_intnode_t *)info;
-			xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr, node);
-			btree = dp->d_ops->node_tree_p(node);
+			xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr,
+						   bp->b_addr);
+			btree = nodehdr.btree;
 			blk->hashval = be32_to_cpu(btree[nodehdr.count - 1].hashval);
 			if (forward)
 				blk->index = 0;
@@ -2296,7 +2290,7 @@ xfs_da3_swap_lastblock(
 
 		dead_node = (xfs_da_intnode_t *)dead_info;
 		xfs_da3_node_hdr_from_disk(dp->i_mount, &deadhdr, dead_node);
-		btree = dp->d_ops->node_tree_p(dead_node);
+		btree = deadhdr.btree;
 		dead_level = deadhdr.level;
 		dead_hash = be32_to_cpu(btree[deadhdr.count - 1].hashval);
 	}
@@ -2363,7 +2357,7 @@ xfs_da3_swap_lastblock(
 			goto done;
 		}
 		level = par_hdr.level;
-		btree = dp->d_ops->node_tree_p(par_node);
+		btree = par_hdr.btree;
 		for (entno = 0;
 		     entno < par_hdr.count &&
 		     be32_to_cpu(btree[entno].hashval) < dead_hash;
@@ -2413,7 +2407,7 @@ xfs_da3_swap_lastblock(
 			error = -EFSCORRUPTED;
 			goto done;
 		}
-		btree = dp->d_ops->node_tree_p(par_node);
+		btree = par_hdr.btree;
 		entno = 0;
 	}
 	/*
diff --git a/fs/xfs/libxfs/xfs_da_btree.h b/fs/xfs/libxfs/xfs_da_btree.h
index 69ebf6a50d85..63ed45057fa5 100644
--- a/fs/xfs/libxfs/xfs_da_btree.h
+++ b/fs/xfs/libxfs/xfs_da_btree.h
@@ -135,6 +135,7 @@ struct xfs_da3_icnode_hdr {
 	uint16_t		magic;
 	uint16_t		count;
 	uint16_t		level;
+	struct xfs_da_node_entry *btree;
 };
 
 /*
diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c
index 912096416a86..f896d37c845f 100644
--- a/fs/xfs/libxfs/xfs_da_format.c
+++ b/fs/xfs/libxfs/xfs_da_format.c
@@ -494,22 +494,6 @@ xfs_dir3_leaf_hdr_to_disk(
 	hdr3->stale = cpu_to_be16(from->stale);
 }
 
-
-/*
- * Directory/Attribute Node block operations
- */
-static struct xfs_da_node_entry *
-xfs_da2_node_tree_p(struct xfs_da_intnode *dap)
-{
-	return dap->__btree;
-}
-
-static struct xfs_da_node_entry *
-xfs_da3_node_tree_p(struct xfs_da_intnode *dap)
-{
-	return ((struct xfs_da3_intnode *)dap)->__btree;
-}
-
 /*
  * Directory free space block operations
  */
@@ -669,7 +653,6 @@ static const struct xfs_dir_ops xfs_dir2_ops = {
 	.leaf_ents_p = xfs_dir2_leaf_ents_p,
 
 	.node_hdr_size = sizeof(struct xfs_da_node_hdr),
-	.node_tree_p = xfs_da2_node_tree_p,
 
 	.free_hdr_size = sizeof(struct xfs_dir2_free_hdr),
 	.free_hdr_to_disk = xfs_dir2_free_hdr_to_disk,
@@ -717,7 +700,6 @@ static const struct xfs_dir_ops xfs_dir2_ftype_ops = {
 	.leaf_ents_p = xfs_dir2_leaf_ents_p,
 
 	.node_hdr_size = sizeof(struct xfs_da_node_hdr),
-	.node_tree_p = xfs_da2_node_tree_p,
 
 	.free_hdr_size = sizeof(struct xfs_dir2_free_hdr),
 	.free_hdr_to_disk = xfs_dir2_free_hdr_to_disk,
@@ -765,7 +747,6 @@ static const struct xfs_dir_ops xfs_dir3_ops = {
 	.leaf_ents_p = xfs_dir3_leaf_ents_p,
 
 	.node_hdr_size = sizeof(struct xfs_da3_node_hdr),
-	.node_tree_p = xfs_da3_node_tree_p,
 
 	.free_hdr_size = sizeof(struct xfs_dir3_free_hdr),
 	.free_hdr_to_disk = xfs_dir3_free_hdr_to_disk,
@@ -778,12 +759,10 @@ static const struct xfs_dir_ops xfs_dir3_ops = {
 
 static const struct xfs_dir_ops xfs_dir2_nondir_ops = {
 	.node_hdr_size = sizeof(struct xfs_da_node_hdr),
-	.node_tree_p = xfs_da2_node_tree_p,
 };
 
 static const struct xfs_dir_ops xfs_dir3_nondir_ops = {
 	.node_hdr_size = sizeof(struct xfs_da3_node_hdr),
-	.node_tree_p = xfs_da3_node_tree_p,
 };
 
 /*
diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h
index c16efeae0f2b..6eee4c1b20da 100644
--- a/fs/xfs/libxfs/xfs_dir2.h
+++ b/fs/xfs/libxfs/xfs_dir2.h
@@ -82,8 +82,6 @@ struct xfs_dir_ops {
 		(*leaf_ents_p)(struct xfs_dir2_leaf *lp);
 
 	int	node_hdr_size;
-	struct xfs_da_node_entry *
-		(*node_tree_p)(struct xfs_da_intnode *dap);
 
 	int	free_hdr_size;
 	void	(*free_hdr_to_disk)(struct xfs_dir2_free *to,
diff --git a/fs/xfs/scrub/dabtree.c b/fs/xfs/scrub/dabtree.c
index be19a48716b7..52aa69743dfa 100644
--- a/fs/xfs/scrub/dabtree.c
+++ b/fs/xfs/scrub/dabtree.c
@@ -83,10 +83,12 @@ xchk_da_btree_node_entry(
 	int				level)
 {
 	struct xfs_da_state_blk		*blk = &ds->state->path.blk[level];
+	struct xfs_da3_icnode_hdr	hdr;
 
 	ASSERT(blk->magic == XFS_DA_NODE_MAGIC);
 
-	return (void *)ds->dargs.dp->d_ops->node_tree_p(blk->bp->b_addr) +
+	xfs_da3_node_hdr_from_disk(ds->sc->mp, &hdr, blk->bp->b_addr);
+	return (void *)hdr.btree +
 		(blk->index * sizeof(struct xfs_da_node_entry));
 }
 
@@ -411,7 +413,7 @@ xchk_da_btree_block(
 		blk->magic = XFS_DA_NODE_MAGIC;
 		node = blk->bp->b_addr;
 		xfs_da3_node_hdr_from_disk(ip->i_mount, &nodehdr, node);
-		btree = ip->d_ops->node_tree_p(node);
+		btree = nodehdr.btree;
 		*pmaxrecs = nodehdr.count;
 		blk->hashval = be32_to_cpu(btree[*pmaxrecs - 1].hashval);
 		if (level == 0) {
diff --git a/fs/xfs/xfs_attr_inactive.c b/fs/xfs/xfs_attr_inactive.c
index c1ce06ccfab0..f6d8967f0a8e 100644
--- a/fs/xfs/xfs_attr_inactive.c
+++ b/fs/xfs/xfs_attr_inactive.c
@@ -190,19 +190,17 @@ xfs_attr3_leaf_inactive(
  */
 STATIC int
 xfs_attr3_node_inactive(
-	struct xfs_trans **trans,
-	struct xfs_inode *dp,
-	struct xfs_buf	*bp,
-	int		level)
+	struct xfs_trans	**trans,
+	struct xfs_inode	*dp,
+	struct xfs_buf		*bp,
+	int			level)
 {
-	xfs_da_blkinfo_t *info;
-	xfs_da_intnode_t *node;
-	xfs_dablk_t child_fsb;
-	xfs_daddr_t parent_blkno, child_blkno;
-	int error, i;
-	struct xfs_buf *child_bp;
-	struct xfs_da_node_entry *btree;
+	struct xfs_da_blkinfo	*info;
+	xfs_dablk_t		child_fsb;
+	xfs_daddr_t		parent_blkno, child_blkno;
+	struct xfs_buf		*child_bp;
 	struct xfs_da3_icnode_hdr ichdr;
+	int			error, i;
 
 	/*
 	 * Since this code is recursive (gasp!) we must protect ourselves.
@@ -212,15 +210,13 @@ xfs_attr3_node_inactive(
 		return -EFSCORRUPTED;
 	}
 
-	node = bp->b_addr;
-	xfs_da3_node_hdr_from_disk(dp->i_mount, &ichdr, node);
+	xfs_da3_node_hdr_from_disk(dp->i_mount, &ichdr, bp->b_addr);
 	parent_blkno = bp->b_bn;
 	if (!ichdr.count) {
 		xfs_trans_brelse(*trans, bp);
 		return 0;
 	}
-	btree = dp->d_ops->node_tree_p(node);
-	child_fsb = be32_to_cpu(btree[0].before);
+	child_fsb = be32_to_cpu(ichdr.btree[0].before);
 	xfs_trans_brelse(*trans, bp);	/* no locks for later trans */
 
 	/*
@@ -279,13 +275,15 @@ xfs_attr3_node_inactive(
 		 * child block number.
 		 */
 		if (i + 1 < ichdr.count) {
+			struct xfs_da3_icnode_hdr phdr;
+
 			error = xfs_da3_node_read(*trans, dp, 0, parent_blkno,
 						 &bp, XFS_ATTR_FORK);
 			if (error)
 				return error;
-			node = bp->b_addr;
-			btree = dp->d_ops->node_tree_p(node);
-			child_fsb = be32_to_cpu(btree[i + 1].before);
+			xfs_da3_node_hdr_from_disk(dp->i_mount, &phdr,
+						  bp->b_addr);
+			child_fsb = be32_to_cpu(phdr.btree[i + 1].before);
 			xfs_trans_brelse(*trans, bp);
 		}
 		/*
diff --git a/fs/xfs/xfs_attr_list.c b/fs/xfs/xfs_attr_list.c
index 5b5a3772ed24..032920952aa2 100644
--- a/fs/xfs/xfs_attr_list.c
+++ b/fs/xfs/xfs_attr_list.c
@@ -254,7 +254,7 @@ xfs_attr_node_list_lookup(
 		else
 			expected_level--;
 
-		btree = dp->d_ops->node_tree_p(node);
+		btree = nodehdr.btree;
 		for (i = 0; i < nodehdr.count; btree++, i++) {
 			if (cursor->hashval <= be32_to_cpu(btree->hashval)) {
 				cursor->blkno = be32_to_cpu(btree->before);
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 06/34] xfs: move the node header size to struct xfs_da_geometry
  2019-11-01 22:06 remove m_dirops Christoph Hellwig
                   ` (4 preceding siblings ...)
  2019-11-01 22:06 ` [PATCH 05/34] xfs: add a btree entries pointer to struct xfs_da3_icnode_hdr Christoph Hellwig
@ 2019-11-01 22:06 ` Christoph Hellwig
  2019-11-04 19:58   ` Darrick J. Wong
  2019-11-01 22:06 ` [PATCH 07/34] xfs: devirtualize ->leaf_hdr_from_disk Christoph Hellwig
                   ` (27 subsequent siblings)
  33 siblings, 1 reply; 81+ messages in thread
From: Christoph Hellwig @ 2019-11-01 22:06 UTC (permalink / raw)
  To: linux-xfs

Move the node header size field to struct xfs_da_geometry, and remove
the now unused non-directory dir ops infrastructure.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 fs/xfs/libxfs/xfs_da_btree.c  | 14 ++++++++------
 fs/xfs/libxfs/xfs_da_btree.h  |  1 +
 fs/xfs/libxfs/xfs_da_format.c | 28 ----------------------------
 fs/xfs/libxfs/xfs_dir2.c      | 12 +++++++-----
 fs/xfs/libxfs/xfs_dir2.h      |  4 ----
 fs/xfs/xfs_iops.c             |  1 -
 fs/xfs/xfs_mount.h            |  1 -
 7 files changed, 16 insertions(+), 45 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_da_btree.c b/fs/xfs/libxfs/xfs_da_btree.c
index d8f062343bab..26ad79d96205 100644
--- a/fs/xfs/libxfs/xfs_da_btree.c
+++ b/fs/xfs/libxfs/xfs_da_btree.c
@@ -414,7 +414,7 @@ xfs_da3_node_create(
 
 	xfs_da3_node_hdr_to_disk(dp->i_mount, node, &ichdr);
 	xfs_trans_log_buf(tp, bp,
-		XFS_DA_LOGRANGE(node, &node->hdr, dp->d_ops->node_hdr_size));
+		XFS_DA_LOGRANGE(node, &node->hdr, args->geo->node_hdr_size));
 
 	*bpp = bp;
 	return 0;
@@ -920,12 +920,13 @@ xfs_da3_node_rebalance(
 	 */
 	xfs_da3_node_hdr_to_disk(dp->i_mount, node1, &nodehdr1);
 	xfs_trans_log_buf(tp, blk1->bp,
-		XFS_DA_LOGRANGE(node1, &node1->hdr, dp->d_ops->node_hdr_size));
+		XFS_DA_LOGRANGE(node1, &node1->hdr,
+				state->args->geo->node_hdr_size));
 
 	xfs_da3_node_hdr_to_disk(dp->i_mount, node2, &nodehdr2);
 	xfs_trans_log_buf(tp, blk2->bp,
 		XFS_DA_LOGRANGE(node2, &node2->hdr,
-				dp->d_ops->node_hdr_size +
+				state->args->geo->node_hdr_size +
 				(sizeof(btree2[0]) * nodehdr2.count)));
 
 	/*
@@ -996,7 +997,8 @@ xfs_da3_node_add(
 	nodehdr.count += 1;
 	xfs_da3_node_hdr_to_disk(dp->i_mount, node, &nodehdr);
 	xfs_trans_log_buf(state->args->trans, oldblk->bp,
-		XFS_DA_LOGRANGE(node, &node->hdr, dp->d_ops->node_hdr_size));
+		XFS_DA_LOGRANGE(node, &node->hdr,
+				state->args->geo->node_hdr_size));
 
 	/*
 	 * Copy the last hash value from the oldblk to propagate upwards.
@@ -1426,7 +1428,7 @@ xfs_da3_node_remove(
 	nodehdr.count -= 1;
 	xfs_da3_node_hdr_to_disk(dp->i_mount, node, &nodehdr);
 	xfs_trans_log_buf(state->args->trans, drop_blk->bp,
-	    XFS_DA_LOGRANGE(node, &node->hdr, dp->d_ops->node_hdr_size));
+	    XFS_DA_LOGRANGE(node, &node->hdr, state->args->geo->node_hdr_size));
 
 	/*
 	 * Copy the last hash value from the block to propagate upwards.
@@ -1499,7 +1501,7 @@ xfs_da3_node_unbalance(
 	xfs_da3_node_hdr_to_disk(dp->i_mount, save_node, &save_hdr);
 	xfs_trans_log_buf(tp, save_blk->bp,
 		XFS_DA_LOGRANGE(save_node, &save_node->hdr,
-				dp->d_ops->node_hdr_size));
+				state->args->geo->node_hdr_size));
 
 	/*
 	 * Save the last hashval in the remaining block for upward propagation.
diff --git a/fs/xfs/libxfs/xfs_da_btree.h b/fs/xfs/libxfs/xfs_da_btree.h
index 63ed45057fa5..11b2d75f83ad 100644
--- a/fs/xfs/libxfs/xfs_da_btree.h
+++ b/fs/xfs/libxfs/xfs_da_btree.h
@@ -22,6 +22,7 @@ struct xfs_da_geometry {
 	int		fsbcount;	/* da block size in filesystem blocks */
 	uint8_t		fsblog;		/* log2 of _filesystem_ block size */
 	uint8_t		blklog;		/* log2 of da block size */
+	int		node_hdr_size;	/* danode header size in bytes */
 	uint		node_ents;	/* # of entries in a danode */
 	int		magicpct;	/* 37% of block size in bytes */
 	xfs_dablk_t	datablk;	/* blockno of dir data v2 */
diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c
index f896d37c845f..68dff1de61e9 100644
--- a/fs/xfs/libxfs/xfs_da_format.c
+++ b/fs/xfs/libxfs/xfs_da_format.c
@@ -652,8 +652,6 @@ static const struct xfs_dir_ops xfs_dir2_ops = {
 	.leaf_max_ents = xfs_dir2_max_leaf_ents,
 	.leaf_ents_p = xfs_dir2_leaf_ents_p,
 
-	.node_hdr_size = sizeof(struct xfs_da_node_hdr),
-
 	.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,
@@ -699,8 +697,6 @@ static const struct xfs_dir_ops xfs_dir2_ftype_ops = {
 	.leaf_max_ents = xfs_dir2_max_leaf_ents,
 	.leaf_ents_p = xfs_dir2_leaf_ents_p,
 
-	.node_hdr_size = sizeof(struct xfs_da_node_hdr),
-
 	.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,
@@ -746,8 +742,6 @@ static const struct xfs_dir_ops xfs_dir3_ops = {
 	.leaf_max_ents = xfs_dir3_max_leaf_ents,
 	.leaf_ents_p = xfs_dir3_leaf_ents_p,
 
-	.node_hdr_size = sizeof(struct xfs_da3_node_hdr),
-
 	.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,
@@ -757,14 +751,6 @@ static const struct xfs_dir_ops xfs_dir3_ops = {
 	.db_to_fdindex = xfs_dir3_db_to_fdindex,
 };
 
-static const struct xfs_dir_ops xfs_dir2_nondir_ops = {
-	.node_hdr_size = sizeof(struct xfs_da_node_hdr),
-};
-
-static const struct xfs_dir_ops xfs_dir3_nondir_ops = {
-	.node_hdr_size = sizeof(struct xfs_da3_node_hdr),
-};
-
 /*
  * Return the ops structure according to the current config.  If we are passed
  * an inode, then that overrides the default config we use which is based on
@@ -785,17 +771,3 @@ xfs_dir_get_ops(
 		return &xfs_dir2_ftype_ops;
 	return &xfs_dir2_ops;
 }
-
-const struct xfs_dir_ops *
-xfs_nondir_get_ops(
-	struct xfs_mount	*mp,
-	struct xfs_inode	*dp)
-{
-	if (dp)
-		return dp->d_ops;
-	if (mp->m_nondir_inode_ops)
-		return mp->m_nondir_inode_ops;
-	if (xfs_sb_version_hascrc(&mp->m_sb))
-		return &xfs_dir3_nondir_ops;
-	return &xfs_dir2_nondir_ops;
-}
diff --git a/fs/xfs/libxfs/xfs_dir2.c b/fs/xfs/libxfs/xfs_dir2.c
index 867c5dee0751..aef20ec6e140 100644
--- a/fs/xfs/libxfs/xfs_dir2.c
+++ b/fs/xfs/libxfs/xfs_dir2.c
@@ -99,16 +99,13 @@ xfs_da_mount(
 	struct xfs_mount	*mp)
 {
 	struct xfs_da_geometry	*dageo;
-	int			nodehdr_size;
 
 
 	ASSERT(mp->m_sb.sb_versionnum & XFS_SB_VERSION_DIRV2BIT);
 	ASSERT(xfs_dir2_dirblock_bytes(&mp->m_sb) <= XFS_MAX_BLOCKSIZE);
 
 	mp->m_dir_inode_ops = xfs_dir_get_ops(mp, NULL);
-	mp->m_nondir_inode_ops = xfs_nondir_get_ops(mp, NULL);
 
-	nodehdr_size = mp->m_dir_inode_ops->node_hdr_size;
 	mp->m_dir_geo = kmem_zalloc(sizeof(struct xfs_da_geometry),
 				    KM_MAYFAIL);
 	mp->m_attr_geo = kmem_zalloc(sizeof(struct xfs_da_geometry),
@@ -125,6 +122,10 @@ xfs_da_mount(
 	dageo->fsblog = mp->m_sb.sb_blocklog;
 	dageo->blksize = xfs_dir2_dirblock_bytes(&mp->m_sb);
 	dageo->fsbcount = 1 << mp->m_sb.sb_dirblklog;
+	if (xfs_sb_version_hascrc(&mp->m_sb))
+		dageo->node_hdr_size = sizeof(struct xfs_da3_node_hdr);
+	else
+		dageo->node_hdr_size = sizeof(struct xfs_da_node_hdr);
 
 	/*
 	 * Now we've set up the block conversion variables, we can calculate the
@@ -133,7 +134,7 @@ xfs_da_mount(
 	dageo->datablk = xfs_dir2_byte_to_da(dageo, XFS_DIR2_DATA_OFFSET);
 	dageo->leafblk = xfs_dir2_byte_to_da(dageo, XFS_DIR2_LEAF_OFFSET);
 	dageo->freeblk = xfs_dir2_byte_to_da(dageo, XFS_DIR2_FREE_OFFSET);
-	dageo->node_ents = (dageo->blksize - nodehdr_size) /
+	dageo->node_ents = (dageo->blksize - dageo->node_hdr_size) /
 				(uint)sizeof(xfs_da_node_entry_t);
 	dageo->magicpct = (dageo->blksize * 37) / 100;
 
@@ -143,7 +144,8 @@ xfs_da_mount(
 	dageo->fsblog = mp->m_sb.sb_blocklog;
 	dageo->blksize = 1 << dageo->blklog;
 	dageo->fsbcount = 1;
-	dageo->node_ents = (dageo->blksize - nodehdr_size) /
+	dageo->node_hdr_size = mp->m_dir_geo->node_hdr_size;
+	dageo->node_ents = (dageo->blksize - dageo->node_hdr_size) /
 				(uint)sizeof(xfs_da_node_entry_t);
 	dageo->magicpct = (dageo->blksize * 37) / 100;
 
diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h
index 6eee4c1b20da..87fe876e90ed 100644
--- a/fs/xfs/libxfs/xfs_dir2.h
+++ b/fs/xfs/libxfs/xfs_dir2.h
@@ -81,8 +81,6 @@ struct xfs_dir_ops {
 	struct xfs_dir2_leaf_entry *
 		(*leaf_ents_p)(struct xfs_dir2_leaf *lp);
 
-	int	node_hdr_size;
-
 	int	free_hdr_size;
 	void	(*free_hdr_to_disk)(struct xfs_dir2_free *to,
 				    struct xfs_dir3_icfree_hdr *from);
@@ -98,8 +96,6 @@ struct xfs_dir_ops {
 
 extern const struct xfs_dir_ops *
 	xfs_dir_get_ops(struct xfs_mount *mp, struct xfs_inode *dp);
-extern const struct xfs_dir_ops *
-	xfs_nondir_get_ops(struct xfs_mount *mp, struct xfs_inode *dp);
 
 /*
  * Generic directory interface routines
diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c
index 18e45e3a3f9f..40d4495e013c 100644
--- a/fs/xfs/xfs_iops.c
+++ b/fs/xfs/xfs_iops.c
@@ -1319,7 +1319,6 @@ xfs_setup_inode(
 		lockdep_set_class(&ip->i_lock.mr_lock, &xfs_dir_ilock_class);
 		ip->d_ops = ip->i_mount->m_dir_inode_ops;
 	} else {
-		ip->d_ops = ip->i_mount->m_nondir_inode_ops;
 		lockdep_set_class(&ip->i_lock.mr_lock, &xfs_nondir_ilock_class);
 	}
 
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
index a46cb3fd24b1..3ddc5f4d1053 100644
--- a/fs/xfs/xfs_mount.h
+++ b/fs/xfs/xfs_mount.h
@@ -159,7 +159,6 @@ typedef struct xfs_mount {
 	uint8_t			m_sectbb_log;	/* sectlog - BBSHIFT */
 	const struct xfs_nameops *m_dirnameops;	/* vector of dir name ops */
 	const struct xfs_dir_ops *m_dir_inode_ops; /* vector of dir inode ops */
-	const struct xfs_dir_ops *m_nondir_inode_ops; /* !dir inode ops */
 	uint			m_chsize;	/* size of next field */
 	atomic_t		m_active_trans;	/* number trans frozen */
 	struct xfs_mru_cache	*m_filestream;  /* per-mount filestream data */
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 07/34] xfs: devirtualize ->leaf_hdr_from_disk
  2019-11-01 22:06 remove m_dirops Christoph Hellwig
                   ` (5 preceding siblings ...)
  2019-11-01 22:06 ` [PATCH 06/34] xfs: move the node header size to struct xfs_da_geometry Christoph Hellwig
@ 2019-11-01 22:06 ` Christoph Hellwig
  2019-11-04 19:59   ` Darrick J. Wong
  2019-11-01 22:06 ` [PATCH 08/34] xfs: devirtualize ->leaf_hdr_to_disk Christoph Hellwig
                   ` (26 subsequent siblings)
  33 siblings, 1 reply; 81+ messages in thread
From: Christoph Hellwig @ 2019-11-01 22:06 UTC (permalink / raw)
  To: linux-xfs

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

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 fs/xfs/libxfs/xfs_da_btree.c   |  5 ++--
 fs/xfs/libxfs/xfs_da_format.c  | 35 --------------------------
 fs/xfs/libxfs/xfs_dir2.h       |  2 --
 fs/xfs/libxfs/xfs_dir2_block.c |  2 +-
 fs/xfs/libxfs/xfs_dir2_leaf.c  | 45 ++++++++++++++++++++++++++++------
 fs/xfs/libxfs/xfs_dir2_node.c  | 28 ++++++++++-----------
 fs/xfs/libxfs/xfs_dir2_priv.h  |  2 ++
 fs/xfs/scrub/dir.c             |  2 +-
 8 files changed, 58 insertions(+), 63 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_da_btree.c b/fs/xfs/libxfs/xfs_da_btree.c
index 26ad79d96205..aeb1884fd8c7 100644
--- a/fs/xfs/libxfs/xfs_da_btree.c
+++ b/fs/xfs/libxfs/xfs_da_btree.c
@@ -641,7 +641,7 @@ xfs_da3_root_split(
 		struct xfs_dir2_leaf_entry *ents;
 
 		leaf = (xfs_dir2_leaf_t *)oldroot;
-		dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf);
+		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 ||
@@ -2283,7 +2283,8 @@ xfs_da3_swap_lastblock(
 		struct xfs_dir2_leaf_entry *ents;
 
 		dead_leaf2 = (xfs_dir2_leaf_t *)dead_info;
-		dp->d_ops->leaf_hdr_from_disk(&leafhdr, dead_leaf2);
+		xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &leafhdr,
+					    dead_leaf2);
 		ents = dp->d_ops->leaf_ents_p(dead_leaf2);
 		dead_level = 0;
 		dead_hash = be32_to_cpu(ents[leafhdr.count - 1].hashval);
diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c
index 68dff1de61e9..c848cab41be5 100644
--- a/fs/xfs/libxfs/xfs_da_format.c
+++ b/fs/xfs/libxfs/xfs_da_format.c
@@ -430,21 +430,6 @@ xfs_dir3_leaf_ents_p(struct xfs_dir2_leaf *lp)
 	return ((struct xfs_dir3_leaf *)lp)->__ents;
 }
 
-static void
-xfs_dir2_leaf_hdr_from_disk(
-	struct xfs_dir3_icleaf_hdr	*to,
-	struct xfs_dir2_leaf		*from)
-{
-	to->forw = be32_to_cpu(from->hdr.info.forw);
-	to->back = be32_to_cpu(from->hdr.info.back);
-	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);
-
-	ASSERT(to->magic == XFS_DIR2_LEAF1_MAGIC ||
-	       to->magic == XFS_DIR2_LEAFN_MAGIC);
-}
-
 static void
 xfs_dir2_leaf_hdr_to_disk(
 	struct xfs_dir2_leaf		*to,
@@ -460,23 +445,6 @@ xfs_dir2_leaf_hdr_to_disk(
 	to->hdr.stale = cpu_to_be16(from->stale);
 }
 
-static void
-xfs_dir3_leaf_hdr_from_disk(
-	struct xfs_dir3_icleaf_hdr	*to,
-	struct xfs_dir2_leaf		*from)
-{
-	struct xfs_dir3_leaf_hdr *hdr3 = (struct xfs_dir3_leaf_hdr *)from;
-
-	to->forw = be32_to_cpu(hdr3->info.hdr.forw);
-	to->back = be32_to_cpu(hdr3->info.hdr.back);
-	to->magic = be16_to_cpu(hdr3->info.hdr.magic);
-	to->count = be16_to_cpu(hdr3->count);
-	to->stale = be16_to_cpu(hdr3->stale);
-
-	ASSERT(to->magic == XFS_DIR3_LEAF1_MAGIC ||
-	       to->magic == XFS_DIR3_LEAFN_MAGIC);
-}
-
 static void
 xfs_dir3_leaf_hdr_to_disk(
 	struct xfs_dir2_leaf		*to,
@@ -648,7 +616,6 @@ static const struct xfs_dir_ops xfs_dir2_ops = {
 
 	.leaf_hdr_size = sizeof(struct xfs_dir2_leaf_hdr),
 	.leaf_hdr_to_disk = xfs_dir2_leaf_hdr_to_disk,
-	.leaf_hdr_from_disk = xfs_dir2_leaf_hdr_from_disk,
 	.leaf_max_ents = xfs_dir2_max_leaf_ents,
 	.leaf_ents_p = xfs_dir2_leaf_ents_p,
 
@@ -693,7 +660,6 @@ static const struct xfs_dir_ops xfs_dir2_ftype_ops = {
 
 	.leaf_hdr_size = sizeof(struct xfs_dir2_leaf_hdr),
 	.leaf_hdr_to_disk = xfs_dir2_leaf_hdr_to_disk,
-	.leaf_hdr_from_disk = xfs_dir2_leaf_hdr_from_disk,
 	.leaf_max_ents = xfs_dir2_max_leaf_ents,
 	.leaf_ents_p = xfs_dir2_leaf_ents_p,
 
@@ -738,7 +704,6 @@ static const struct xfs_dir_ops xfs_dir3_ops = {
 
 	.leaf_hdr_size = sizeof(struct xfs_dir3_leaf_hdr),
 	.leaf_hdr_to_disk = xfs_dir3_leaf_hdr_to_disk,
-	.leaf_hdr_from_disk = xfs_dir3_leaf_hdr_from_disk,
 	.leaf_max_ents = xfs_dir3_max_leaf_ents,
 	.leaf_ents_p = xfs_dir3_leaf_ents_p,
 
diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h
index 87fe876e90ed..74c592496bf0 100644
--- a/fs/xfs/libxfs/xfs_dir2.h
+++ b/fs/xfs/libxfs/xfs_dir2.h
@@ -75,8 +75,6 @@ struct xfs_dir_ops {
 	int	leaf_hdr_size;
 	void	(*leaf_hdr_to_disk)(struct xfs_dir2_leaf *to,
 				    struct xfs_dir3_icleaf_hdr *from);
-	void	(*leaf_hdr_from_disk)(struct xfs_dir3_icleaf_hdr *to,
-				      struct xfs_dir2_leaf *from);
 	int	(*leaf_max_ents)(struct xfs_da_geometry *geo);
 	struct xfs_dir2_leaf_entry *
 		(*leaf_ents_p)(struct xfs_dir2_leaf *lp);
diff --git a/fs/xfs/libxfs/xfs_dir2_block.c b/fs/xfs/libxfs/xfs_dir2_block.c
index 49e4bc39e7bb..e6ed90a6f19b 100644
--- a/fs/xfs/libxfs/xfs_dir2_block.c
+++ b/fs/xfs/libxfs/xfs_dir2_block.c
@@ -923,7 +923,7 @@ xfs_dir2_leaf_to_block(
 	tp = args->trans;
 	mp = dp->i_mount;
 	leaf = lbp->b_addr;
-	dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf);
+	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);
 
diff --git a/fs/xfs/libxfs/xfs_dir2_leaf.c b/fs/xfs/libxfs/xfs_dir2_leaf.c
index a53e4585a2f3..137ffd0a538b 100644
--- a/fs/xfs/libxfs/xfs_dir2_leaf.c
+++ b/fs/xfs/libxfs/xfs_dir2_leaf.c
@@ -30,6 +30,35 @@ static void xfs_dir3_leaf_log_bests(struct xfs_da_args *args,
 static void xfs_dir3_leaf_log_tail(struct xfs_da_args *args,
 				   struct xfs_buf *bp);
 
+void
+xfs_dir2_leaf_hdr_from_disk(
+	struct xfs_mount		*mp,
+	struct xfs_dir3_icleaf_hdr	*to,
+	struct xfs_dir2_leaf		*from)
+{
+	if (xfs_sb_version_hascrc(&mp->m_sb)) {
+		struct xfs_dir3_leaf *from3 = (struct xfs_dir3_leaf *)from;
+
+		to->forw = be32_to_cpu(from3->hdr.info.hdr.forw);
+		to->back = be32_to_cpu(from3->hdr.info.hdr.back);
+		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);
+
+		ASSERT(to->magic == XFS_DIR3_LEAF1_MAGIC ||
+		       to->magic == XFS_DIR3_LEAFN_MAGIC);
+	} else {
+		to->forw = be32_to_cpu(from->hdr.info.forw);
+		to->back = be32_to_cpu(from->hdr.info.back);
+		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);
+
+		ASSERT(to->magic == XFS_DIR2_LEAF1_MAGIC ||
+		       to->magic == XFS_DIR2_LEAFN_MAGIC);
+	}
+}
+
 /*
  * Check the internal consistency of a leaf1 block.
  * Pop an assert if something is wrong.
@@ -43,7 +72,7 @@ xfs_dir3_leaf1_check(
 	struct xfs_dir2_leaf	*leaf = bp->b_addr;
 	struct xfs_dir3_icleaf_hdr leafhdr;
 
-	dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf);
+	xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &leafhdr, leaf);
 
 	if (leafhdr.magic == XFS_DIR3_LEAF1_MAGIC) {
 		struct xfs_dir3_leaf_hdr *leaf3 = bp->b_addr;
@@ -96,7 +125,7 @@ xfs_dir3_leaf_check_int(
 	ops = xfs_dir_get_ops(mp, dp);
 
 	if (!hdr) {
-		ops->leaf_hdr_from_disk(&leafhdr, leaf);
+		xfs_dir2_leaf_hdr_from_disk(mp, &leafhdr, leaf);
 		hdr = &leafhdr;
 	}
 
@@ -381,7 +410,7 @@ xfs_dir2_block_to_leaf(
 	/*
 	 * Set the counts in the leaf header.
 	 */
-	dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf);
+	xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &leafhdr, leaf);
 	leafhdr.count = be32_to_cpu(btp->count);
 	leafhdr.stale = be32_to_cpu(btp->stale);
 	dp->d_ops->leaf_hdr_to_disk(leaf, &leafhdr);
@@ -608,7 +637,7 @@ xfs_dir2_leaf_addname(
 	leaf = lbp->b_addr;
 	ltp = xfs_dir2_leaf_tail_p(args->geo, leaf);
 	ents = dp->d_ops->leaf_ents_p(leaf);
-	dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf);
+	xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &leafhdr, leaf);
 	bestsp = xfs_dir2_leaf_bests_p(ltp);
 	length = dp->d_ops->data_entsize(args->namelen);
 
@@ -1197,7 +1226,7 @@ xfs_dir2_leaf_lookup_int(
 	leaf = lbp->b_addr;
 	xfs_dir3_leaf_check(dp, lbp);
 	ents = dp->d_ops->leaf_ents_p(leaf);
-	dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf);
+	xfs_dir2_leaf_hdr_from_disk(mp, &leafhdr, leaf);
 
 	/*
 	 * Look for the first leaf entry with our hash value.
@@ -1330,7 +1359,7 @@ xfs_dir2_leaf_removename(
 	hdr = dbp->b_addr;
 	xfs_dir3_data_check(dp, dbp);
 	bf = dp->d_ops->data_bestfree_p(hdr);
-	dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf);
+	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.
@@ -1509,7 +1538,7 @@ xfs_dir2_leaf_search_hash(
 
 	leaf = lbp->b_addr;
 	ents = args->dp->d_ops->leaf_ents_p(leaf);
-	args->dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf);
+	xfs_dir2_leaf_hdr_from_disk(args->dp->i_mount, &leafhdr, leaf);
 
 	/*
 	 * Note, the table cannot be empty, so we have to go through the loop.
@@ -1697,7 +1726,7 @@ xfs_dir2_node_to_leaf(
 		return 0;
 	lbp = state->path.blk[0].bp;
 	leaf = lbp->b_addr;
-	dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf);
+	xfs_dir2_leaf_hdr_from_disk(mp, &leafhdr, leaf);
 
 	ASSERT(leafhdr.magic == XFS_DIR2_LEAFN_MAGIC ||
 	       leafhdr.magic == XFS_DIR3_LEAFN_MAGIC);
diff --git a/fs/xfs/libxfs/xfs_dir2_node.c b/fs/xfs/libxfs/xfs_dir2_node.c
index 705c4f562758..736a3ea2b92c 100644
--- a/fs/xfs/libxfs/xfs_dir2_node.c
+++ b/fs/xfs/libxfs/xfs_dir2_node.c
@@ -45,7 +45,7 @@ xfs_dir3_leafn_check(
 	struct xfs_dir2_leaf	*leaf = bp->b_addr;
 	struct xfs_dir3_icleaf_hdr leafhdr;
 
-	dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf);
+	xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &leafhdr, leaf);
 
 	if (leafhdr.magic == XFS_DIR3_LEAFN_MAGIC) {
 		struct xfs_dir3_leaf_hdr *leaf3 = bp->b_addr;
@@ -438,7 +438,7 @@ xfs_dir2_leafn_add(
 
 	trace_xfs_dir2_leafn_add(args, index);
 
-	dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf);
+	xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &leafhdr, leaf);
 	ents = dp->d_ops->leaf_ents_p(leaf);
 
 	/*
@@ -534,7 +534,7 @@ xfs_dir2_leaf_lasthash(
 	struct xfs_dir2_leaf_entry *ents;
 	struct xfs_dir3_icleaf_hdr leafhdr;
 
-	dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf);
+	xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &leafhdr, leaf);
 
 	ASSERT(leafhdr.magic == XFS_DIR2_LEAFN_MAGIC ||
 	       leafhdr.magic == XFS_DIR3_LEAFN_MAGIC ||
@@ -583,7 +583,7 @@ xfs_dir2_leafn_lookup_for_addname(
 	tp = args->trans;
 	mp = dp->i_mount;
 	leaf = bp->b_addr;
-	dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf);
+	xfs_dir2_leaf_hdr_from_disk(mp, &leafhdr, leaf);
 	ents = dp->d_ops->leaf_ents_p(leaf);
 
 	xfs_dir3_leaf_check(dp, bp);
@@ -735,7 +735,7 @@ xfs_dir2_leafn_lookup_for_entry(
 	tp = args->trans;
 	mp = dp->i_mount;
 	leaf = bp->b_addr;
-	dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf);
+	xfs_dir2_leaf_hdr_from_disk(mp, &leafhdr, leaf);
 	ents = dp->d_ops->leaf_ents_p(leaf);
 
 	xfs_dir3_leaf_check(dp, bp);
@@ -971,8 +971,8 @@ xfs_dir2_leafn_order(
 	struct xfs_dir3_icleaf_hdr hdr1;
 	struct xfs_dir3_icleaf_hdr hdr2;
 
-	dp->d_ops->leaf_hdr_from_disk(&hdr1, leaf1);
-	dp->d_ops->leaf_hdr_from_disk(&hdr2, leaf2);
+	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);
 
@@ -1024,8 +1024,8 @@ xfs_dir2_leafn_rebalance(
 
 	leaf1 = blk1->bp->b_addr;
 	leaf2 = blk2->bp->b_addr;
-	dp->d_ops->leaf_hdr_from_disk(&hdr1, leaf1);
-	dp->d_ops->leaf_hdr_from_disk(&hdr2, leaf2);
+	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);
 
@@ -1222,7 +1222,7 @@ xfs_dir2_leafn_remove(
 	dp = args->dp;
 	tp = args->trans;
 	leaf = bp->b_addr;
-	dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf);
+	xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &leafhdr, leaf);
 	ents = dp->d_ops->leaf_ents_p(leaf);
 
 	/*
@@ -1444,7 +1444,7 @@ xfs_dir2_leafn_toosmall(
 	 */
 	blk = &state->path.blk[state->path.active - 1];
 	leaf = blk->bp->b_addr;
-	dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf);
+	xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &leafhdr, leaf);
 	ents = dp->d_ops->leaf_ents_p(leaf);
 	xfs_dir3_leaf_check(dp, blk->bp);
 
@@ -1507,7 +1507,7 @@ xfs_dir2_leafn_toosmall(
 			(state->args->geo->blksize >> 2);
 
 		leaf = bp->b_addr;
-		dp->d_ops->leaf_hdr_from_disk(&hdr2, leaf);
+		xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &hdr2, leaf);
 		ents = dp->d_ops->leaf_ents_p(leaf);
 		count += hdr2.count - hdr2.stale;
 		bytes -= count * sizeof(ents[0]);
@@ -1570,8 +1570,8 @@ xfs_dir2_leafn_unbalance(
 	drop_leaf = drop_blk->bp->b_addr;
 	save_leaf = save_blk->bp->b_addr;
 
-	dp->d_ops->leaf_hdr_from_disk(&savehdr, save_leaf);
-	dp->d_ops->leaf_hdr_from_disk(&drophdr, drop_leaf);
+	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);
 
diff --git a/fs/xfs/libxfs/xfs_dir2_priv.h b/fs/xfs/libxfs/xfs_dir2_priv.h
index 973b1527b7ba..434bb60c718c 100644
--- a/fs/xfs/libxfs/xfs_dir2_priv.h
+++ b/fs/xfs/libxfs/xfs_dir2_priv.h
@@ -67,6 +67,8 @@ extern int xfs_dir3_data_init(struct xfs_da_args *args, xfs_dir2_db_t blkno,
 		struct xfs_buf **bpp);
 
 /* xfs_dir2_leaf.c */
+void xfs_dir2_leaf_hdr_from_disk(struct xfs_mount *mp,
+		struct xfs_dir3_icleaf_hdr *to, struct xfs_dir2_leaf *from);
 extern int xfs_dir3_leaf_read(struct xfs_trans *tp, struct xfs_inode *dp,
 		xfs_dablk_t fbno, xfs_daddr_t mappedbno, struct xfs_buf **bpp);
 extern int xfs_dir3_leafn_read(struct xfs_trans *tp, struct xfs_inode *dp,
diff --git a/fs/xfs/scrub/dir.c b/fs/xfs/scrub/dir.c
index 97f274f7cd38..5b004d1f6bef 100644
--- a/fs/xfs/scrub/dir.c
+++ b/fs/xfs/scrub/dir.c
@@ -504,7 +504,7 @@ xchk_directory_leaf1_bestfree(
 	xchk_buffer_recheck(sc, bp);
 
 	leaf = bp->b_addr;
-	d_ops->leaf_hdr_from_disk(&leafhdr, leaf);
+	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);
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 08/34] xfs: devirtualize ->leaf_hdr_to_disk
  2019-11-01 22:06 remove m_dirops Christoph Hellwig
                   ` (6 preceding siblings ...)
  2019-11-01 22:06 ` [PATCH 07/34] xfs: devirtualize ->leaf_hdr_from_disk Christoph Hellwig
@ 2019-11-01 22:06 ` Christoph Hellwig
  2019-11-04 20:00   ` Darrick J. Wong
  2019-11-01 22:06 ` [PATCH 09/34] xfs: add a entries pointer to struct xfs_dir3_icleaf_hdr Christoph Hellwig
                   ` (25 subsequent siblings)
  33 siblings, 1 reply; 81+ messages in thread
From: Christoph Hellwig @ 2019-11-01 22:06 UTC (permalink / raw)
  To: linux-xfs

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

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 fs/xfs/libxfs/xfs_da_format.c | 35 -------------------------------
 fs/xfs/libxfs/xfs_dir2.h      |  2 --
 fs/xfs/libxfs/xfs_dir2_leaf.c | 39 ++++++++++++++++++++++++++++++-----
 fs/xfs/libxfs/xfs_dir2_node.c | 12 +++++------
 fs/xfs/libxfs/xfs_dir2_priv.h |  2 ++
 5 files changed, 42 insertions(+), 48 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c
index c848cab41be5..193708d12459 100644
--- a/fs/xfs/libxfs/xfs_da_format.c
+++ b/fs/xfs/libxfs/xfs_da_format.c
@@ -430,38 +430,6 @@ xfs_dir3_leaf_ents_p(struct xfs_dir2_leaf *lp)
 	return ((struct xfs_dir3_leaf *)lp)->__ents;
 }
 
-static void
-xfs_dir2_leaf_hdr_to_disk(
-	struct xfs_dir2_leaf		*to,
-	struct xfs_dir3_icleaf_hdr	*from)
-{
-	ASSERT(from->magic == XFS_DIR2_LEAF1_MAGIC ||
-	       from->magic == XFS_DIR2_LEAFN_MAGIC);
-
-	to->hdr.info.forw = cpu_to_be32(from->forw);
-	to->hdr.info.back = cpu_to_be32(from->back);
-	to->hdr.info.magic = cpu_to_be16(from->magic);
-	to->hdr.count = cpu_to_be16(from->count);
-	to->hdr.stale = cpu_to_be16(from->stale);
-}
-
-static void
-xfs_dir3_leaf_hdr_to_disk(
-	struct xfs_dir2_leaf		*to,
-	struct xfs_dir3_icleaf_hdr	*from)
-{
-	struct xfs_dir3_leaf_hdr *hdr3 = (struct xfs_dir3_leaf_hdr *)to;
-
-	ASSERT(from->magic == XFS_DIR3_LEAF1_MAGIC ||
-	       from->magic == XFS_DIR3_LEAFN_MAGIC);
-
-	hdr3->info.hdr.forw = cpu_to_be32(from->forw);
-	hdr3->info.hdr.back = cpu_to_be32(from->back);
-	hdr3->info.hdr.magic = cpu_to_be16(from->magic);
-	hdr3->count = cpu_to_be16(from->count);
-	hdr3->stale = cpu_to_be16(from->stale);
-}
-
 /*
  * Directory free space block operations
  */
@@ -615,7 +583,6 @@ static const struct xfs_dir_ops xfs_dir2_ops = {
 	.data_unused_p = xfs_dir2_data_unused_p,
 
 	.leaf_hdr_size = sizeof(struct xfs_dir2_leaf_hdr),
-	.leaf_hdr_to_disk = xfs_dir2_leaf_hdr_to_disk,
 	.leaf_max_ents = xfs_dir2_max_leaf_ents,
 	.leaf_ents_p = xfs_dir2_leaf_ents_p,
 
@@ -659,7 +626,6 @@ static const struct xfs_dir_ops xfs_dir2_ftype_ops = {
 	.data_unused_p = xfs_dir2_data_unused_p,
 
 	.leaf_hdr_size = sizeof(struct xfs_dir2_leaf_hdr),
-	.leaf_hdr_to_disk = xfs_dir2_leaf_hdr_to_disk,
 	.leaf_max_ents = xfs_dir2_max_leaf_ents,
 	.leaf_ents_p = xfs_dir2_leaf_ents_p,
 
@@ -703,7 +669,6 @@ static const struct xfs_dir_ops xfs_dir3_ops = {
 	.data_unused_p = xfs_dir3_data_unused_p,
 
 	.leaf_hdr_size = sizeof(struct xfs_dir3_leaf_hdr),
-	.leaf_hdr_to_disk = xfs_dir3_leaf_hdr_to_disk,
 	.leaf_max_ents = xfs_dir3_max_leaf_ents,
 	.leaf_ents_p = xfs_dir3_leaf_ents_p,
 
diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h
index 74c592496bf0..15a1a72dc126 100644
--- a/fs/xfs/libxfs/xfs_dir2.h
+++ b/fs/xfs/libxfs/xfs_dir2.h
@@ -73,8 +73,6 @@ struct xfs_dir_ops {
 		(*data_unused_p)(struct xfs_dir2_data_hdr *hdr);
 
 	int	leaf_hdr_size;
-	void	(*leaf_hdr_to_disk)(struct xfs_dir2_leaf *to,
-				    struct xfs_dir3_icleaf_hdr *from);
 	int	(*leaf_max_ents)(struct xfs_da_geometry *geo);
 	struct xfs_dir2_leaf_entry *
 		(*leaf_ents_p)(struct xfs_dir2_leaf *lp);
diff --git a/fs/xfs/libxfs/xfs_dir2_leaf.c b/fs/xfs/libxfs/xfs_dir2_leaf.c
index 137ffd0a538b..56aae0b4cf89 100644
--- a/fs/xfs/libxfs/xfs_dir2_leaf.c
+++ b/fs/xfs/libxfs/xfs_dir2_leaf.c
@@ -59,6 +59,35 @@ xfs_dir2_leaf_hdr_from_disk(
 	}
 }
 
+void
+xfs_dir2_leaf_hdr_to_disk(
+	struct xfs_mount		*mp,
+	struct xfs_dir2_leaf		*to,
+	struct xfs_dir3_icleaf_hdr	*from)
+{
+	if (xfs_sb_version_hascrc(&mp->m_sb)) {
+		struct xfs_dir3_leaf *to3 = (struct xfs_dir3_leaf *)to;
+
+		ASSERT(from->magic == XFS_DIR3_LEAF1_MAGIC ||
+		       from->magic == XFS_DIR3_LEAFN_MAGIC);
+
+		to3->hdr.info.hdr.forw = cpu_to_be32(from->forw);
+		to3->hdr.info.hdr.back = cpu_to_be32(from->back);
+		to3->hdr.info.hdr.magic = cpu_to_be16(from->magic);
+		to3->hdr.count = cpu_to_be16(from->count);
+		to3->hdr.stale = cpu_to_be16(from->stale);
+	} else {
+		ASSERT(from->magic == XFS_DIR2_LEAF1_MAGIC ||
+		       from->magic == XFS_DIR2_LEAFN_MAGIC);
+
+		to->hdr.info.forw = cpu_to_be32(from->forw);
+		to->hdr.info.back = cpu_to_be32(from->back);
+		to->hdr.info.magic = cpu_to_be16(from->magic);
+		to->hdr.count = cpu_to_be16(from->count);
+		to->hdr.stale = cpu_to_be16(from->stale);
+	}
+}
+
 /*
  * Check the internal consistency of a leaf1 block.
  * Pop an assert if something is wrong.
@@ -413,7 +442,7 @@ xfs_dir2_block_to_leaf(
 	xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &leafhdr, leaf);
 	leafhdr.count = be32_to_cpu(btp->count);
 	leafhdr.stale = be32_to_cpu(btp->stale);
-	dp->d_ops->leaf_hdr_to_disk(leaf, &leafhdr);
+	xfs_dir2_leaf_hdr_to_disk(dp->i_mount, leaf, &leafhdr);
 	xfs_dir3_leaf_log_header(args, lbp);
 
 	/*
@@ -881,7 +910,7 @@ xfs_dir2_leaf_addname(
 	/*
 	 * Log the leaf fields and give up the buffers.
 	 */
-	dp->d_ops->leaf_hdr_to_disk(leaf, &leafhdr);
+	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_check(dp, lbp);
@@ -934,7 +963,7 @@ xfs_dir3_leaf_compact(
 	leafhdr->count -= leafhdr->stale;
 	leafhdr->stale = 0;
 
-	dp->d_ops->leaf_hdr_to_disk(leaf, leafhdr);
+	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);
@@ -1384,7 +1413,7 @@ xfs_dir2_leaf_removename(
 	 * We just mark the leaf entry stale by putting a null in it.
 	 */
 	leafhdr.stale++;
-	dp->d_ops->leaf_hdr_to_disk(leaf, &leafhdr);
+	xfs_dir2_leaf_hdr_to_disk(dp->i_mount, leaf, &leafhdr);
 	xfs_dir3_leaf_log_header(args, lbp);
 
 	lep->address = cpu_to_be32(XFS_DIR2_NULL_DATAPTR);
@@ -1775,7 +1804,7 @@ xfs_dir2_node_to_leaf(
 	memcpy(xfs_dir2_leaf_bests_p(ltp), dp->d_ops->free_bests_p(free),
 		freehdr.nvalid * sizeof(xfs_dir2_data_off_t));
 
-	dp->d_ops->leaf_hdr_to_disk(leaf, &leafhdr);
+	xfs_dir2_leaf_hdr_to_disk(mp, leaf, &leafhdr);
 	xfs_dir3_leaf_log_header(args, lbp);
 	xfs_dir3_leaf_log_bests(args, lbp, 0, be32_to_cpu(ltp->bestcount) - 1);
 	xfs_dir3_leaf_log_tail(args, lbp);
diff --git a/fs/xfs/libxfs/xfs_dir2_node.c b/fs/xfs/libxfs/xfs_dir2_node.c
index 736a3ea2b92c..207ef9b4fe50 100644
--- a/fs/xfs/libxfs/xfs_dir2_node.c
+++ b/fs/xfs/libxfs/xfs_dir2_node.c
@@ -493,7 +493,7 @@ xfs_dir2_leafn_add(
 	lep->address = cpu_to_be32(xfs_dir2_db_off_to_dataptr(args->geo,
 				args->blkno, args->index));
 
-	dp->d_ops->leaf_hdr_to_disk(leaf, &leafhdr);
+	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_check(dp, bp);
@@ -1073,8 +1073,8 @@ xfs_dir2_leafn_rebalance(
 	ASSERT(hdr1.stale + hdr2.stale == oldstale);
 
 	/* log the changes made when moving the entries */
-	dp->d_ops->leaf_hdr_to_disk(leaf1, &hdr1);
-	dp->d_ops->leaf_hdr_to_disk(leaf2, &hdr2);
+	xfs_dir2_leaf_hdr_to_disk(dp->i_mount, leaf1, &hdr1);
+	xfs_dir2_leaf_hdr_to_disk(dp->i_mount, leaf2, &hdr2);
 	xfs_dir3_leaf_log_header(args, blk1->bp);
 	xfs_dir3_leaf_log_header(args, blk2->bp);
 
@@ -1243,7 +1243,7 @@ xfs_dir2_leafn_remove(
 	 * Log the leaf block changes.
 	 */
 	leafhdr.stale++;
-	dp->d_ops->leaf_hdr_to_disk(leaf, &leafhdr);
+	xfs_dir2_leaf_hdr_to_disk(dp->i_mount, leaf, &leafhdr);
 	xfs_dir3_leaf_log_header(args, bp);
 
 	lep->address = cpu_to_be32(XFS_DIR2_NULL_DATAPTR);
@@ -1599,8 +1599,8 @@ xfs_dir2_leafn_unbalance(
 	save_blk->hashval = be32_to_cpu(sents[savehdr.count - 1].hashval);
 
 	/* log the changes made when moving the entries */
-	dp->d_ops->leaf_hdr_to_disk(save_leaf, &savehdr);
-	dp->d_ops->leaf_hdr_to_disk(drop_leaf, &drophdr);
+	xfs_dir2_leaf_hdr_to_disk(dp->i_mount, save_leaf, &savehdr);
+	xfs_dir2_leaf_hdr_to_disk(dp->i_mount, drop_leaf, &drophdr);
 	xfs_dir3_leaf_log_header(args, save_blk->bp);
 	xfs_dir3_leaf_log_header(args, drop_blk->bp);
 
diff --git a/fs/xfs/libxfs/xfs_dir2_priv.h b/fs/xfs/libxfs/xfs_dir2_priv.h
index 434bb60c718c..b402a2391f49 100644
--- a/fs/xfs/libxfs/xfs_dir2_priv.h
+++ b/fs/xfs/libxfs/xfs_dir2_priv.h
@@ -69,6 +69,8 @@ extern int xfs_dir3_data_init(struct xfs_da_args *args, xfs_dir2_db_t blkno,
 /* xfs_dir2_leaf.c */
 void xfs_dir2_leaf_hdr_from_disk(struct xfs_mount *mp,
 		struct xfs_dir3_icleaf_hdr *to, struct xfs_dir2_leaf *from);
+void xfs_dir2_leaf_hdr_to_disk(struct xfs_mount *mp, struct xfs_dir2_leaf *to,
+		struct xfs_dir3_icleaf_hdr *from);
 extern int xfs_dir3_leaf_read(struct xfs_trans *tp, struct xfs_inode *dp,
 		xfs_dablk_t fbno, xfs_daddr_t mappedbno, struct xfs_buf **bpp);
 extern int xfs_dir3_leafn_read(struct xfs_trans *tp, struct xfs_inode *dp,
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 09/34] xfs: add a entries pointer to struct xfs_dir3_icleaf_hdr
  2019-11-01 22:06 remove m_dirops Christoph Hellwig
                   ` (7 preceding siblings ...)
  2019-11-01 22:06 ` [PATCH 08/34] xfs: devirtualize ->leaf_hdr_to_disk Christoph Hellwig
@ 2019-11-01 22:06 ` Christoph Hellwig
  2019-11-04 20:04   ` Darrick J. Wong
  2019-11-01 22:06 ` [PATCH 10/34] xfs: move the dir2 leaf header size to struct xfs_da_geometry Christoph Hellwig
                   ` (24 subsequent siblings)
  33 siblings, 1 reply; 81+ messages in thread
From: Christoph Hellwig @ 2019-11-01 22:06 UTC (permalink / raw)
  To: linux-xfs

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@lst.de>
---
 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  |   5 +-
 fs/xfs/scrub/dir.c             |  13 +++--
 8 files changed, 88 insertions(+), 126 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_da_btree.c b/fs/xfs/libxfs/xfs_da_btree.c
index aeb1884fd8c7..af825983c054 100644
--- a/fs/xfs/libxfs/xfs_da_btree.c
+++ b/fs/xfs/libxfs/xfs_da_btree.c
@@ -638,15 +638,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;
 
 		/*
@@ -2285,7 +2284,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 e6ed90a6f19b..38886b9c7b48 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 56aae0b4cf89..d6581f40f0a4 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)));
@@ -1417,7 +1412,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,
@@ -1506,26 +1501,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.
 	 */
@@ -1559,21 +1552,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 207ef9b4fe50..76c896da8352 100644
--- a/fs/xfs/libxfs/xfs_dir2_node.c
+++ b/fs/xfs/libxfs/xfs_dir2_node.c
@@ -439,7 +439,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
@@ -495,7 +495,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;
 }
@@ -530,11 +530,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 ||
@@ -545,9 +543,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);
 }
 
 /*
@@ -576,7 +572,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;
@@ -584,7 +579,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);
@@ -608,7 +602,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++) {
 		/*
@@ -728,7 +722,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;
@@ -736,7 +729,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)
@@ -756,7 +748,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++) {
 		/*
@@ -911,7 +903,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);
 	}
 	/*
@@ -933,7 +925,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,
@@ -942,7 +934,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);
 	}
 
 	/*
@@ -973,8 +966,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) ||
@@ -1026,8 +1019,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)
@@ -1215,7 +1208,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);
 
@@ -1223,12 +1215,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.
@@ -1247,7 +1238,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
@@ -1344,7 +1335,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;
 }
@@ -1445,7 +1436,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;
@@ -1508,7 +1499,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]);
 
@@ -1572,8 +1563,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
@@ -2155,8 +2146,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 */
 
@@ -2188,16 +2177,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.
 		 */
@@ -2207,7 +2197,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 b402a2391f49..07cea5751783 100644
--- a/fs/xfs/libxfs/xfs_dir2_priv.h
+++ b/fs/xfs/libxfs/xfs_dir2_priv.h
@@ -18,6 +18,7 @@ struct xfs_dir3_icleaf_hdr {
 	uint16_t		magic;
 	uint16_t		count;
 	uint16_t		stale;
+	struct xfs_dir2_leaf_entry *ents;
 };
 
 struct xfs_dir3_icfree_hdr {
@@ -25,7 +26,6 @@ struct xfs_dir3_icfree_hdr {
 	uint32_t		firstdb;
 	uint32_t		nvalid;
 	uint32_t		nused;
-
 };
 
 /* xfs_dir2.c */
@@ -86,7 +86,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..27fdf8978467 100644
--- a/fs/xfs/scrub/dir.c
+++ b/fs/xfs/scrub/dir.c
@@ -195,13 +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) +
+	xfs_dir2_leaf_hdr_from_disk(mp, &hdr, blk->bp->b_addr);
+	ent = (void *)hdr.ents +
 		(blk->index * sizeof(struct xfs_dir2_leaf_entry));
 
 	/* Check the hash of the entry. */
@@ -481,7 +483,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 +506,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 +533,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


^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 10/34] xfs: move the dir2 leaf header size to struct xfs_da_geometry
  2019-11-01 22:06 remove m_dirops Christoph Hellwig
                   ` (8 preceding siblings ...)
  2019-11-01 22:06 ` [PATCH 09/34] xfs: add a entries pointer to struct xfs_dir3_icleaf_hdr Christoph Hellwig
@ 2019-11-01 22:06 ` Christoph Hellwig
  2019-11-04 20:05   ` Darrick J. Wong
  2019-11-01 22:06 ` [PATCH 11/34] xfs: move the max dir2 leaf entries count " Christoph Hellwig
                   ` (23 subsequent siblings)
  33 siblings, 1 reply; 81+ messages in thread
From: Christoph Hellwig @ 2019-11-01 22:06 UTC (permalink / raw)
  To: linux-xfs

Move the leaf header size towards our structure for dir/attr geometry
parameters.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 fs/xfs/libxfs/xfs_da_btree.h  | 1 +
 fs/xfs/libxfs/xfs_da_format.c | 3 ---
 fs/xfs/libxfs/xfs_dir2.c      | 7 +++++--
 fs/xfs/libxfs/xfs_dir2.h      | 1 -
 fs/xfs/libxfs/xfs_dir2_leaf.c | 2 +-
 fs/xfs/libxfs/xfs_dir2_node.c | 4 ++--
 6 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_da_btree.h b/fs/xfs/libxfs/xfs_da_btree.h
index 11b2d75f83ad..5e3e954fee77 100644
--- a/fs/xfs/libxfs/xfs_da_btree.h
+++ b/fs/xfs/libxfs/xfs_da_btree.h
@@ -26,6 +26,7 @@ struct xfs_da_geometry {
 	uint		node_ents;	/* # of entries in a danode */
 	int		magicpct;	/* 37% of block size in bytes */
 	xfs_dablk_t	datablk;	/* blockno of dir data v2 */
+	int		leaf_hdr_size;	/* dir2 leaf header size */
 	xfs_dablk_t	leafblk;	/* blockno of leaf data v2 */
 	xfs_dablk_t	freeblk;	/* blockno of free data v2 */
 };
diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c
index ed21ce01502f..a3e87f4788e0 100644
--- a/fs/xfs/libxfs/xfs_da_format.c
+++ b/fs/xfs/libxfs/xfs_da_format.c
@@ -570,7 +570,6 @@ static const struct xfs_dir_ops xfs_dir2_ops = {
 	.data_entry_p = xfs_dir2_data_entry_p,
 	.data_unused_p = xfs_dir2_data_unused_p,
 
-	.leaf_hdr_size = sizeof(struct xfs_dir2_leaf_hdr),
 	.leaf_max_ents = xfs_dir2_max_leaf_ents,
 
 	.free_hdr_size = sizeof(struct xfs_dir2_free_hdr),
@@ -612,7 +611,6 @@ static const struct xfs_dir_ops xfs_dir2_ftype_ops = {
 	.data_entry_p = xfs_dir2_data_entry_p,
 	.data_unused_p = xfs_dir2_data_unused_p,
 
-	.leaf_hdr_size = sizeof(struct xfs_dir2_leaf_hdr),
 	.leaf_max_ents = xfs_dir2_max_leaf_ents,
 
 	.free_hdr_size = sizeof(struct xfs_dir2_free_hdr),
@@ -654,7 +652,6 @@ static const struct xfs_dir_ops xfs_dir3_ops = {
 	.data_entry_p = xfs_dir3_data_entry_p,
 	.data_unused_p = xfs_dir3_data_unused_p,
 
-	.leaf_hdr_size = sizeof(struct xfs_dir3_leaf_hdr),
 	.leaf_max_ents = xfs_dir3_max_leaf_ents,
 
 	.free_hdr_size = sizeof(struct xfs_dir3_free_hdr),
diff --git a/fs/xfs/libxfs/xfs_dir2.c b/fs/xfs/libxfs/xfs_dir2.c
index aef20ec6e140..94badb28fd1a 100644
--- a/fs/xfs/libxfs/xfs_dir2.c
+++ b/fs/xfs/libxfs/xfs_dir2.c
@@ -122,10 +122,13 @@ xfs_da_mount(
 	dageo->fsblog = mp->m_sb.sb_blocklog;
 	dageo->blksize = xfs_dir2_dirblock_bytes(&mp->m_sb);
 	dageo->fsbcount = 1 << mp->m_sb.sb_dirblklog;
-	if (xfs_sb_version_hascrc(&mp->m_sb))
+	if (xfs_sb_version_hascrc(&mp->m_sb)) {
 		dageo->node_hdr_size = sizeof(struct xfs_da3_node_hdr);
-	else
+		dageo->leaf_hdr_size = sizeof(struct xfs_dir3_leaf_hdr);
+	} else {
 		dageo->node_hdr_size = sizeof(struct xfs_da_node_hdr);
+		dageo->leaf_hdr_size = sizeof(struct xfs_dir2_leaf_hdr);
+	}
 
 	/*
 	 * Now we've set up the block conversion variables, we can calculate the
diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h
index b46657974134..544adee5dd12 100644
--- a/fs/xfs/libxfs/xfs_dir2.h
+++ b/fs/xfs/libxfs/xfs_dir2.h
@@ -72,7 +72,6 @@ struct xfs_dir_ops {
 	struct xfs_dir2_data_unused *
 		(*data_unused_p)(struct xfs_dir2_data_hdr *hdr);
 
-	int	leaf_hdr_size;
 	int	(*leaf_max_ents)(struct xfs_da_geometry *geo);
 
 	int	free_hdr_size;
diff --git a/fs/xfs/libxfs/xfs_dir2_leaf.c b/fs/xfs/libxfs/xfs_dir2_leaf.c
index d6581f40f0a4..f72fd8182223 100644
--- a/fs/xfs/libxfs/xfs_dir2_leaf.c
+++ b/fs/xfs/libxfs/xfs_dir2_leaf.c
@@ -1132,7 +1132,7 @@ xfs_dir3_leaf_log_header(
 
 	xfs_trans_log_buf(args->trans, bp,
 			  (uint)((char *)&leaf->hdr - (char *)leaf),
-			  args->dp->d_ops->leaf_hdr_size - 1);
+			  args->geo->leaf_hdr_size - 1);
 }
 
 /*
diff --git a/fs/xfs/libxfs/xfs_dir2_node.c b/fs/xfs/libxfs/xfs_dir2_node.c
index 76c896da8352..76f31909376e 100644
--- a/fs/xfs/libxfs/xfs_dir2_node.c
+++ b/fs/xfs/libxfs/xfs_dir2_node.c
@@ -1334,7 +1334,7 @@ xfs_dir2_leafn_remove(
 	 * Return indication of whether this leaf block is empty enough
 	 * to justify trying to join it with a neighbor.
 	 */
-	*rval = (dp->d_ops->leaf_hdr_size +
+	*rval = (args->geo->leaf_hdr_size +
 		 (uint)sizeof(leafhdr.ents) * (leafhdr.count - leafhdr.stale)) <
 		args->geo->magicpct;
 	return 0;
@@ -1440,7 +1440,7 @@ xfs_dir2_leafn_toosmall(
 	xfs_dir3_leaf_check(dp, blk->bp);
 
 	count = leafhdr.count - leafhdr.stale;
-	bytes = dp->d_ops->leaf_hdr_size + count * sizeof(ents[0]);
+	bytes = state->args->geo->leaf_hdr_size + count * sizeof(ents[0]);
 	if (bytes > (state->args->geo->blksize >> 1)) {
 		/*
 		 * Blk over 50%, don't try to join.
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 11/34] xfs: move the max dir2 leaf entries count to struct xfs_da_geometry
  2019-11-01 22:06 remove m_dirops Christoph Hellwig
                   ` (9 preceding siblings ...)
  2019-11-01 22:06 ` [PATCH 10/34] xfs: move the dir2 leaf header size to struct xfs_da_geometry Christoph Hellwig
@ 2019-11-01 22:06 ` Christoph Hellwig
  2019-11-04 20:07   ` Darrick J. Wong
  2019-11-01 22:06 ` [PATCH 12/34] xfs: devirtualize ->free_hdr_from_disk Christoph Hellwig
                   ` (22 subsequent siblings)
  33 siblings, 1 reply; 81+ messages in thread
From: Christoph Hellwig @ 2019-11-01 22:06 UTC (permalink / raw)
  To: linux-xfs

Move the max leaf entries count towards our structure for dir/attr
geometry parameters.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 fs/xfs/libxfs/xfs_da_btree.h  |  1 +
 fs/xfs/libxfs/xfs_da_format.c | 23 -----------------------
 fs/xfs/libxfs/xfs_dir2.c      |  2 ++
 fs/xfs/libxfs/xfs_dir2.h      |  2 --
 fs/xfs/libxfs/xfs_dir2_leaf.c |  2 +-
 fs/xfs/libxfs/xfs_dir2_node.c |  2 +-
 fs/xfs/scrub/dir.c            |  3 +--
 7 files changed, 6 insertions(+), 29 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_da_btree.h b/fs/xfs/libxfs/xfs_da_btree.h
index 5e3e954fee77..c8b137685ca7 100644
--- a/fs/xfs/libxfs/xfs_da_btree.h
+++ b/fs/xfs/libxfs/xfs_da_btree.h
@@ -27,6 +27,7 @@ struct xfs_da_geometry {
 	int		magicpct;	/* 37% of block size in bytes */
 	xfs_dablk_t	datablk;	/* blockno of dir data v2 */
 	int		leaf_hdr_size;	/* dir2 leaf header size */
+	unsigned int	leaf_max_ents;	/* # of entries in dir2 leaf */
 	xfs_dablk_t	leafblk;	/* blockno of leaf data v2 */
 	xfs_dablk_t	freeblk;	/* blockno of free data v2 */
 };
diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c
index a3e87f4788e0..fe9e20698719 100644
--- a/fs/xfs/libxfs/xfs_da_format.c
+++ b/fs/xfs/libxfs/xfs_da_format.c
@@ -401,23 +401,6 @@ xfs_dir3_data_unused_p(struct xfs_dir2_data_hdr *hdr)
 }
 
 
-/*
- * Directory Leaf block operations
- */
-static int
-xfs_dir2_max_leaf_ents(struct xfs_da_geometry *geo)
-{
-	return (geo->blksize - sizeof(struct xfs_dir2_leaf_hdr)) /
-		(uint)sizeof(struct xfs_dir2_leaf_entry);
-}
-
-static int
-xfs_dir3_max_leaf_ents(struct xfs_da_geometry *geo)
-{
-	return (geo->blksize - sizeof(struct xfs_dir3_leaf_hdr)) /
-		(uint)sizeof(struct xfs_dir2_leaf_entry);
-}
-
 /*
  * Directory free space block operations
  */
@@ -570,8 +553,6 @@ static const struct xfs_dir_ops xfs_dir2_ops = {
 	.data_entry_p = xfs_dir2_data_entry_p,
 	.data_unused_p = xfs_dir2_data_unused_p,
 
-	.leaf_max_ents = xfs_dir2_max_leaf_ents,
-
 	.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,
@@ -611,8 +592,6 @@ static const struct xfs_dir_ops xfs_dir2_ftype_ops = {
 	.data_entry_p = xfs_dir2_data_entry_p,
 	.data_unused_p = xfs_dir2_data_unused_p,
 
-	.leaf_max_ents = xfs_dir2_max_leaf_ents,
-
 	.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,
@@ -652,8 +631,6 @@ static const struct xfs_dir_ops xfs_dir3_ops = {
 	.data_entry_p = xfs_dir3_data_entry_p,
 	.data_unused_p = xfs_dir3_data_unused_p,
 
-	.leaf_max_ents = xfs_dir3_max_leaf_ents,
-
 	.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,
diff --git a/fs/xfs/libxfs/xfs_dir2.c b/fs/xfs/libxfs/xfs_dir2.c
index 94badb28fd1a..9f88b9885747 100644
--- a/fs/xfs/libxfs/xfs_dir2.c
+++ b/fs/xfs/libxfs/xfs_dir2.c
@@ -129,6 +129,8 @@ xfs_da_mount(
 		dageo->node_hdr_size = sizeof(struct xfs_da_node_hdr);
 		dageo->leaf_hdr_size = sizeof(struct xfs_dir2_leaf_hdr);
 	}
+	dageo->leaf_max_ents = (dageo->blksize - dageo->leaf_hdr_size) /
+			sizeof(struct xfs_dir2_leaf_entry);
 
 	/*
 	 * Now we've set up the block conversion variables, we can calculate the
diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h
index 544adee5dd12..ee18fc56a6a1 100644
--- a/fs/xfs/libxfs/xfs_dir2.h
+++ b/fs/xfs/libxfs/xfs_dir2.h
@@ -72,8 +72,6 @@ struct xfs_dir_ops {
 	struct xfs_dir2_data_unused *
 		(*data_unused_p)(struct xfs_dir2_data_hdr *hdr);
 
-	int	(*leaf_max_ents)(struct xfs_da_geometry *geo);
-
 	int	free_hdr_size;
 	void	(*free_hdr_to_disk)(struct xfs_dir2_free *to,
 				    struct xfs_dir3_icfree_hdr *from);
diff --git a/fs/xfs/libxfs/xfs_dir2_leaf.c b/fs/xfs/libxfs/xfs_dir2_leaf.c
index f72fd8182223..38d42fe1aa02 100644
--- a/fs/xfs/libxfs/xfs_dir2_leaf.c
+++ b/fs/xfs/libxfs/xfs_dir2_leaf.c
@@ -167,7 +167,7 @@ xfs_dir3_leaf_check_int(
 	 * Should factor in the size of the bests table as well.
 	 * We can deduce a value for that from di_size.
 	 */
-	if (hdr->count > ops->leaf_max_ents(geo))
+	if (hdr->count > geo->leaf_max_ents)
 		return __this_address;
 
 	/* Leaves and bests don't overlap in leaf format. */
diff --git a/fs/xfs/libxfs/xfs_dir2_node.c b/fs/xfs/libxfs/xfs_dir2_node.c
index 76f31909376e..3b9ed6ac72b6 100644
--- a/fs/xfs/libxfs/xfs_dir2_node.c
+++ b/fs/xfs/libxfs/xfs_dir2_node.c
@@ -455,7 +455,7 @@ xfs_dir2_leafn_add(
 	 * a compact.
 	 */
 
-	if (leafhdr.count == dp->d_ops->leaf_max_ents(args->geo)) {
+	if (leafhdr.count == args->geo->leaf_max_ents) {
 		if (!leafhdr.stale)
 			return -ENOSPC;
 		compact = leafhdr.stale > 1;
diff --git a/fs/xfs/scrub/dir.c b/fs/xfs/scrub/dir.c
index 27fdf8978467..e4e189d3c1c0 100644
--- a/fs/xfs/scrub/dir.c
+++ b/fs/xfs/scrub/dir.c
@@ -487,7 +487,6 @@ xchk_directory_leaf1_bestfree(
 	struct xfs_dir2_leaf		*leaf;
 	struct xfs_buf			*dbp;
 	struct xfs_buf			*bp;
-	const struct xfs_dir_ops	*d_ops = sc->ip->d_ops;
 	struct xfs_da_geometry		*geo = sc->mp->m_dir_geo;
 	__be16				*bestp;
 	__u16				best;
@@ -527,7 +526,7 @@ xchk_directory_leaf1_bestfree(
 	}
 
 	/* Is the leaf count even remotely sane? */
-	if (leafhdr.count > d_ops->leaf_max_ents(geo)) {
+	if (leafhdr.count > geo->leaf_max_ents) {
 		xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk);
 		goto out;
 	}
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 12/34] xfs: devirtualize ->free_hdr_from_disk
  2019-11-01 22:06 remove m_dirops Christoph Hellwig
                   ` (10 preceding siblings ...)
  2019-11-01 22:06 ` [PATCH 11/34] xfs: move the max dir2 leaf entries count " Christoph Hellwig
@ 2019-11-01 22:06 ` Christoph Hellwig
  2019-11-04 20:08   ` Darrick J. Wong
  2019-11-01 22:06 ` [PATCH 13/34] xfs: devirtualize ->free_hdr_to_disk Christoph Hellwig
                   ` (21 subsequent siblings)
  33 siblings, 1 reply; 81+ messages in thread
From: Christoph Hellwig @ 2019-11-01 22:06 UTC (permalink / raw)
  To: linux-xfs

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: Christoph Hellwig <hch@lst.de>
---
 fs/xfs/libxfs/xfs_da_format.c | 30 -----------------------
 fs/xfs/libxfs/xfs_dir2.h      |  2 --
 fs/xfs/libxfs/xfs_dir2_leaf.c | 14 +++--------
 fs/xfs/libxfs/xfs_dir2_node.c | 46 +++++++++++++++++++++++++++--------
 fs/xfs/libxfs/xfs_dir2_priv.h |  5 ++--
 fs/xfs/scrub/dir.c            |  2 +-
 6 files changed, 43 insertions(+), 56 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c
index fe9e20698719..d0e541d9d335 100644
--- a/fs/xfs/libxfs/xfs_da_format.c
+++ b/fs/xfs/libxfs/xfs_da_format.c
@@ -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,
diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h
index ee18fc56a6a1..c3e6a6fb7e37 100644
--- a/fs/xfs/libxfs/xfs_dir2.h
+++ b/fs/xfs/libxfs/xfs_dir2.h
@@ -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,
diff --git a/fs/xfs/libxfs/xfs_dir2_leaf.c b/fs/xfs/libxfs/xfs_dir2_leaf.c
index 38d42fe1aa02..4b697dd85eab 100644
--- a/fs/xfs/libxfs/xfs_dir2_leaf.c
+++ b/fs/xfs/libxfs/xfs_dir2_leaf.c
@@ -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
@@ -1756,7 +1748,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);
 
diff --git a/fs/xfs/libxfs/xfs_dir2_node.c b/fs/xfs/libxfs/xfs_dir2_node.c
index 3b9ed6ac72b6..9e22710bb772 100644
--- a/fs/xfs/libxfs/xfs_dir2_node.c
+++ b/fs/xfs/libxfs/xfs_dir2_node.c
@@ -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) >
@@ -509,7 +533,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);
@@ -1117,7 +1141,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) {
 		/*
@@ -1286,7 +1310,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)));
@@ -1680,7 +1705,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,
@@ -1689,7 +1714,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. */
@@ -1758,7 +1783,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);
@@ -1807,7 +1833,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--) {
@@ -2260,7 +2286,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.
diff --git a/fs/xfs/libxfs/xfs_dir2_priv.h b/fs/xfs/libxfs/xfs_dir2_priv.h
index 07cea5751783..ef4a2b402e25 100644
--- a/fs/xfs/libxfs/xfs_dir2_priv.h
+++ b/fs/xfs/libxfs/xfs_dir2_priv.h
@@ -104,10 +104,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,
diff --git a/fs/xfs/scrub/dir.c b/fs/xfs/scrub/dir.c
index e4e189d3c1c0..6b8d9a774ddf 100644
--- a/fs/xfs/scrub/dir.c
+++ b/fs/xfs/scrub/dir.c
@@ -601,7 +601,7 @@ xchk_directory_free_bestfree(
 	}
 
 	/* Check all the entries. */
-	sc->ip->d_ops->free_hdr_from_disk(&freehdr, bp->b_addr);
+	xfs_dir2_free_hdr_from_disk(sc->ip->i_mount, &freehdr, bp->b_addr);
 	bestp = sc->ip->d_ops->free_bests_p(bp->b_addr);
 	for (i = 0; i < freehdr.nvalid; i++, bestp++) {
 		best = be16_to_cpu(*bestp);
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 13/34] xfs: devirtualize ->free_hdr_to_disk
  2019-11-01 22:06 remove m_dirops Christoph Hellwig
                   ` (11 preceding siblings ...)
  2019-11-01 22:06 ` [PATCH 12/34] xfs: devirtualize ->free_hdr_from_disk Christoph Hellwig
@ 2019-11-01 22:06 ` Christoph Hellwig
  2019-11-04 20:08   ` Darrick J. Wong
  2019-11-01 22:06 ` [PATCH 14/34] xfs: make the xfs_dir3_icfree_hdr available to xfs_dir2_node_addname_int Christoph Hellwig
                   ` (20 subsequent siblings)
  33 siblings, 1 reply; 81+ messages in thread
From: Christoph Hellwig @ 2019-11-01 22:06 UTC (permalink / raw)
  To: linux-xfs

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

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 fs/xfs/libxfs/xfs_da_format.c | 31 -------------------------------
 fs/xfs/libxfs/xfs_dir2.h      |  2 --
 fs/xfs/libxfs/xfs_dir2_node.c | 33 +++++++++++++++++++++++++++++----
 3 files changed, 29 insertions(+), 37 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c
index d0e541d9d335..b943d9443d55 100644
--- a/fs/xfs/libxfs/xfs_da_format.c
+++ b/fs/xfs/libxfs/xfs_da_format.c
@@ -468,34 +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_to_disk(
-	struct xfs_dir2_free		*to,
-	struct xfs_dir3_icfree_hdr	*from)
-{
-	ASSERT(from->magic == XFS_DIR2_FREE_MAGIC);
-
-	to->hdr.magic = cpu_to_be32(from->magic);
-	to->hdr.firstdb = cpu_to_be32(from->firstdb);
-	to->hdr.nvalid = cpu_to_be32(from->nvalid);
-	to->hdr.nused = cpu_to_be32(from->nused);
-}
-
-static void
-xfs_dir3_free_hdr_to_disk(
-	struct xfs_dir2_free		*to,
-	struct xfs_dir3_icfree_hdr	*from)
-{
-	struct xfs_dir3_free_hdr *hdr3 = (struct xfs_dir3_free_hdr *)to;
-
-	ASSERT(from->magic == XFS_DIR3_FREE_MAGIC);
-
-	hdr3->hdr.magic = cpu_to_be32(from->magic);
-	hdr3->firstdb = cpu_to_be32(from->firstdb);
-	hdr3->nvalid = cpu_to_be32(from->nvalid);
-	hdr3->nused = cpu_to_be32(from->nused);
-}
-
 static const struct xfs_dir_ops xfs_dir2_ops = {
 	.sf_entsize = xfs_dir2_sf_entsize,
 	.sf_nextentry = xfs_dir2_sf_nextentry,
@@ -527,7 +499,6 @@ static const struct xfs_dir_ops xfs_dir2_ops = {
 	.data_unused_p = xfs_dir2_data_unused_p,
 
 	.free_hdr_size = sizeof(struct xfs_dir2_free_hdr),
-	.free_hdr_to_disk = xfs_dir2_free_hdr_to_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,
@@ -565,7 +536,6 @@ static const struct xfs_dir_ops xfs_dir2_ftype_ops = {
 	.data_unused_p = xfs_dir2_data_unused_p,
 
 	.free_hdr_size = sizeof(struct xfs_dir2_free_hdr),
-	.free_hdr_to_disk = xfs_dir2_free_hdr_to_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,
@@ -603,7 +573,6 @@ static const struct xfs_dir_ops xfs_dir3_ops = {
 	.data_unused_p = xfs_dir3_data_unused_p,
 
 	.free_hdr_size = sizeof(struct xfs_dir3_free_hdr),
-	.free_hdr_to_disk = xfs_dir3_free_hdr_to_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,
diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h
index c3e6a6fb7e37..613a78281d03 100644
--- a/fs/xfs/libxfs/xfs_dir2.h
+++ b/fs/xfs/libxfs/xfs_dir2.h
@@ -73,8 +73,6 @@ struct xfs_dir_ops {
 		(*data_unused_p)(struct xfs_dir2_data_hdr *hdr);
 
 	int	free_hdr_size;
-	void	(*free_hdr_to_disk)(struct xfs_dir2_free *to,
-				    struct xfs_dir3_icfree_hdr *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,
diff --git a/fs/xfs/libxfs/xfs_dir2_node.c b/fs/xfs/libxfs/xfs_dir2_node.c
index 9e22710bb772..26032eba1e32 100644
--- a/fs/xfs/libxfs/xfs_dir2_node.c
+++ b/fs/xfs/libxfs/xfs_dir2_node.c
@@ -244,6 +244,31 @@ xfs_dir2_free_hdr_from_disk(
 	}
 }
 
+static void
+xfs_dir2_free_hdr_to_disk(
+	struct xfs_mount		*mp,
+	struct xfs_dir2_free		*to,
+	struct xfs_dir3_icfree_hdr	*from)
+{
+	if (xfs_sb_version_hascrc(&mp->m_sb)) {
+		struct xfs_dir3_free	*to3 = (struct xfs_dir3_free *)to;
+
+		ASSERT(from->magic == XFS_DIR3_FREE_MAGIC);
+
+		to3->hdr.hdr.magic = cpu_to_be32(from->magic);
+		to3->hdr.firstdb = cpu_to_be32(from->firstdb);
+		to3->hdr.nvalid = cpu_to_be32(from->nvalid);
+		to3->hdr.nused = cpu_to_be32(from->nused);
+	} else {
+		ASSERT(from->magic == XFS_DIR2_FREE_MAGIC);
+
+		to->hdr.magic = cpu_to_be32(from->magic);
+		to->hdr.firstdb = cpu_to_be32(from->firstdb);
+		to->hdr.nvalid = cpu_to_be32(from->nvalid);
+		to->hdr.nused = cpu_to_be32(from->nused);
+	}
+}
+
 int
 xfs_dir2_free_read(
 	struct xfs_trans	*tp,
@@ -302,7 +327,7 @@ xfs_dir3_free_get_buf(
 		uuid_copy(&hdr3->hdr.uuid, &mp->m_sb.sb_meta_uuid);
 	} else
 		hdr.magic = XFS_DIR2_FREE_MAGIC;
-	dp->d_ops->free_hdr_to_disk(bp->b_addr, &hdr);
+	xfs_dir2_free_hdr_to_disk(mp, bp->b_addr, &hdr);
 	*bpp = bp;
 	return 0;
 }
@@ -418,7 +443,7 @@ xfs_dir2_leaf_to_node(
 	freehdr.nused = n;
 	freehdr.nvalid = be32_to_cpu(ltp->bestcount);
 
-	dp->d_ops->free_hdr_to_disk(fbp->b_addr, &freehdr);
+	xfs_dir2_free_hdr_to_disk(dp->i_mount, fbp->b_addr, &freehdr);
 	xfs_dir2_free_log_bests(args, fbp, 0, freehdr.nvalid - 1);
 	xfs_dir2_free_log_header(args, fbp);
 
@@ -1176,7 +1201,7 @@ xfs_dir3_data_block_free(
 		logfree = 1;
 	}
 
-	dp->d_ops->free_hdr_to_disk(free, &freehdr);
+	xfs_dir2_free_hdr_to_disk(dp->i_mount, free, &freehdr);
 	xfs_dir2_free_log_header(args, fbp);
 
 	/*
@@ -1733,7 +1758,7 @@ xfs_dir2_node_add_datablk(
 	 */
 	if (bests[*findex] == cpu_to_be16(NULLDATAOFF)) {
 		freehdr.nused++;
-		dp->d_ops->free_hdr_to_disk(fbp->b_addr, &freehdr);
+		xfs_dir2_free_hdr_to_disk(mp, fbp->b_addr, &freehdr);
 		xfs_dir2_free_log_header(args, fbp);
 	}
 
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 14/34] xfs: make the xfs_dir3_icfree_hdr available to xfs_dir2_node_addname_int
  2019-11-01 22:06 remove m_dirops Christoph Hellwig
                   ` (12 preceding siblings ...)
  2019-11-01 22:06 ` [PATCH 13/34] xfs: devirtualize ->free_hdr_to_disk Christoph Hellwig
@ 2019-11-01 22:06 ` Christoph Hellwig
  2019-11-04 20:25   ` Darrick J. Wong
  2019-11-01 22:07 ` [PATCH 15/34] xfs: add a bests pointer to struct xfs_dir3_icfree_hdr Christoph Hellwig
                   ` (19 subsequent siblings)
  33 siblings, 1 reply; 81+ messages in thread
From: Christoph Hellwig @ 2019-11-01 22:06 UTC (permalink / raw)
  To: linux-xfs

Return the xfs_dir3_icfree_hdr used by the helpers called from
xfs_dir2_node_addname_int to the main function to prepare for the
next round of changes.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 fs/xfs/libxfs/xfs_dir2_node.c | 42 +++++++++++++++++------------------
 1 file changed, 20 insertions(+), 22 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_dir2_node.c b/fs/xfs/libxfs/xfs_dir2_node.c
index 26032eba1e32..d400243c9556 100644
--- a/fs/xfs/libxfs/xfs_dir2_node.c
+++ b/fs/xfs/libxfs/xfs_dir2_node.c
@@ -1660,14 +1660,13 @@ xfs_dir2_node_add_datablk(
 	xfs_dir2_db_t		*dbno,
 	struct xfs_buf		**dbpp,
 	struct xfs_buf		**fbpp,
+	struct xfs_dir3_icfree_hdr *hdr,
 	int			*findex)
 {
 	struct xfs_inode	*dp = args->dp;
 	struct xfs_trans	*tp = args->trans;
 	struct xfs_mount	*mp = dp->i_mount;
-	struct xfs_dir3_icfree_hdr freehdr;
 	struct xfs_dir2_data_free *bf;
-	struct xfs_dir2_data_hdr *hdr;
 	struct xfs_dir2_free	*free = NULL;
 	xfs_dir2_db_t		fbno;
 	struct xfs_buf		*fbp;
@@ -1730,25 +1729,25 @@ xfs_dir2_node_add_datablk(
 			return error;
 		free = fbp->b_addr;
 		bests = dp->d_ops->free_bests_p(free);
-		xfs_dir2_free_hdr_from_disk(mp, &freehdr, free);
+		xfs_dir2_free_hdr_from_disk(mp, hdr, free);
 
 		/* Remember the first slot as our empty slot. */
-		freehdr.firstdb = (fbno - xfs_dir2_byte_to_db(args->geo,
+		hdr->firstdb = (fbno - xfs_dir2_byte_to_db(args->geo,
 							XFS_DIR2_FREE_OFFSET)) *
 				dp->d_ops->free_max_bests(args->geo);
 	} else {
 		free = fbp->b_addr;
 		bests = dp->d_ops->free_bests_p(free);
-		xfs_dir2_free_hdr_from_disk(mp, &freehdr, free);
+		xfs_dir2_free_hdr_from_disk(mp, hdr, free);
 	}
 
 	/* Set the freespace block index from the data block number. */
 	*findex = dp->d_ops->db_to_fdindex(args->geo, *dbno);
 
 	/* Extend the freespace table if the new data block is off the end. */
-	if (*findex >= freehdr.nvalid) {
+	if (*findex >= hdr->nvalid) {
 		ASSERT(*findex < dp->d_ops->free_max_bests(args->geo));
-		freehdr.nvalid = *findex + 1;
+		hdr->nvalid = *findex + 1;
 		bests[*findex] = cpu_to_be16(NULLDATAOFF);
 	}
 
@@ -1757,14 +1756,13 @@ xfs_dir2_node_add_datablk(
 	 * true) then update the header.
 	 */
 	if (bests[*findex] == cpu_to_be16(NULLDATAOFF)) {
-		freehdr.nused++;
-		xfs_dir2_free_hdr_to_disk(mp, fbp->b_addr, &freehdr);
+		hdr->nused++;
+		xfs_dir2_free_hdr_to_disk(mp, fbp->b_addr, hdr);
 		xfs_dir2_free_log_header(args, fbp);
 	}
 
 	/* Update the freespace value for the new block in the table. */
-	hdr = dbp->b_addr;
-	bf = dp->d_ops->data_bestfree_p(hdr);
+	bf = dp->d_ops->data_bestfree_p(dbp->b_addr);
 	bests[*findex] = bf[0].length;
 
 	*dbpp = dbp;
@@ -1778,10 +1776,10 @@ xfs_dir2_node_find_freeblk(
 	struct xfs_da_state_blk	*fblk,
 	xfs_dir2_db_t		*dbnop,
 	struct xfs_buf		**fbpp,
+	struct xfs_dir3_icfree_hdr *hdr,
 	int			*findexp,
 	int			length)
 {
-	struct xfs_dir3_icfree_hdr freehdr;
 	struct xfs_dir2_free	*free = NULL;
 	struct xfs_inode	*dp = args->dp;
 	struct xfs_trans	*tp = args->trans;
@@ -1808,13 +1806,12 @@ xfs_dir2_node_find_freeblk(
 		if (findex >= 0) {
 			/* caller already found the freespace for us. */
 			bests = dp->d_ops->free_bests_p(free);
-			xfs_dir2_free_hdr_from_disk(dp->i_mount, &freehdr,
-						    free);
+			xfs_dir2_free_hdr_from_disk(dp->i_mount, hdr, free);
 
-			ASSERT(findex < freehdr.nvalid);
+			ASSERT(findex < hdr->nvalid);
 			ASSERT(be16_to_cpu(bests[findex]) != NULLDATAOFF);
 			ASSERT(be16_to_cpu(bests[findex]) >= length);
-			dbno = freehdr.firstdb + findex;
+			dbno = hdr->firstdb + findex;
 			goto found_block;
 		}
 
@@ -1858,13 +1855,13 @@ xfs_dir2_node_find_freeblk(
 
 		free = fbp->b_addr;
 		bests = dp->d_ops->free_bests_p(free);
-		xfs_dir2_free_hdr_from_disk(dp->i_mount, &freehdr, free);
+		xfs_dir2_free_hdr_from_disk(dp->i_mount, hdr, free);
 
 		/* Scan the free entry array for a large enough free space. */
-		for (findex = freehdr.nvalid - 1; findex >= 0; findex--) {
+		for (findex = hdr->nvalid - 1; findex >= 0; findex--) {
 			if (be16_to_cpu(bests[findex]) != NULLDATAOFF &&
 			    be16_to_cpu(bests[findex]) >= length) {
-				dbno = freehdr.firstdb + findex;
+				dbno = hdr->firstdb + findex;
 				goto found_block;
 			}
 		}
@@ -1898,6 +1895,7 @@ xfs_dir2_node_addname_int(
 	struct xfs_dir2_free	*free = NULL;	/* freespace block structure */
 	struct xfs_trans	*tp = args->trans;
 	struct xfs_inode	*dp = args->dp;
+	struct xfs_dir3_icfree_hdr freehdr;
 	struct xfs_buf		*dbp;		/* data block buffer */
 	struct xfs_buf		*fbp;		/* freespace buffer */
 	xfs_dir2_data_aoff_t	aoff;
@@ -1912,8 +1910,8 @@ xfs_dir2_node_addname_int(
 	__be16			*bests;
 
 	length = dp->d_ops->data_entsize(args->namelen);
-	error = xfs_dir2_node_find_freeblk(args, fblk, &dbno, &fbp, &findex,
-					   length);
+	error = xfs_dir2_node_find_freeblk(args, fblk, &dbno, &fbp, &freehdr,
+					   &findex, length);
 	if (error)
 		return error;
 
@@ -1935,7 +1933,7 @@ xfs_dir2_node_addname_int(
 		/* we're going to have to log the free block index later */
 		logfree = 1;
 		error = xfs_dir2_node_add_datablk(args, fblk, &dbno, &dbp, &fbp,
-						  &findex);
+						  &freehdr, &findex);
 	} else {
 		/* Read the data block in. */
 		error = xfs_dir3_data_read(tp, dp,
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 15/34] xfs: add a bests pointer to struct xfs_dir3_icfree_hdr
  2019-11-01 22:06 remove m_dirops Christoph Hellwig
                   ` (13 preceding siblings ...)
  2019-11-01 22:06 ` [PATCH 14/34] xfs: make the xfs_dir3_icfree_hdr available to xfs_dir2_node_addname_int Christoph Hellwig
@ 2019-11-01 22:07 ` Christoph Hellwig
  2019-11-04 20:21   ` Darrick J. Wong
  2019-11-01 22:07 ` [PATCH 16/34] xfs: move the dir2 free header size to struct xfs_da_geometry Christoph Hellwig
                   ` (18 subsequent siblings)
  33 siblings, 1 reply; 81+ messages in thread
From: Christoph Hellwig @ 2019-11-01 22:07 UTC (permalink / raw)
  To: linux-xfs

All but two callers of the ->free_bests_p dir operation already have a
struct xfs_dir3_icfree_hdr from a previous call to
xfs_dir2_free_hdr_from_disk at hand.  Add a pointer to the bests to
struct xfs_dir3_icfree_hdr to clean up this pattern.  To optimize this
pattern, pass the struct xfs_dir3_icfree_hdr to xfs_dir2_free_log_bests
instead of recalculating the pointer there.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 fs/xfs/libxfs/xfs_da_format.c | 15 ------
 fs/xfs/libxfs/xfs_dir2.h      |  1 -
 fs/xfs/libxfs/xfs_dir2_leaf.c |  6 +--
 fs/xfs/libxfs/xfs_dir2_node.c | 97 ++++++++++++++---------------------
 fs/xfs/libxfs/xfs_dir2_priv.h |  1 +
 fs/xfs/scrub/dir.c            |  6 +--
 6 files changed, 43 insertions(+), 83 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c
index b943d9443d55..7263b6d6a135 100644
--- a/fs/xfs/libxfs/xfs_da_format.c
+++ b/fs/xfs/libxfs/xfs_da_format.c
@@ -411,12 +411,6 @@ xfs_dir2_free_max_bests(struct xfs_da_geometry *geo)
 		sizeof(xfs_dir2_data_off_t);
 }
 
-static __be16 *
-xfs_dir2_free_bests_p(struct xfs_dir2_free *free)
-{
-	return (__be16 *)((char *)free + sizeof(struct xfs_dir2_free_hdr));
-}
-
 /*
  * Convert data space db to the corresponding free db.
  */
@@ -443,12 +437,6 @@ xfs_dir3_free_max_bests(struct xfs_da_geometry *geo)
 		sizeof(xfs_dir2_data_off_t);
 }
 
-static __be16 *
-xfs_dir3_free_bests_p(struct xfs_dir2_free *free)
-{
-	return (__be16 *)((char *)free + sizeof(struct xfs_dir3_free_hdr));
-}
-
 /*
  * Convert data space db to the corresponding free db.
  */
@@ -500,7 +488,6 @@ static const struct xfs_dir_ops xfs_dir2_ops = {
 
 	.free_hdr_size = sizeof(struct xfs_dir2_free_hdr),
 	.free_max_bests = xfs_dir2_free_max_bests,
-	.free_bests_p = xfs_dir2_free_bests_p,
 	.db_to_fdb = xfs_dir2_db_to_fdb,
 	.db_to_fdindex = xfs_dir2_db_to_fdindex,
 };
@@ -537,7 +524,6 @@ static const struct xfs_dir_ops xfs_dir2_ftype_ops = {
 
 	.free_hdr_size = sizeof(struct xfs_dir2_free_hdr),
 	.free_max_bests = xfs_dir2_free_max_bests,
-	.free_bests_p = xfs_dir2_free_bests_p,
 	.db_to_fdb = xfs_dir2_db_to_fdb,
 	.db_to_fdindex = xfs_dir2_db_to_fdindex,
 };
@@ -574,7 +560,6 @@ static const struct xfs_dir_ops xfs_dir3_ops = {
 
 	.free_hdr_size = sizeof(struct xfs_dir3_free_hdr),
 	.free_max_bests = xfs_dir3_free_max_bests,
-	.free_bests_p = xfs_dir3_free_bests_p,
 	.db_to_fdb = xfs_dir3_db_to_fdb,
 	.db_to_fdindex = xfs_dir3_db_to_fdindex,
 };
diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h
index 613a78281d03..402f00326b64 100644
--- a/fs/xfs/libxfs/xfs_dir2.h
+++ b/fs/xfs/libxfs/xfs_dir2.h
@@ -74,7 +74,6 @@ struct xfs_dir_ops {
 
 	int	free_hdr_size;
 	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,
 				   xfs_dir2_db_t db);
 	int	(*db_to_fdindex)(struct xfs_da_geometry *geo,
diff --git a/fs/xfs/libxfs/xfs_dir2_leaf.c b/fs/xfs/libxfs/xfs_dir2_leaf.c
index 4b697dd85eab..3770107c0695 100644
--- a/fs/xfs/libxfs/xfs_dir2_leaf.c
+++ b/fs/xfs/libxfs/xfs_dir2_leaf.c
@@ -1678,7 +1678,6 @@ xfs_dir2_node_to_leaf(
 	int			error;		/* error return code */
 	struct xfs_buf		*fbp;		/* buffer for freespace block */
 	xfs_fileoff_t		fo;		/* freespace file offset */
-	xfs_dir2_free_t		*free;		/* freespace structure */
 	struct xfs_buf		*lbp;		/* buffer for leaf block */
 	xfs_dir2_leaf_tail_t	*ltp;		/* tail of leaf structure */
 	xfs_dir2_leaf_t		*leaf;		/* leaf structure */
@@ -1747,8 +1746,7 @@ xfs_dir2_node_to_leaf(
 	error = xfs_dir2_free_read(tp, dp,  args->geo->freeblk, &fbp);
 	if (error)
 		return error;
-	free = fbp->b_addr;
-	xfs_dir2_free_hdr_from_disk(mp, &freehdr, free);
+	xfs_dir2_free_hdr_from_disk(mp, &freehdr, fbp->b_addr);
 
 	ASSERT(!freehdr.firstdb);
 
@@ -1782,7 +1780,7 @@ xfs_dir2_node_to_leaf(
 	/*
 	 * Set up the leaf bests table.
 	 */
-	memcpy(xfs_dir2_leaf_bests_p(ltp), dp->d_ops->free_bests_p(free),
+	memcpy(xfs_dir2_leaf_bests_p(ltp), freehdr.bests,
 		freehdr.nvalid * sizeof(xfs_dir2_data_off_t));
 
 	xfs_dir2_leaf_hdr_to_disk(mp, leaf, &leafhdr);
diff --git a/fs/xfs/libxfs/xfs_dir2_node.c b/fs/xfs/libxfs/xfs_dir2_node.c
index d400243c9556..eff7cfeb19b9 100644
--- a/fs/xfs/libxfs/xfs_dir2_node.c
+++ b/fs/xfs/libxfs/xfs_dir2_node.c
@@ -233,6 +233,7 @@ xfs_dir2_free_hdr_from_disk(
 		to->firstdb = be32_to_cpu(from3->hdr.firstdb);
 		to->nvalid = be32_to_cpu(from3->hdr.nvalid);
 		to->nused = be32_to_cpu(from3->hdr.nused);
+		to->bests = (void *)from3 + sizeof(struct xfs_dir3_free_hdr);
 
 		ASSERT(to->magic == XFS_DIR3_FREE_MAGIC);
 	} else {
@@ -240,6 +241,8 @@ xfs_dir2_free_hdr_from_disk(
 		to->firstdb = be32_to_cpu(from->hdr.firstdb);
 		to->nvalid = be32_to_cpu(from->hdr.nvalid);
 		to->nused = be32_to_cpu(from->hdr.nused);
+		to->bests = (void *)from + sizeof(struct xfs_dir2_free_hdr);
+
 		ASSERT(to->magic == XFS_DIR2_FREE_MAGIC);
 	}
 }
@@ -338,21 +341,19 @@ xfs_dir3_free_get_buf(
 STATIC void
 xfs_dir2_free_log_bests(
 	struct xfs_da_args	*args,
+	struct xfs_dir3_icfree_hdr *hdr,
 	struct xfs_buf		*bp,
 	int			first,		/* first entry to log */
 	int			last)		/* last entry to log */
 {
-	xfs_dir2_free_t		*free;		/* freespace structure */
-	__be16			*bests;
+	struct xfs_dir2_free	*free = bp->b_addr;
 
-	free = bp->b_addr;
-	bests = args->dp->d_ops->free_bests_p(free);
 	ASSERT(free->hdr.magic == cpu_to_be32(XFS_DIR2_FREE_MAGIC) ||
 	       free->hdr.magic == cpu_to_be32(XFS_DIR3_FREE_MAGIC));
 	xfs_trans_log_buf(args->trans, bp,
-		(uint)((char *)&bests[first] - (char *)free),
-		(uint)((char *)&bests[last] - (char *)free +
-		       sizeof(bests[0]) - 1));
+			  (char *)&hdr->bests[first] - (char *)free,
+			  (char *)&hdr->bests[last] - (char *)free +
+			   sizeof(hdr->bests[0]) - 1);
 }
 
 /*
@@ -388,14 +389,12 @@ xfs_dir2_leaf_to_node(
 	int			error;		/* error return value */
 	struct xfs_buf		*fbp;		/* freespace buffer */
 	xfs_dir2_db_t		fdb;		/* freespace block number */
-	xfs_dir2_free_t		*free;		/* freespace structure */
 	__be16			*from;		/* pointer to freespace entry */
 	int			i;		/* leaf freespace index */
 	xfs_dir2_leaf_t		*leaf;		/* leaf structure */
 	xfs_dir2_leaf_tail_t	*ltp;		/* leaf tail structure */
 	int			n;		/* count of live freespc ents */
 	xfs_dir2_data_off_t	off;		/* freespace entry value */
-	__be16			*to;		/* pointer to freespace entry */
 	xfs_trans_t		*tp;		/* transaction pointer */
 	struct xfs_dir3_icfree_hdr freehdr;
 
@@ -417,8 +416,7 @@ xfs_dir2_leaf_to_node(
 	if (error)
 		return error;
 
-	free = fbp->b_addr;
-	xfs_dir2_free_hdr_from_disk(dp->i_mount, &freehdr, free);
+	xfs_dir2_free_hdr_from_disk(dp->i_mount, &freehdr, fbp->b_addr);
 	leaf = lbp->b_addr;
 	ltp = xfs_dir2_leaf_tail_p(args->geo, leaf);
 	if (be32_to_cpu(ltp->bestcount) >
@@ -430,11 +428,11 @@ xfs_dir2_leaf_to_node(
 	 * Count active entries.
 	 */
 	from = xfs_dir2_leaf_bests_p(ltp);
-	to = dp->d_ops->free_bests_p(free);
-	for (i = n = 0; i < be32_to_cpu(ltp->bestcount); i++, from++, to++) {
-		if ((off = be16_to_cpu(*from)) != NULLDATAOFF)
+	for (i = n = 0; i < be32_to_cpu(ltp->bestcount); i++, from++) {
+		off = be16_to_cpu(*from);
+		if (off != NULLDATAOFF)
 			n++;
-		*to = cpu_to_be16(off);
+		freehdr.bests[i] = cpu_to_be16(off);
 	}
 
 	/*
@@ -444,7 +442,7 @@ xfs_dir2_leaf_to_node(
 	freehdr.nvalid = be32_to_cpu(ltp->bestcount);
 
 	xfs_dir2_free_hdr_to_disk(dp->i_mount, fbp->b_addr, &freehdr);
-	xfs_dir2_free_log_bests(args, fbp, 0, freehdr.nvalid - 1);
+	xfs_dir2_free_log_bests(args, &freehdr, fbp, 0, freehdr.nvalid - 1);
 	xfs_dir2_free_log_header(args, fbp);
 
 	/*
@@ -673,7 +671,7 @@ xfs_dir2_leafn_lookup_for_addname(
 		 * in hand, take a look at it.
 		 */
 		if (newdb != curdb) {
-			__be16 *bests;
+			struct xfs_dir3_icfree_hdr freehdr;
 
 			curdb = newdb;
 			/*
@@ -708,8 +706,9 @@ xfs_dir2_leafn_lookup_for_addname(
 			/*
 			 * If it has room, return it.
 			 */
-			bests = dp->d_ops->free_bests_p(free);
-			if (unlikely(bests[fi] == cpu_to_be16(NULLDATAOFF))) {
+			xfs_dir2_free_hdr_from_disk(mp, &freehdr, free);
+			if (unlikely(freehdr.bests[fi] ==
+				     cpu_to_be16(NULLDATAOFF))) {
 				XFS_ERROR_REPORT("xfs_dir2_leafn_lookup_int",
 							XFS_ERRLEVEL_LOW, mp);
 				if (curfdb != newfdb)
@@ -717,7 +716,7 @@ xfs_dir2_leafn_lookup_for_addname(
 				return -EFSCORRUPTED;
 			}
 			curfdb = newfdb;
-			if (be16_to_cpu(bests[fi]) >= length)
+			if (be16_to_cpu(freehdr.bests[fi]) >= length)
 				goto out;
 		}
 	}
@@ -1162,19 +1161,17 @@ xfs_dir3_data_block_free(
 	int			longest)
 {
 	int			logfree = 0;
-	__be16			*bests;
 	struct xfs_dir3_icfree_hdr freehdr;
 	struct xfs_inode	*dp = args->dp;
 
 	xfs_dir2_free_hdr_from_disk(dp->i_mount, &freehdr, free);
-	bests = dp->d_ops->free_bests_p(free);
 	if (hdr) {
 		/*
 		 * Data block is not empty, just set the free entry to the new
 		 * value.
 		 */
-		bests[findex] = cpu_to_be16(longest);
-		xfs_dir2_free_log_bests(args, fbp, findex, findex);
+		freehdr.bests[findex] = cpu_to_be16(longest);
+		xfs_dir2_free_log_bests(args, &freehdr, fbp, findex, findex);
 		return 0;
 	}
 
@@ -1190,14 +1187,14 @@ xfs_dir3_data_block_free(
 		int	i;		/* free entry index */
 
 		for (i = findex - 1; i >= 0; i--) {
-			if (bests[i] != cpu_to_be16(NULLDATAOFF))
+			if (freehdr.bests[i] != cpu_to_be16(NULLDATAOFF))
 				break;
 		}
 		freehdr.nvalid = i + 1;
 		logfree = 0;
 	} else {
 		/* Not the last entry, just punch it out.  */
-		bests[findex] = cpu_to_be16(NULLDATAOFF);
+		freehdr.bests[findex] = cpu_to_be16(NULLDATAOFF);
 		logfree = 1;
 	}
 
@@ -1226,7 +1223,7 @@ xfs_dir3_data_block_free(
 
 	/* Log the free entry that changed, unless we got rid of it.  */
 	if (logfree)
-		xfs_dir2_free_log_bests(args, fbp, findex, findex);
+		xfs_dir2_free_log_bests(args, &freehdr, fbp, findex, findex);
 	return 0;
 }
 
@@ -1667,11 +1664,9 @@ xfs_dir2_node_add_datablk(
 	struct xfs_trans	*tp = args->trans;
 	struct xfs_mount	*mp = dp->i_mount;
 	struct xfs_dir2_data_free *bf;
-	struct xfs_dir2_free	*free = NULL;
 	xfs_dir2_db_t		fbno;
 	struct xfs_buf		*fbp;
 	struct xfs_buf		*dbp;
-	__be16			*bests = NULL;
 	int			error;
 
 	/* Not allowed to allocate, return failure. */
@@ -1727,18 +1722,14 @@ xfs_dir2_node_add_datablk(
 		error = xfs_dir3_free_get_buf(args, fbno, &fbp);
 		if (error)
 			return error;
-		free = fbp->b_addr;
-		bests = dp->d_ops->free_bests_p(free);
-		xfs_dir2_free_hdr_from_disk(mp, hdr, free);
+		xfs_dir2_free_hdr_from_disk(mp, hdr, fbp->b_addr);
 
 		/* Remember the first slot as our empty slot. */
 		hdr->firstdb = (fbno - xfs_dir2_byte_to_db(args->geo,
 							XFS_DIR2_FREE_OFFSET)) *
 				dp->d_ops->free_max_bests(args->geo);
 	} else {
-		free = fbp->b_addr;
-		bests = dp->d_ops->free_bests_p(free);
-		xfs_dir2_free_hdr_from_disk(mp, hdr, free);
+		xfs_dir2_free_hdr_from_disk(mp, hdr, fbp->b_addr);
 	}
 
 	/* Set the freespace block index from the data block number. */
@@ -1748,14 +1739,14 @@ xfs_dir2_node_add_datablk(
 	if (*findex >= hdr->nvalid) {
 		ASSERT(*findex < dp->d_ops->free_max_bests(args->geo));
 		hdr->nvalid = *findex + 1;
-		bests[*findex] = cpu_to_be16(NULLDATAOFF);
+		hdr->bests[*findex] = cpu_to_be16(NULLDATAOFF);
 	}
 
 	/*
 	 * If this entry was for an empty data block (this should always be
 	 * true) then update the header.
 	 */
-	if (bests[*findex] == cpu_to_be16(NULLDATAOFF)) {
+	if (hdr->bests[*findex] == cpu_to_be16(NULLDATAOFF)) {
 		hdr->nused++;
 		xfs_dir2_free_hdr_to_disk(mp, fbp->b_addr, hdr);
 		xfs_dir2_free_log_header(args, fbp);
@@ -1763,7 +1754,7 @@ xfs_dir2_node_add_datablk(
 
 	/* Update the freespace value for the new block in the table. */
 	bf = dp->d_ops->data_bestfree_p(dbp->b_addr);
-	bests[*findex] = bf[0].length;
+	hdr->bests[*findex] = bf[0].length;
 
 	*dbpp = dbp;
 	*fbpp = fbp;
@@ -1780,7 +1771,6 @@ xfs_dir2_node_find_freeblk(
 	int			*findexp,
 	int			length)
 {
-	struct xfs_dir2_free	*free = NULL;
 	struct xfs_inode	*dp = args->dp;
 	struct xfs_trans	*tp = args->trans;
 	struct xfs_buf		*fbp = NULL;
@@ -1790,7 +1780,6 @@ xfs_dir2_node_find_freeblk(
 	xfs_dir2_db_t		dbno = -1;
 	xfs_dir2_db_t		fbno;
 	xfs_fileoff_t		fo;
-	__be16			*bests = NULL;
 	int			findex = 0;
 	int			error;
 
@@ -1801,16 +1790,13 @@ xfs_dir2_node_find_freeblk(
 	 */
 	if (fblk) {
 		fbp = fblk->bp;
-		free = fbp->b_addr;
 		findex = fblk->index;
+		xfs_dir2_free_hdr_from_disk(dp->i_mount, hdr, fbp->b_addr);
 		if (findex >= 0) {
 			/* caller already found the freespace for us. */
-			bests = dp->d_ops->free_bests_p(free);
-			xfs_dir2_free_hdr_from_disk(dp->i_mount, hdr, free);
-
 			ASSERT(findex < hdr->nvalid);
-			ASSERT(be16_to_cpu(bests[findex]) != NULLDATAOFF);
-			ASSERT(be16_to_cpu(bests[findex]) >= length);
+			ASSERT(be16_to_cpu(hdr->bests[findex]) != NULLDATAOFF);
+			ASSERT(be16_to_cpu(hdr->bests[findex]) >= length);
 			dbno = hdr->firstdb + findex;
 			goto found_block;
 		}
@@ -1853,14 +1839,12 @@ xfs_dir2_node_find_freeblk(
 		if (!fbp)
 			continue;
 
-		free = fbp->b_addr;
-		bests = dp->d_ops->free_bests_p(free);
-		xfs_dir2_free_hdr_from_disk(dp->i_mount, hdr, free);
+		xfs_dir2_free_hdr_from_disk(dp->i_mount, hdr, fbp->b_addr);
 
 		/* Scan the free entry array for a large enough free space. */
 		for (findex = hdr->nvalid - 1; findex >= 0; findex--) {
-			if (be16_to_cpu(bests[findex]) != NULLDATAOFF &&
-			    be16_to_cpu(bests[findex]) >= length) {
+			if (be16_to_cpu(hdr->bests[findex]) != NULLDATAOFF &&
+			    be16_to_cpu(hdr->bests[findex]) >= length) {
 				dbno = hdr->firstdb + findex;
 				goto found_block;
 			}
@@ -1877,7 +1861,6 @@ xfs_dir2_node_find_freeblk(
 	return 0;
 }
 
-
 /*
  * Add the data entry for a node-format directory name addition.
  * The leaf entry is added in xfs_dir2_leafn_add.
@@ -1892,7 +1875,6 @@ xfs_dir2_node_addname_int(
 	struct xfs_dir2_data_entry *dep;	/* data entry pointer */
 	struct xfs_dir2_data_hdr *hdr;		/* data block header */
 	struct xfs_dir2_data_free *bf;
-	struct xfs_dir2_free	*free = NULL;	/* freespace block structure */
 	struct xfs_trans	*tp = args->trans;
 	struct xfs_inode	*dp = args->dp;
 	struct xfs_dir3_icfree_hdr freehdr;
@@ -1907,7 +1889,6 @@ xfs_dir2_node_addname_int(
 	int			needlog = 0;	/* need to log data header */
 	int			needscan = 0;	/* need to rescan data frees */
 	__be16			*tagp;		/* data entry tag pointer */
-	__be16			*bests;
 
 	length = dp->d_ops->data_entsize(args->namelen);
 	error = xfs_dir2_node_find_freeblk(args, fblk, &dbno, &fbp, &freehdr,
@@ -1978,16 +1959,14 @@ xfs_dir2_node_addname_int(
 		xfs_dir2_data_log_header(args, dbp);
 
 	/* If the freespace block entry is now wrong, update it. */
-	free = fbp->b_addr;
-	bests = dp->d_ops->free_bests_p(free);
-	if (bests[findex] != bf[0].length) {
-		bests[findex] = bf[0].length;
+	if (freehdr.bests[findex] != bf[0].length) {
+		freehdr.bests[findex] = bf[0].length;
 		logfree = 1;
 	}
 
 	/* Log the freespace entry if needed. */
 	if (logfree)
-		xfs_dir2_free_log_bests(args, fbp, findex, findex);
+		xfs_dir2_free_log_bests(args, &freehdr, fbp, findex, findex);
 
 	/* Return the data block and offset in args. */
 	args->blkno = (xfs_dablk_t)dbno;
diff --git a/fs/xfs/libxfs/xfs_dir2_priv.h b/fs/xfs/libxfs/xfs_dir2_priv.h
index ef4a2b402e25..b73cf38c6969 100644
--- a/fs/xfs/libxfs/xfs_dir2_priv.h
+++ b/fs/xfs/libxfs/xfs_dir2_priv.h
@@ -26,6 +26,7 @@ struct xfs_dir3_icfree_hdr {
 	uint32_t		firstdb;
 	uint32_t		nvalid;
 	uint32_t		nused;
+	__be16			*bests;
 };
 
 /* xfs_dir2.c */
diff --git a/fs/xfs/scrub/dir.c b/fs/xfs/scrub/dir.c
index 6b8d9a774ddf..dfaa0fca617e 100644
--- a/fs/xfs/scrub/dir.c
+++ b/fs/xfs/scrub/dir.c
@@ -581,7 +581,6 @@ xchk_directory_free_bestfree(
 	struct xfs_dir3_icfree_hdr	freehdr;
 	struct xfs_buf			*dbp;
 	struct xfs_buf			*bp;
-	__be16				*bestp;
 	__u16				best;
 	unsigned int			stale = 0;
 	int				i;
@@ -602,9 +601,8 @@ xchk_directory_free_bestfree(
 
 	/* Check all the entries. */
 	xfs_dir2_free_hdr_from_disk(sc->ip->i_mount, &freehdr, bp->b_addr);
-	bestp = sc->ip->d_ops->free_bests_p(bp->b_addr);
-	for (i = 0; i < freehdr.nvalid; i++, bestp++) {
-		best = be16_to_cpu(*bestp);
+	for (i = 0; i < freehdr.nvalid; i++) {
+		best = be16_to_cpu(freehdr.bests[i]);
 		if (best == NULLDATAOFF) {
 			stale++;
 			continue;
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 16/34] xfs: move the dir2 free header size to struct xfs_da_geometry
  2019-11-01 22:06 remove m_dirops Christoph Hellwig
                   ` (14 preceding siblings ...)
  2019-11-01 22:07 ` [PATCH 15/34] xfs: add a bests pointer to struct xfs_dir3_icfree_hdr Christoph Hellwig
@ 2019-11-01 22:07 ` Christoph Hellwig
  2019-11-04 20:22   ` Darrick J. Wong
  2019-11-01 22:07 ` [PATCH 17/34] xfs: move the max dir2 free bests count " Christoph Hellwig
                   ` (17 subsequent siblings)
  33 siblings, 1 reply; 81+ messages in thread
From: Christoph Hellwig @ 2019-11-01 22:07 UTC (permalink / raw)
  To: linux-xfs

Move the free header size towards our structure for dir/attr geometry
parameters.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 fs/xfs/libxfs/xfs_da_btree.h  | 1 +
 fs/xfs/libxfs/xfs_da_format.c | 3 ---
 fs/xfs/libxfs/xfs_dir2.c      | 2 ++
 fs/xfs/libxfs/xfs_dir2.h      | 1 -
 fs/xfs/libxfs/xfs_dir2_node.c | 2 +-
 5 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_da_btree.h b/fs/xfs/libxfs/xfs_da_btree.h
index c8b137685ca7..3d0b1e97bf43 100644
--- a/fs/xfs/libxfs/xfs_da_btree.h
+++ b/fs/xfs/libxfs/xfs_da_btree.h
@@ -29,6 +29,7 @@ struct xfs_da_geometry {
 	int		leaf_hdr_size;	/* dir2 leaf header size */
 	unsigned int	leaf_max_ents;	/* # of entries in dir2 leaf */
 	xfs_dablk_t	leafblk;	/* blockno of leaf data v2 */
+	int		free_hdr_size;	/* dir2 free header size */
 	xfs_dablk_t	freeblk;	/* blockno of free data v2 */
 };
 
diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c
index 7263b6d6a135..1fc8982c830f 100644
--- a/fs/xfs/libxfs/xfs_da_format.c
+++ b/fs/xfs/libxfs/xfs_da_format.c
@@ -486,7 +486,6 @@ static const struct xfs_dir_ops xfs_dir2_ops = {
 	.data_entry_p = xfs_dir2_data_entry_p,
 	.data_unused_p = xfs_dir2_data_unused_p,
 
-	.free_hdr_size = sizeof(struct xfs_dir2_free_hdr),
 	.free_max_bests = xfs_dir2_free_max_bests,
 	.db_to_fdb = xfs_dir2_db_to_fdb,
 	.db_to_fdindex = xfs_dir2_db_to_fdindex,
@@ -522,7 +521,6 @@ static const struct xfs_dir_ops xfs_dir2_ftype_ops = {
 	.data_entry_p = xfs_dir2_data_entry_p,
 	.data_unused_p = xfs_dir2_data_unused_p,
 
-	.free_hdr_size = sizeof(struct xfs_dir2_free_hdr),
 	.free_max_bests = xfs_dir2_free_max_bests,
 	.db_to_fdb = xfs_dir2_db_to_fdb,
 	.db_to_fdindex = xfs_dir2_db_to_fdindex,
@@ -558,7 +556,6 @@ static const struct xfs_dir_ops xfs_dir3_ops = {
 	.data_entry_p = xfs_dir3_data_entry_p,
 	.data_unused_p = xfs_dir3_data_unused_p,
 
-	.free_hdr_size = sizeof(struct xfs_dir3_free_hdr),
 	.free_max_bests = xfs_dir3_free_max_bests,
 	.db_to_fdb = xfs_dir3_db_to_fdb,
 	.db_to_fdindex = xfs_dir3_db_to_fdindex,
diff --git a/fs/xfs/libxfs/xfs_dir2.c b/fs/xfs/libxfs/xfs_dir2.c
index 9f88b9885747..13ac228bfc86 100644
--- a/fs/xfs/libxfs/xfs_dir2.c
+++ b/fs/xfs/libxfs/xfs_dir2.c
@@ -125,9 +125,11 @@ xfs_da_mount(
 	if (xfs_sb_version_hascrc(&mp->m_sb)) {
 		dageo->node_hdr_size = sizeof(struct xfs_da3_node_hdr);
 		dageo->leaf_hdr_size = sizeof(struct xfs_dir3_leaf_hdr);
+		dageo->free_hdr_size = sizeof(struct xfs_dir3_free_hdr);
 	} else {
 		dageo->node_hdr_size = sizeof(struct xfs_da_node_hdr);
 		dageo->leaf_hdr_size = sizeof(struct xfs_dir2_leaf_hdr);
+		dageo->free_hdr_size = sizeof(struct xfs_dir2_free_hdr);
 	}
 	dageo->leaf_max_ents = (dageo->blksize - dageo->leaf_hdr_size) /
 			sizeof(struct xfs_dir2_leaf_entry);
diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h
index 402f00326b64..d87cd71e3cf1 100644
--- a/fs/xfs/libxfs/xfs_dir2.h
+++ b/fs/xfs/libxfs/xfs_dir2.h
@@ -72,7 +72,6 @@ struct xfs_dir_ops {
 	struct xfs_dir2_data_unused *
 		(*data_unused_p)(struct xfs_dir2_data_hdr *hdr);
 
-	int	free_hdr_size;
 	int	(*free_max_bests)(struct xfs_da_geometry *geo);
 	xfs_dir2_db_t (*db_to_fdb)(struct xfs_da_geometry *geo,
 				   xfs_dir2_db_t db);
diff --git a/fs/xfs/libxfs/xfs_dir2_node.c b/fs/xfs/libxfs/xfs_dir2_node.c
index eff7cfeb19b9..7047d1e066f9 100644
--- a/fs/xfs/libxfs/xfs_dir2_node.c
+++ b/fs/xfs/libxfs/xfs_dir2_node.c
@@ -372,7 +372,7 @@ xfs_dir2_free_log_header(
 	       free->hdr.magic == cpu_to_be32(XFS_DIR3_FREE_MAGIC));
 #endif
 	xfs_trans_log_buf(args->trans, bp, 0,
-			  args->dp->d_ops->free_hdr_size - 1);
+			  args->geo->free_hdr_size - 1);
 }
 
 /*
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 17/34] xfs: move the max dir2 free bests count to struct xfs_da_geometry
  2019-11-01 22:06 remove m_dirops Christoph Hellwig
                   ` (15 preceding siblings ...)
  2019-11-01 22:07 ` [PATCH 16/34] xfs: move the dir2 free header size to struct xfs_da_geometry Christoph Hellwig
@ 2019-11-01 22:07 ` Christoph Hellwig
  2019-11-04 20:23   ` Darrick J. Wong
  2019-11-01 22:07 ` [PATCH 18/34] xfs: devirtualize ->db_to_fdb and ->db_to_fdindex Christoph Hellwig
                   ` (16 subsequent siblings)
  33 siblings, 1 reply; 81+ messages in thread
From: Christoph Hellwig @ 2019-11-01 22:07 UTC (permalink / raw)
  To: linux-xfs

Move the max free bests count towards our structure for dir/attr
geometry parameters.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 fs/xfs/libxfs/xfs_da_btree.h  |  1 +
 fs/xfs/libxfs/xfs_da_format.c | 29 ++++-------------------------
 fs/xfs/libxfs/xfs_dir2.c      |  2 ++
 fs/xfs/libxfs/xfs_dir2.h      |  1 -
 fs/xfs/libxfs/xfs_dir2_node.c | 12 +++++-------
 5 files changed, 12 insertions(+), 33 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_da_btree.h b/fs/xfs/libxfs/xfs_da_btree.h
index 3d0b1e97bf43..e3f4329ab882 100644
--- a/fs/xfs/libxfs/xfs_da_btree.h
+++ b/fs/xfs/libxfs/xfs_da_btree.h
@@ -30,6 +30,7 @@ struct xfs_da_geometry {
 	unsigned int	leaf_max_ents;	/* # of entries in dir2 leaf */
 	xfs_dablk_t	leafblk;	/* blockno of leaf data v2 */
 	int		free_hdr_size;	/* dir2 free header size */
+	unsigned int	free_max_bests;	/* # of bests entries in dir2 free */
 	xfs_dablk_t	freeblk;	/* blockno of free data v2 */
 };
 
diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c
index 1fc8982c830f..d2d3144c1598 100644
--- a/fs/xfs/libxfs/xfs_da_format.c
+++ b/fs/xfs/libxfs/xfs_da_format.c
@@ -400,17 +400,6 @@ xfs_dir3_data_unused_p(struct xfs_dir2_data_hdr *hdr)
 		((char *)hdr + sizeof(struct xfs_dir3_data_hdr));
 }
 
-
-/*
- * Directory free space block operations
- */
-static int
-xfs_dir2_free_max_bests(struct xfs_da_geometry *geo)
-{
-	return (geo->blksize - sizeof(struct xfs_dir2_free_hdr)) /
-		sizeof(xfs_dir2_data_off_t);
-}
-
 /*
  * Convert data space db to the corresponding free db.
  */
@@ -418,7 +407,7 @@ static xfs_dir2_db_t
 xfs_dir2_db_to_fdb(struct xfs_da_geometry *geo, xfs_dir2_db_t db)
 {
 	return xfs_dir2_byte_to_db(geo, XFS_DIR2_FREE_OFFSET) +
-			(db / xfs_dir2_free_max_bests(geo));
+			(db / geo->free_max_bests);
 }
 
 /*
@@ -427,14 +416,7 @@ xfs_dir2_db_to_fdb(struct xfs_da_geometry *geo, xfs_dir2_db_t db)
 static int
 xfs_dir2_db_to_fdindex(struct xfs_da_geometry *geo, xfs_dir2_db_t db)
 {
-	return db % xfs_dir2_free_max_bests(geo);
-}
-
-static int
-xfs_dir3_free_max_bests(struct xfs_da_geometry *geo)
-{
-	return (geo->blksize - sizeof(struct xfs_dir3_free_hdr)) /
-		sizeof(xfs_dir2_data_off_t);
+	return db % geo->free_max_bests;
 }
 
 /*
@@ -444,7 +426,7 @@ static xfs_dir2_db_t
 xfs_dir3_db_to_fdb(struct xfs_da_geometry *geo, xfs_dir2_db_t db)
 {
 	return xfs_dir2_byte_to_db(geo, XFS_DIR2_FREE_OFFSET) +
-			(db / xfs_dir3_free_max_bests(geo));
+			(db / geo->free_max_bests);
 }
 
 /*
@@ -453,7 +435,7 @@ xfs_dir3_db_to_fdb(struct xfs_da_geometry *geo, xfs_dir2_db_t db)
 static int
 xfs_dir3_db_to_fdindex(struct xfs_da_geometry *geo, xfs_dir2_db_t db)
 {
-	return db % xfs_dir3_free_max_bests(geo);
+	return db % geo->free_max_bests;
 }
 
 static const struct xfs_dir_ops xfs_dir2_ops = {
@@ -486,7 +468,6 @@ static const struct xfs_dir_ops xfs_dir2_ops = {
 	.data_entry_p = xfs_dir2_data_entry_p,
 	.data_unused_p = xfs_dir2_data_unused_p,
 
-	.free_max_bests = xfs_dir2_free_max_bests,
 	.db_to_fdb = xfs_dir2_db_to_fdb,
 	.db_to_fdindex = xfs_dir2_db_to_fdindex,
 };
@@ -521,7 +502,6 @@ static const struct xfs_dir_ops xfs_dir2_ftype_ops = {
 	.data_entry_p = xfs_dir2_data_entry_p,
 	.data_unused_p = xfs_dir2_data_unused_p,
 
-	.free_max_bests = xfs_dir2_free_max_bests,
 	.db_to_fdb = xfs_dir2_db_to_fdb,
 	.db_to_fdindex = xfs_dir2_db_to_fdindex,
 };
@@ -556,7 +536,6 @@ static const struct xfs_dir_ops xfs_dir3_ops = {
 	.data_entry_p = xfs_dir3_data_entry_p,
 	.data_unused_p = xfs_dir3_data_unused_p,
 
-	.free_max_bests = xfs_dir3_free_max_bests,
 	.db_to_fdb = xfs_dir3_db_to_fdb,
 	.db_to_fdindex = xfs_dir3_db_to_fdindex,
 };
diff --git a/fs/xfs/libxfs/xfs_dir2.c b/fs/xfs/libxfs/xfs_dir2.c
index 13ac228bfc86..6c46893af17e 100644
--- a/fs/xfs/libxfs/xfs_dir2.c
+++ b/fs/xfs/libxfs/xfs_dir2.c
@@ -133,6 +133,8 @@ xfs_da_mount(
 	}
 	dageo->leaf_max_ents = (dageo->blksize - dageo->leaf_hdr_size) /
 			sizeof(struct xfs_dir2_leaf_entry);
+	dageo->free_max_bests = (dageo->blksize - dageo->free_hdr_size) /
+			sizeof(xfs_dir2_data_off_t);
 
 	/*
 	 * Now we've set up the block conversion variables, we can calculate the
diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h
index d87cd71e3cf1..e3c1385d1522 100644
--- a/fs/xfs/libxfs/xfs_dir2.h
+++ b/fs/xfs/libxfs/xfs_dir2.h
@@ -72,7 +72,6 @@ struct xfs_dir_ops {
 	struct xfs_dir2_data_unused *
 		(*data_unused_p)(struct xfs_dir2_data_hdr *hdr);
 
-	int	(*free_max_bests)(struct xfs_da_geometry *geo);
 	xfs_dir2_db_t (*db_to_fdb)(struct xfs_da_geometry *geo,
 				   xfs_dir2_db_t db);
 	int	(*db_to_fdindex)(struct xfs_da_geometry *geo,
diff --git a/fs/xfs/libxfs/xfs_dir2_node.c b/fs/xfs/libxfs/xfs_dir2_node.c
index 7047d1e066f9..0fcd7351038e 100644
--- a/fs/xfs/libxfs/xfs_dir2_node.c
+++ b/fs/xfs/libxfs/xfs_dir2_node.c
@@ -160,10 +160,9 @@ xfs_dir3_free_header_check(
 	struct xfs_buf		*bp)
 {
 	struct xfs_mount	*mp = dp->i_mount;
+	int			maxbests = mp->m_dir_geo->free_max_bests;
 	unsigned int		firstdb;
-	int			maxbests;
 
-	maxbests = dp->d_ops->free_max_bests(mp->m_dir_geo);
 	firstdb = (xfs_dir2_da_to_db(mp->m_dir_geo, fbno) -
 		   xfs_dir2_byte_to_db(mp->m_dir_geo, XFS_DIR2_FREE_OFFSET)) *
 			maxbests;
@@ -558,8 +557,7 @@ xfs_dir2_free_hdr_check(
 
 	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);
+	ASSERT((hdr.firstdb % dp->i_mount->m_dir_geo->free_max_bests) == 0);
 	ASSERT(hdr.firstdb <= db);
 	ASSERT(db < hdr.firstdb + hdr.nvalid);
 }
@@ -1334,7 +1332,7 @@ xfs_dir2_leafn_remove(
 		struct xfs_dir3_icfree_hdr freehdr;
 
 		xfs_dir2_free_hdr_from_disk(dp->i_mount, &freehdr, free);
-		ASSERT(freehdr.firstdb == dp->d_ops->free_max_bests(args->geo) *
+		ASSERT(freehdr.firstdb == args->geo->free_max_bests *
 			(fdb - xfs_dir2_byte_to_db(args->geo,
 						   XFS_DIR2_FREE_OFFSET)));
 	}
@@ -1727,7 +1725,7 @@ xfs_dir2_node_add_datablk(
 		/* Remember the first slot as our empty slot. */
 		hdr->firstdb = (fbno - xfs_dir2_byte_to_db(args->geo,
 							XFS_DIR2_FREE_OFFSET)) *
-				dp->d_ops->free_max_bests(args->geo);
+				args->geo->free_max_bests;
 	} else {
 		xfs_dir2_free_hdr_from_disk(mp, hdr, fbp->b_addr);
 	}
@@ -1737,7 +1735,7 @@ xfs_dir2_node_add_datablk(
 
 	/* Extend the freespace table if the new data block is off the end. */
 	if (*findex >= hdr->nvalid) {
-		ASSERT(*findex < dp->d_ops->free_max_bests(args->geo));
+		ASSERT(*findex < args->geo->free_max_bests);
 		hdr->nvalid = *findex + 1;
 		hdr->bests[*findex] = cpu_to_be16(NULLDATAOFF);
 	}
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 18/34] xfs: devirtualize ->db_to_fdb and ->db_to_fdindex
  2019-11-01 22:06 remove m_dirops Christoph Hellwig
                   ` (16 preceding siblings ...)
  2019-11-01 22:07 ` [PATCH 17/34] xfs: move the max dir2 free bests count " Christoph Hellwig
@ 2019-11-01 22:07 ` Christoph Hellwig
  2019-11-04 20:26   ` Darrick J. Wong
  2019-11-01 22:07 ` [PATCH 19/34] xfs: devirtualize ->sf_get_parent_ino and ->sf_put_parent_ino Christoph Hellwig
                   ` (15 subsequent siblings)
  33 siblings, 1 reply; 81+ messages in thread
From: Christoph Hellwig @ 2019-11-01 22:07 UTC (permalink / raw)
  To: linux-xfs

Now that the max bests value is in struct xfs_da_geometry both instances
of ->db_to_fdb and ->db_to_fdindex are identical.  Replace them with
local xfs_dir2_db_to_fdb and xfs_dir2_db_to_fdindex functions in
xfs_dir2_node.c.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 fs/xfs/libxfs/xfs_da_format.c | 47 -----------------------------------
 fs/xfs/libxfs/xfs_dir2.h      |  5 ----
 fs/xfs/libxfs/xfs_dir2_node.c | 35 ++++++++++++++++++++------
 3 files changed, 27 insertions(+), 60 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c
index d2d3144c1598..2b708b9fae1a 100644
--- a/fs/xfs/libxfs/xfs_da_format.c
+++ b/fs/xfs/libxfs/xfs_da_format.c
@@ -400,44 +400,6 @@ xfs_dir3_data_unused_p(struct xfs_dir2_data_hdr *hdr)
 		((char *)hdr + sizeof(struct xfs_dir3_data_hdr));
 }
 
-/*
- * Convert data space db to the corresponding free db.
- */
-static xfs_dir2_db_t
-xfs_dir2_db_to_fdb(struct xfs_da_geometry *geo, xfs_dir2_db_t db)
-{
-	return xfs_dir2_byte_to_db(geo, XFS_DIR2_FREE_OFFSET) +
-			(db / geo->free_max_bests);
-}
-
-/*
- * Convert data space db to the corresponding index in a free db.
- */
-static int
-xfs_dir2_db_to_fdindex(struct xfs_da_geometry *geo, xfs_dir2_db_t db)
-{
-	return db % geo->free_max_bests;
-}
-
-/*
- * Convert data space db to the corresponding free db.
- */
-static xfs_dir2_db_t
-xfs_dir3_db_to_fdb(struct xfs_da_geometry *geo, xfs_dir2_db_t db)
-{
-	return xfs_dir2_byte_to_db(geo, XFS_DIR2_FREE_OFFSET) +
-			(db / geo->free_max_bests);
-}
-
-/*
- * Convert data space db to the corresponding index in a free db.
- */
-static int
-xfs_dir3_db_to_fdindex(struct xfs_da_geometry *geo, xfs_dir2_db_t db)
-{
-	return db % geo->free_max_bests;
-}
-
 static const struct xfs_dir_ops xfs_dir2_ops = {
 	.sf_entsize = xfs_dir2_sf_entsize,
 	.sf_nextentry = xfs_dir2_sf_nextentry,
@@ -467,9 +429,6 @@ static const struct xfs_dir_ops xfs_dir2_ops = {
 	.data_first_entry_p = xfs_dir2_data_first_entry_p,
 	.data_entry_p = xfs_dir2_data_entry_p,
 	.data_unused_p = xfs_dir2_data_unused_p,
-
-	.db_to_fdb = xfs_dir2_db_to_fdb,
-	.db_to_fdindex = xfs_dir2_db_to_fdindex,
 };
 
 static const struct xfs_dir_ops xfs_dir2_ftype_ops = {
@@ -501,9 +460,6 @@ static const struct xfs_dir_ops xfs_dir2_ftype_ops = {
 	.data_first_entry_p = xfs_dir2_ftype_data_first_entry_p,
 	.data_entry_p = xfs_dir2_data_entry_p,
 	.data_unused_p = xfs_dir2_data_unused_p,
-
-	.db_to_fdb = xfs_dir2_db_to_fdb,
-	.db_to_fdindex = xfs_dir2_db_to_fdindex,
 };
 
 static const struct xfs_dir_ops xfs_dir3_ops = {
@@ -535,9 +491,6 @@ static const struct xfs_dir_ops xfs_dir3_ops = {
 	.data_first_entry_p = xfs_dir3_data_first_entry_p,
 	.data_entry_p = xfs_dir3_data_entry_p,
 	.data_unused_p = xfs_dir3_data_unused_p,
-
-	.db_to_fdb = xfs_dir3_db_to_fdb,
-	.db_to_fdindex = xfs_dir3_db_to_fdindex,
 };
 
 /*
diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h
index e3c1385d1522..e302679d8c80 100644
--- a/fs/xfs/libxfs/xfs_dir2.h
+++ b/fs/xfs/libxfs/xfs_dir2.h
@@ -71,11 +71,6 @@ struct xfs_dir_ops {
 		(*data_entry_p)(struct xfs_dir2_data_hdr *hdr);
 	struct xfs_dir2_data_unused *
 		(*data_unused_p)(struct xfs_dir2_data_hdr *hdr);
-
-	xfs_dir2_db_t (*db_to_fdb)(struct xfs_da_geometry *geo,
-				   xfs_dir2_db_t db);
-	int	(*db_to_fdindex)(struct xfs_da_geometry *geo,
-				 xfs_dir2_db_t db);
 };
 
 extern const struct xfs_dir_ops *
diff --git a/fs/xfs/libxfs/xfs_dir2_node.c b/fs/xfs/libxfs/xfs_dir2_node.c
index 0fcd7351038e..ceb5936b58dd 100644
--- a/fs/xfs/libxfs/xfs_dir2_node.c
+++ b/fs/xfs/libxfs/xfs_dir2_node.c
@@ -33,6 +33,25 @@ static int xfs_dir2_leafn_remove(xfs_da_args_t *args, struct xfs_buf *bp,
 				 int index, xfs_da_state_blk_t *dblk,
 				 int *rval);
 
+/*
+ * Convert data space db to the corresponding free db.
+ */
+static xfs_dir2_db_t
+xfs_dir2_db_to_fdb(struct xfs_da_geometry *geo, xfs_dir2_db_t db)
+{
+	return xfs_dir2_byte_to_db(geo, XFS_DIR2_FREE_OFFSET) +
+			(db / geo->free_max_bests);
+}
+
+/*
+ * Convert data space db to the corresponding index in a free db.
+ */
+static int
+xfs_dir2_db_to_fdindex(struct xfs_da_geometry *geo, xfs_dir2_db_t db)
+{
+	return db % geo->free_max_bests;
+}
+
 /*
  * Check internal consistency of a leafn block.
  */
@@ -676,7 +695,7 @@ xfs_dir2_leafn_lookup_for_addname(
 			 * Convert the data block to the free block
 			 * holding its freespace information.
 			 */
-			newfdb = dp->d_ops->db_to_fdb(args->geo, newdb);
+			newfdb = xfs_dir2_db_to_fdb(args->geo, newdb);
 			/*
 			 * If it's not the one we have in hand, read it in.
 			 */
@@ -700,7 +719,7 @@ xfs_dir2_leafn_lookup_for_addname(
 			/*
 			 * Get the index for our entry.
 			 */
-			fi = dp->d_ops->db_to_fdindex(args->geo, curdb);
+			fi = xfs_dir2_db_to_fdindex(args->geo, curdb);
 			/*
 			 * If it has room, return it.
 			 */
@@ -1320,7 +1339,7 @@ xfs_dir2_leafn_remove(
 		 * Convert the data block number to a free block,
 		 * read in the free block.
 		 */
-		fdb = dp->d_ops->db_to_fdb(args->geo, db);
+		fdb = xfs_dir2_db_to_fdb(args->geo, db);
 		error = xfs_dir2_free_read(tp, dp,
 					   xfs_dir2_db_to_da(args->geo, fdb),
 					   &fbp);
@@ -1340,7 +1359,7 @@ xfs_dir2_leafn_remove(
 		/*
 		 * Calculate which entry we need to fix.
 		 */
-		findex = dp->d_ops->db_to_fdindex(args->geo, db);
+		findex = xfs_dir2_db_to_fdindex(args->geo, db);
 		longest = be16_to_cpu(bf[0].length);
 		/*
 		 * If the data block is now empty we can get rid of it
@@ -1683,7 +1702,7 @@ xfs_dir2_node_add_datablk(
 	 * Get the freespace block corresponding to the data block
 	 * that was just allocated.
 	 */
-	fbno = dp->d_ops->db_to_fdb(args->geo, *dbno);
+	fbno = xfs_dir2_db_to_fdb(args->geo, *dbno);
 	error = xfs_dir2_free_try_read(tp, dp,
 			       xfs_dir2_db_to_da(args->geo, fbno), &fbp);
 	if (error)
@@ -1698,11 +1717,11 @@ xfs_dir2_node_add_datablk(
 		if (error)
 			return error;
 
-		if (dp->d_ops->db_to_fdb(args->geo, *dbno) != fbno) {
+		if (xfs_dir2_db_to_fdb(args->geo, *dbno) != fbno) {
 			xfs_alert(mp,
 "%s: dir ino %llu needed freesp block %lld for data block %lld, got %lld",
 				__func__, (unsigned long long)dp->i_ino,
-				(long long)dp->d_ops->db_to_fdb(args->geo, *dbno),
+				(long long)xfs_dir2_db_to_fdb(args->geo, *dbno),
 				(long long)*dbno, (long long)fbno);
 			if (fblk) {
 				xfs_alert(mp,
@@ -1731,7 +1750,7 @@ xfs_dir2_node_add_datablk(
 	}
 
 	/* Set the freespace block index from the data block number. */
-	*findex = dp->d_ops->db_to_fdindex(args->geo, *dbno);
+	*findex = xfs_dir2_db_to_fdindex(args->geo, *dbno);
 
 	/* Extend the freespace table if the new data block is off the end. */
 	if (*findex >= hdr->nvalid) {
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 19/34] xfs: devirtualize ->sf_get_parent_ino and ->sf_put_parent_ino
  2019-11-01 22:06 remove m_dirops Christoph Hellwig
                   ` (17 preceding siblings ...)
  2019-11-01 22:07 ` [PATCH 18/34] xfs: devirtualize ->db_to_fdb and ->db_to_fdindex Christoph Hellwig
@ 2019-11-01 22:07 ` Christoph Hellwig
  2019-11-04 20:26   ` Darrick J. Wong
  2019-11-01 22:07 ` [PATCH 20/34] xfs: devirtualize ->sf_entsize and ->sf_nextentry Christoph Hellwig
                   ` (14 subsequent siblings)
  33 siblings, 1 reply; 81+ messages in thread
From: Christoph Hellwig @ 2019-11-01 22:07 UTC (permalink / raw)
  To: linux-xfs

The parent inode handling is the same for all directory format variants,
just use direct calls instead of going through a pointless indirect
call.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 fs/xfs/libxfs/xfs_da_format.c  | 10 ++--------
 fs/xfs/libxfs/xfs_dir2.h       |  3 ---
 fs/xfs/libxfs/xfs_dir2_block.c |  2 +-
 fs/xfs/libxfs/xfs_dir2_priv.h  |  2 ++
 fs/xfs/libxfs/xfs_dir2_sf.c    | 20 ++++++++++----------
 fs/xfs/xfs_dir2_readdir.c      |  2 +-
 6 files changed, 16 insertions(+), 23 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c
index 2b708b9fae1a..7858469c09e4 100644
--- a/fs/xfs/libxfs/xfs_da_format.c
+++ b/fs/xfs/libxfs/xfs_da_format.c
@@ -132,14 +132,14 @@ xfs_dir2_sf_put_ino(
 		put_unaligned_be32(ino, to);
 }
 
-static xfs_ino_t
+xfs_ino_t
 xfs_dir2_sf_get_parent_ino(
 	struct xfs_dir2_sf_hdr	*hdr)
 {
 	return xfs_dir2_sf_get_ino(hdr, hdr->parent);
 }
 
-static void
+void
 xfs_dir2_sf_put_parent_ino(
 	struct xfs_dir2_sf_hdr	*hdr,
 	xfs_ino_t		ino)
@@ -407,8 +407,6 @@ static const struct xfs_dir_ops xfs_dir2_ops = {
 	.sf_put_ftype = xfs_dir2_sfe_put_ftype,
 	.sf_get_ino = xfs_dir2_sfe_get_ino,
 	.sf_put_ino = xfs_dir2_sfe_put_ino,
-	.sf_get_parent_ino = xfs_dir2_sf_get_parent_ino,
-	.sf_put_parent_ino = xfs_dir2_sf_put_parent_ino,
 
 	.data_entsize = xfs_dir2_data_entsize,
 	.data_get_ftype = xfs_dir2_data_get_ftype,
@@ -438,8 +436,6 @@ static const struct xfs_dir_ops xfs_dir2_ftype_ops = {
 	.sf_put_ftype = xfs_dir3_sfe_put_ftype,
 	.sf_get_ino = xfs_dir3_sfe_get_ino,
 	.sf_put_ino = xfs_dir3_sfe_put_ino,
-	.sf_get_parent_ino = xfs_dir2_sf_get_parent_ino,
-	.sf_put_parent_ino = xfs_dir2_sf_put_parent_ino,
 
 	.data_entsize = xfs_dir3_data_entsize,
 	.data_get_ftype = xfs_dir3_data_get_ftype,
@@ -469,8 +465,6 @@ static const struct xfs_dir_ops xfs_dir3_ops = {
 	.sf_put_ftype = xfs_dir3_sfe_put_ftype,
 	.sf_get_ino = xfs_dir3_sfe_get_ino,
 	.sf_put_ino = xfs_dir3_sfe_put_ino,
-	.sf_get_parent_ino = xfs_dir2_sf_get_parent_ino,
-	.sf_put_parent_ino = xfs_dir2_sf_put_parent_ino,
 
 	.data_entsize = xfs_dir3_data_entsize,
 	.data_get_ftype = xfs_dir3_data_get_ftype,
diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h
index e302679d8c80..d3a0b8daab5f 100644
--- a/fs/xfs/libxfs/xfs_dir2.h
+++ b/fs/xfs/libxfs/xfs_dir2.h
@@ -44,9 +44,6 @@ struct xfs_dir_ops {
 	void	(*sf_put_ino)(struct xfs_dir2_sf_hdr *hdr,
 			      struct xfs_dir2_sf_entry *sfep,
 			      xfs_ino_t ino);
-	xfs_ino_t (*sf_get_parent_ino)(struct xfs_dir2_sf_hdr *hdr);
-	void	(*sf_put_parent_ino)(struct xfs_dir2_sf_hdr *hdr,
-				     xfs_ino_t ino);
 
 	int	(*data_entsize)(int len);
 	uint8_t (*data_get_ftype)(struct xfs_dir2_data_entry *dep);
diff --git a/fs/xfs/libxfs/xfs_dir2_block.c b/fs/xfs/libxfs/xfs_dir2_block.c
index 38886b9c7b48..2ee9fdd182e1 100644
--- a/fs/xfs/libxfs/xfs_dir2_block.c
+++ b/fs/xfs/libxfs/xfs_dir2_block.c
@@ -1163,7 +1163,7 @@ xfs_dir2_sf_to_block(
 	 * Create entry for ..
 	 */
 	dep = dp->d_ops->data_dotdot_entry_p(hdr);
-	dep->inumber = cpu_to_be64(dp->d_ops->sf_get_parent_ino(sfp));
+	dep->inumber = cpu_to_be64(xfs_dir2_sf_get_parent_ino(sfp));
 	dep->namelen = 2;
 	dep->name[0] = dep->name[1] = '.';
 	dp->d_ops->data_put_ftype(dep, XFS_DIR3_FT_DIR);
diff --git a/fs/xfs/libxfs/xfs_dir2_priv.h b/fs/xfs/libxfs/xfs_dir2_priv.h
index b73cf38c6969..d5104fdb8543 100644
--- a/fs/xfs/libxfs/xfs_dir2_priv.h
+++ b/fs/xfs/libxfs/xfs_dir2_priv.h
@@ -135,6 +135,8 @@ extern int xfs_dir2_free_read(struct xfs_trans *tp, struct xfs_inode *dp,
 		xfs_dablk_t fbno, struct xfs_buf **bpp);
 
 /* xfs_dir2_sf.c */
+xfs_ino_t xfs_dir2_sf_get_parent_ino(struct xfs_dir2_sf_hdr *hdr);
+void xfs_dir2_sf_put_parent_ino(struct xfs_dir2_sf_hdr *hdr, xfs_ino_t ino);
 extern int xfs_dir2_block_sfsize(struct xfs_inode *dp,
 		struct xfs_dir2_data_hdr *block, struct xfs_dir2_sf_hdr *sfhp);
 extern int xfs_dir2_block_to_sf(struct xfs_da_args *args, struct xfs_buf *bp,
diff --git a/fs/xfs/libxfs/xfs_dir2_sf.c b/fs/xfs/libxfs/xfs_dir2_sf.c
index ae16ca7c422a..1d7c26d0157c 100644
--- a/fs/xfs/libxfs/xfs_dir2_sf.c
+++ b/fs/xfs/libxfs/xfs_dir2_sf.c
@@ -125,7 +125,7 @@ xfs_dir2_block_sfsize(
 	 */
 	sfhp->count = count;
 	sfhp->i8count = i8count;
-	dp->d_ops->sf_put_parent_ino(sfhp, parent);
+	xfs_dir2_sf_put_parent_ino(sfhp, parent);
 	return size;
 }
 
@@ -204,7 +204,7 @@ xfs_dir2_block_to_sf(
 		else if (dep->namelen == 2 &&
 			 dep->name[0] == '.' && dep->name[1] == '.')
 			ASSERT(be64_to_cpu(dep->inumber) ==
-			       dp->d_ops->sf_get_parent_ino(sfp));
+			       xfs_dir2_sf_get_parent_ino(sfp));
 		/*
 		 * Normal entry, copy it into shortform.
 		 */
@@ -590,7 +590,7 @@ xfs_dir2_sf_check(
 
 	sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data;
 	offset = dp->d_ops->data_first_offset;
-	ino = dp->d_ops->sf_get_parent_ino(sfp);
+	ino = xfs_dir2_sf_get_parent_ino(sfp);
 	i8count = ino > XFS_DIR2_MAX_SHORT_INUM;
 
 	for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp);
@@ -653,7 +653,7 @@ xfs_dir2_sf_verify(
 	endp = (char *)sfp + size;
 
 	/* Check .. entry */
-	ino = dops->sf_get_parent_ino(sfp);
+	ino = xfs_dir2_sf_get_parent_ino(sfp);
 	i8count = ino > XFS_DIR2_MAX_SHORT_INUM;
 	error = xfs_dir_ino_validate(mp, ino);
 	if (error)
@@ -763,7 +763,7 @@ xfs_dir2_sf_create(
 	/*
 	 * Now can put in the inode number, since i8count is set.
 	 */
-	dp->d_ops->sf_put_parent_ino(sfp, pino);
+	xfs_dir2_sf_put_parent_ino(sfp, pino);
 	sfp->count = 0;
 	dp->i_d.di_size = size;
 	xfs_dir2_sf_check(args);
@@ -818,7 +818,7 @@ xfs_dir2_sf_lookup(
 	 */
 	if (args->namelen == 2 &&
 	    args->name[0] == '.' && args->name[1] == '.') {
-		args->inumber = dp->d_ops->sf_get_parent_ino(sfp);
+		args->inumber = xfs_dir2_sf_get_parent_ino(sfp);
 		args->cmpresult = XFS_CMP_EXACT;
 		args->filetype = XFS_DIR3_FT_DIR;
 		return -EEXIST;
@@ -1008,9 +1008,9 @@ xfs_dir2_sf_replace(
 	 */
 	if (args->namelen == 2 &&
 	    args->name[0] == '.' && args->name[1] == '.') {
-		ino = dp->d_ops->sf_get_parent_ino(sfp);
+		ino = xfs_dir2_sf_get_parent_ino(sfp);
 		ASSERT(args->inumber != ino);
-		dp->d_ops->sf_put_parent_ino(sfp, args->inumber);
+		xfs_dir2_sf_put_parent_ino(sfp, args->inumber);
 	}
 	/*
 	 * Normal entry, look for the name.
@@ -1116,7 +1116,7 @@ xfs_dir2_sf_toino4(
 	 */
 	sfp->count = oldsfp->count;
 	sfp->i8count = 0;
-	dp->d_ops->sf_put_parent_ino(sfp, dp->d_ops->sf_get_parent_ino(oldsfp));
+	xfs_dir2_sf_put_parent_ino(sfp, xfs_dir2_sf_get_parent_ino(oldsfp));
 	/*
 	 * Copy the entries field by field.
 	 */
@@ -1189,7 +1189,7 @@ xfs_dir2_sf_toino8(
 	 */
 	sfp->count = oldsfp->count;
 	sfp->i8count = 1;
-	dp->d_ops->sf_put_parent_ino(sfp, dp->d_ops->sf_get_parent_ino(oldsfp));
+	xfs_dir2_sf_put_parent_ino(sfp, xfs_dir2_sf_get_parent_ino(oldsfp));
 	/*
 	 * Copy the entries field by field.
 	 */
diff --git a/fs/xfs/xfs_dir2_readdir.c b/fs/xfs/xfs_dir2_readdir.c
index a0bec0931f3b..6f94d2a45174 100644
--- a/fs/xfs/xfs_dir2_readdir.c
+++ b/fs/xfs/xfs_dir2_readdir.c
@@ -92,7 +92,7 @@ xfs_dir2_sf_getdents(
 	 * Put .. entry unless we're starting past it.
 	 */
 	if (ctx->pos <= dotdot_offset) {
-		ino = dp->d_ops->sf_get_parent_ino(sfp);
+		ino = xfs_dir2_sf_get_parent_ino(sfp);
 		ctx->pos = dotdot_offset & 0x7fffffff;
 		if (!dir_emit(ctx, "..", 2, ino, DT_DIR))
 			return 0;
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 20/34] xfs: devirtualize ->sf_entsize and ->sf_nextentry
  2019-11-01 22:06 remove m_dirops Christoph Hellwig
                   ` (18 preceding siblings ...)
  2019-11-01 22:07 ` [PATCH 19/34] xfs: devirtualize ->sf_get_parent_ino and ->sf_put_parent_ino Christoph Hellwig
@ 2019-11-01 22:07 ` Christoph Hellwig
  2019-11-04 20:28   ` Darrick J. Wong
  2019-11-01 22:07 ` [PATCH 21/34] xfs: devirtualize ->sf_get_ino and ->sf_put_ino Christoph Hellwig
                   ` (13 subsequent siblings)
  33 siblings, 1 reply; 81+ messages in thread
From: Christoph Hellwig @ 2019-11-01 22:07 UTC (permalink / raw)
  To: linux-xfs

Just check for file-type enabled directories directly.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 fs/xfs/libxfs/xfs_da_format.c  | 48 -----------------
 fs/xfs/libxfs/xfs_dir2.h       |  4 --
 fs/xfs/libxfs/xfs_dir2_block.c |  2 +-
 fs/xfs/libxfs/xfs_dir2_priv.h  |  2 +
 fs/xfs/libxfs/xfs_dir2_sf.c    | 99 ++++++++++++++++++++--------------
 fs/xfs/xfs_dir2_readdir.c      |  7 +--
 6 files changed, 66 insertions(+), 96 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c
index 7858469c09e4..f80495a38a76 100644
--- a/fs/xfs/libxfs/xfs_da_format.c
+++ b/fs/xfs/libxfs/xfs_da_format.c
@@ -15,48 +15,6 @@
 #include "xfs_dir2.h"
 #include "xfs_dir2_priv.h"
 
-/*
- * Shortform directory ops
- */
-static int
-xfs_dir2_sf_entsize(
-	struct xfs_dir2_sf_hdr	*hdr,
-	int			len)
-{
-	int count = sizeof(struct xfs_dir2_sf_entry);	/* namelen + offset */
-
-	count += len;					/* name */
-	count += hdr->i8count ? XFS_INO64_SIZE : XFS_INO32_SIZE; /* ino # */
-	return count;
-}
-
-static int
-xfs_dir3_sf_entsize(
-	struct xfs_dir2_sf_hdr	*hdr,
-	int			len)
-{
-	return xfs_dir2_sf_entsize(hdr, len) + sizeof(uint8_t);
-}
-
-static struct xfs_dir2_sf_entry *
-xfs_dir2_sf_nextentry(
-	struct xfs_dir2_sf_hdr	*hdr,
-	struct xfs_dir2_sf_entry *sfep)
-{
-	return (struct xfs_dir2_sf_entry *)
-		((char *)sfep + xfs_dir2_sf_entsize(hdr, sfep->namelen));
-}
-
-static struct xfs_dir2_sf_entry *
-xfs_dir3_sf_nextentry(
-	struct xfs_dir2_sf_hdr	*hdr,
-	struct xfs_dir2_sf_entry *sfep)
-{
-	return (struct xfs_dir2_sf_entry *)
-		((char *)sfep + xfs_dir3_sf_entsize(hdr, sfep->namelen));
-}
-
-
 /*
  * For filetype enabled shortform directories, the file type field is stored at
  * the end of the name.  Because it's only a single byte, endian conversion is
@@ -401,8 +359,6 @@ xfs_dir3_data_unused_p(struct xfs_dir2_data_hdr *hdr)
 }
 
 static const struct xfs_dir_ops xfs_dir2_ops = {
-	.sf_entsize = xfs_dir2_sf_entsize,
-	.sf_nextentry = xfs_dir2_sf_nextentry,
 	.sf_get_ftype = xfs_dir2_sfe_get_ftype,
 	.sf_put_ftype = xfs_dir2_sfe_put_ftype,
 	.sf_get_ino = xfs_dir2_sfe_get_ino,
@@ -430,8 +386,6 @@ static const struct xfs_dir_ops xfs_dir2_ops = {
 };
 
 static const struct xfs_dir_ops xfs_dir2_ftype_ops = {
-	.sf_entsize = xfs_dir3_sf_entsize,
-	.sf_nextentry = xfs_dir3_sf_nextentry,
 	.sf_get_ftype = xfs_dir3_sfe_get_ftype,
 	.sf_put_ftype = xfs_dir3_sfe_put_ftype,
 	.sf_get_ino = xfs_dir3_sfe_get_ino,
@@ -459,8 +413,6 @@ static const struct xfs_dir_ops xfs_dir2_ftype_ops = {
 };
 
 static const struct xfs_dir_ops xfs_dir3_ops = {
-	.sf_entsize = xfs_dir3_sf_entsize,
-	.sf_nextentry = xfs_dir3_sf_nextentry,
 	.sf_get_ftype = xfs_dir3_sfe_get_ftype,
 	.sf_put_ftype = xfs_dir3_sfe_put_ftype,
 	.sf_get_ino = xfs_dir3_sfe_get_ino,
diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h
index d3a0b8daab5f..c99f0ad6607a 100644
--- a/fs/xfs/libxfs/xfs_dir2.h
+++ b/fs/xfs/libxfs/xfs_dir2.h
@@ -32,10 +32,6 @@ extern unsigned char xfs_mode_to_ftype(int mode);
  * directory operations vector for encode/decode routines
  */
 struct xfs_dir_ops {
-	int	(*sf_entsize)(struct xfs_dir2_sf_hdr *hdr, int len);
-	struct xfs_dir2_sf_entry *
-		(*sf_nextentry)(struct xfs_dir2_sf_hdr *hdr,
-				struct xfs_dir2_sf_entry *sfep);
 	uint8_t (*sf_get_ftype)(struct xfs_dir2_sf_entry *sfep);
 	void	(*sf_put_ftype)(struct xfs_dir2_sf_entry *sfep,
 				uint8_t ftype);
diff --git a/fs/xfs/libxfs/xfs_dir2_block.c b/fs/xfs/libxfs/xfs_dir2_block.c
index 2ee9fdd182e1..88b3d1884c74 100644
--- a/fs/xfs/libxfs/xfs_dir2_block.c
+++ b/fs/xfs/libxfs/xfs_dir2_block.c
@@ -1231,7 +1231,7 @@ xfs_dir2_sf_to_block(
 		if (++i == sfp->count)
 			sfep = NULL;
 		else
-			sfep = dp->d_ops->sf_nextentry(sfp, sfep);
+			sfep = xfs_dir2_sf_nextentry(mp, sfp, sfep);
 	}
 	/* Done with the temporary buffer */
 	kmem_free(sfp);
diff --git a/fs/xfs/libxfs/xfs_dir2_priv.h b/fs/xfs/libxfs/xfs_dir2_priv.h
index d5104fdb8543..a96b9ba7909b 100644
--- a/fs/xfs/libxfs/xfs_dir2_priv.h
+++ b/fs/xfs/libxfs/xfs_dir2_priv.h
@@ -137,6 +137,8 @@ extern int xfs_dir2_free_read(struct xfs_trans *tp, struct xfs_inode *dp,
 /* xfs_dir2_sf.c */
 xfs_ino_t xfs_dir2_sf_get_parent_ino(struct xfs_dir2_sf_hdr *hdr);
 void xfs_dir2_sf_put_parent_ino(struct xfs_dir2_sf_hdr *hdr, xfs_ino_t ino);
+struct xfs_dir2_sf_entry *xfs_dir2_sf_nextentry(struct xfs_mount *mp,
+		struct xfs_dir2_sf_hdr *hdr, struct xfs_dir2_sf_entry *sfep);
 extern int xfs_dir2_block_sfsize(struct xfs_inode *dp,
 		struct xfs_dir2_data_hdr *block, struct xfs_dir2_sf_hdr *sfhp);
 extern int xfs_dir2_block_to_sf(struct xfs_da_args *args, struct xfs_buf *bp,
diff --git a/fs/xfs/libxfs/xfs_dir2_sf.c b/fs/xfs/libxfs/xfs_dir2_sf.c
index 1d7c26d0157c..f3a4f0ddfc1a 100644
--- a/fs/xfs/libxfs/xfs_dir2_sf.c
+++ b/fs/xfs/libxfs/xfs_dir2_sf.c
@@ -37,6 +37,32 @@ static void xfs_dir2_sf_check(xfs_da_args_t *args);
 static void xfs_dir2_sf_toino4(xfs_da_args_t *args);
 static void xfs_dir2_sf_toino8(xfs_da_args_t *args);
 
+static int
+xfs_dir2_sf_entsize(
+	struct xfs_mount	*mp,
+	struct xfs_dir2_sf_hdr	*hdr,
+	int			len)
+{
+	int			count = len;
+
+	count += sizeof(struct xfs_dir2_sf_entry);	/* namelen + offset */
+	count += hdr->i8count ? XFS_INO64_SIZE : XFS_INO32_SIZE; /* ino # */
+
+	if (xfs_sb_version_hasftype(&mp->m_sb))
+		count += sizeof(uint8_t);
+	return count;
+}
+
+struct xfs_dir2_sf_entry *
+xfs_dir2_sf_nextentry(
+	struct xfs_mount	*mp,
+	struct xfs_dir2_sf_hdr	*hdr,
+	struct xfs_dir2_sf_entry *sfep)
+{
+	return (struct xfs_dir2_sf_entry *)
+		((char *)sfep + xfs_dir2_sf_entsize(mp, hdr, sfep->namelen));
+}
+
 /*
  * Given a block directory (dp/block), calculate its size as a shortform (sf)
  * directory and a header for the sf directory, if it will fit it the
@@ -219,7 +245,7 @@ xfs_dir2_block_to_sf(
 			dp->d_ops->sf_put_ftype(sfep,
 					dp->d_ops->data_get_ftype(dep));
 
-			sfep = dp->d_ops->sf_nextentry(sfp, sfep);
+			sfep = xfs_dir2_sf_nextentry(mp, sfp, sfep);
 		}
 		ptr += dp->d_ops->data_entsize(dep->namelen);
 	}
@@ -291,7 +317,7 @@ xfs_dir2_sf_addname(
 	/*
 	 * Compute entry (and change in) size.
 	 */
-	incr_isize = dp->d_ops->sf_entsize(sfp, args->namelen);
+	incr_isize = xfs_dir2_sf_entsize(dp->i_mount, sfp, args->namelen);
 	objchange = 0;
 
 	/*
@@ -364,18 +390,17 @@ xfs_dir2_sf_addname_easy(
 	xfs_dir2_data_aoff_t	offset,		/* offset to use for new ent */
 	int			new_isize)	/* new directory size */
 {
+	struct xfs_inode	*dp = args->dp;
+	struct xfs_mount	*mp = dp->i_mount;
 	int			byteoff;	/* byte offset in sf dir */
-	xfs_inode_t		*dp;		/* incore directory inode */
 	xfs_dir2_sf_hdr_t	*sfp;		/* shortform structure */
 
-	dp = args->dp;
-
 	sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data;
 	byteoff = (int)((char *)sfep - (char *)sfp);
 	/*
 	 * Grow the in-inode space.
 	 */
-	xfs_idata_realloc(dp, dp->d_ops->sf_entsize(sfp, args->namelen),
+	xfs_idata_realloc(dp, xfs_dir2_sf_entsize(mp, sfp, args->namelen),
 			  XFS_DATA_FORK);
 	/*
 	 * Need to set up again due to realloc of the inode data.
@@ -416,9 +441,10 @@ xfs_dir2_sf_addname_hard(
 	int			objchange,	/* changing inode number size */
 	int			new_isize)	/* new directory size */
 {
+	struct xfs_inode	*dp = args->dp;
+	struct xfs_mount	*mp = dp->i_mount;
 	int			add_datasize;	/* data size need for new ent */
 	char			*buf;		/* buffer for old */
-	xfs_inode_t		*dp;		/* incore directory inode */
 	int			eof;		/* reached end of old dir */
 	int			nbytes;		/* temp for byte copies */
 	xfs_dir2_data_aoff_t	new_offset;	/* next offset value */
@@ -432,8 +458,6 @@ xfs_dir2_sf_addname_hard(
 	/*
 	 * Copy the old directory to the stack buffer.
 	 */
-	dp = args->dp;
-
 	sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data;
 	old_isize = (int)dp->i_d.di_size;
 	buf = kmem_alloc(old_isize, 0);
@@ -450,7 +474,7 @@ xfs_dir2_sf_addname_hard(
 	      eof = (char *)oldsfep == &buf[old_isize];
 	     !eof;
 	     offset = new_offset + dp->d_ops->data_entsize(oldsfep->namelen),
-	      oldsfep = dp->d_ops->sf_nextentry(oldsfp, oldsfep),
+	      oldsfep = xfs_dir2_sf_nextentry(mp, oldsfp, oldsfep),
 	      eof = (char *)oldsfep == &buf[old_isize]) {
 		new_offset = xfs_dir2_sf_get_offset(oldsfep);
 		if (offset + add_datasize <= new_offset)
@@ -488,7 +512,7 @@ xfs_dir2_sf_addname_hard(
 	 * If there's more left to copy, do that.
 	 */
 	if (!eof) {
-		sfep = dp->d_ops->sf_nextentry(sfp, sfep);
+		sfep = xfs_dir2_sf_nextentry(mp, sfp, sfep);
 		memcpy(sfep, oldsfep, old_isize - nbytes);
 	}
 	kmem_free(buf);
@@ -510,7 +534,8 @@ xfs_dir2_sf_addname_pick(
 	xfs_dir2_sf_entry_t	**sfepp,	/* out(1): new entry ptr */
 	xfs_dir2_data_aoff_t	*offsetp)	/* out(1): new offset */
 {
-	xfs_inode_t		*dp;		/* incore directory inode */
+	struct xfs_inode	*dp = args->dp;
+	struct xfs_mount	*mp = dp->i_mount;
 	int			holefit;	/* found hole it will fit in */
 	int			i;		/* entry number */
 	xfs_dir2_data_aoff_t	offset;		/* data block offset */
@@ -519,8 +544,6 @@ xfs_dir2_sf_addname_pick(
 	int			size;		/* entry's data size */
 	int			used;		/* data bytes used */
 
-	dp = args->dp;
-
 	sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data;
 	size = dp->d_ops->data_entsize(args->namelen);
 	offset = dp->d_ops->data_first_offset;
@@ -536,7 +559,7 @@ xfs_dir2_sf_addname_pick(
 			holefit = offset + size <= xfs_dir2_sf_get_offset(sfep);
 		offset = xfs_dir2_sf_get_offset(sfep) +
 			 dp->d_ops->data_entsize(sfep->namelen);
-		sfep = dp->d_ops->sf_nextentry(sfp, sfep);
+		sfep = xfs_dir2_sf_nextentry(mp, sfp, sfep);
 	}
 	/*
 	 * Calculate data bytes used excluding the new entry, if this
@@ -595,7 +618,7 @@ xfs_dir2_sf_check(
 
 	for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp);
 	     i < sfp->count;
-	     i++, sfep = dp->d_ops->sf_nextentry(sfp, sfep)) {
+	     i++, sfep = xfs_dir2_sf_nextentry(dp->i_mount, sfp, sfep)) {
 		ASSERT(xfs_dir2_sf_get_offset(sfep) >= offset);
 		ino = dp->d_ops->sf_get_ino(sfp, sfep);
 		i8count += ino > XFS_DIR2_MAX_SHORT_INUM;
@@ -680,7 +703,7 @@ xfs_dir2_sf_verify(
 		 * within the data buffer.  The next entry starts after the
 		 * name component, so nextentry is an acceptable test.
 		 */
-		next_sfep = dops->sf_nextentry(sfp, sfep);
+		next_sfep = xfs_dir2_sf_nextentry(mp, sfp, sfep);
 		if (endp < (char *)next_sfep)
 			return __this_address;
 
@@ -779,7 +802,8 @@ int						/* error */
 xfs_dir2_sf_lookup(
 	xfs_da_args_t		*args)		/* operation arguments */
 {
-	xfs_inode_t		*dp;		/* incore directory inode */
+	struct xfs_inode	*dp = args->dp;
+	struct xfs_mount	*mp = dp->i_mount;
 	int			i;		/* entry index */
 	int			error;
 	xfs_dir2_sf_entry_t	*sfep;		/* shortform directory entry */
@@ -790,7 +814,6 @@ xfs_dir2_sf_lookup(
 	trace_xfs_dir2_sf_lookup(args);
 
 	xfs_dir2_sf_check(args);
-	dp = args->dp;
 
 	ASSERT(dp->i_df.if_flags & XFS_IFINLINE);
 	/*
@@ -828,7 +851,7 @@ xfs_dir2_sf_lookup(
 	 */
 	ci_sfep = NULL;
 	for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp); i < sfp->count;
-	     i++, sfep = dp->d_ops->sf_nextentry(sfp, sfep)) {
+	     i++, sfep = xfs_dir2_sf_nextentry(mp, sfp, sfep)) {
 		/*
 		 * Compare name and if it's an exact match, return the inode
 		 * number. If it's the first case-insensitive match, store the
@@ -864,8 +887,9 @@ int						/* error */
 xfs_dir2_sf_removename(
 	xfs_da_args_t		*args)
 {
+	struct xfs_inode	*dp = args->dp;
+	struct xfs_mount	*mp = dp->i_mount;
 	int			byteoff;	/* offset of removed entry */
-	xfs_inode_t		*dp;		/* incore directory inode */
 	int			entsize;	/* this entry's size */
 	int			i;		/* shortform entry index */
 	int			newsize;	/* new inode size */
@@ -875,8 +899,6 @@ xfs_dir2_sf_removename(
 
 	trace_xfs_dir2_sf_removename(args);
 
-	dp = args->dp;
-
 	ASSERT(dp->i_df.if_flags & XFS_IFINLINE);
 	oldsize = (int)dp->i_d.di_size;
 	/*
@@ -895,7 +917,7 @@ xfs_dir2_sf_removename(
 	 * Find the one we're deleting.
 	 */
 	for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp); i < sfp->count;
-	     i++, sfep = dp->d_ops->sf_nextentry(sfp, sfep)) {
+	     i++, sfep = xfs_dir2_sf_nextentry(mp, sfp, sfep)) {
 		if (xfs_da_compname(args, sfep->name, sfep->namelen) ==
 								XFS_CMP_EXACT) {
 			ASSERT(dp->d_ops->sf_get_ino(sfp, sfep) ==
@@ -912,7 +934,7 @@ xfs_dir2_sf_removename(
 	 * Calculate sizes.
 	 */
 	byteoff = (int)((char *)sfep - (char *)sfp);
-	entsize = dp->d_ops->sf_entsize(sfp, args->namelen);
+	entsize = xfs_dir2_sf_entsize(mp, sfp, args->namelen);
 	newsize = oldsize - entsize;
 	/*
 	 * Copy the part if any after the removed entry, sliding it down.
@@ -951,7 +973,8 @@ int						/* error */
 xfs_dir2_sf_replace(
 	xfs_da_args_t		*args)		/* operation arguments */
 {
-	xfs_inode_t		*dp;		/* incore directory inode */
+	struct xfs_inode	*dp = args->dp;
+	struct xfs_mount	*mp = dp->i_mount;
 	int			i;		/* entry index */
 	xfs_ino_t		ino=0;		/* entry old inode number */
 	int			i8elevated;	/* sf_toino8 set i8count=1 */
@@ -960,14 +983,12 @@ xfs_dir2_sf_replace(
 
 	trace_xfs_dir2_sf_replace(args);
 
-	dp = args->dp;
-
 	ASSERT(dp->i_df.if_flags & XFS_IFINLINE);
 	/*
 	 * Bail out if the shortform directory is way too small.
 	 */
 	if (dp->i_d.di_size < offsetof(xfs_dir2_sf_hdr_t, parent)) {
-		ASSERT(XFS_FORCED_SHUTDOWN(dp->i_mount));
+		ASSERT(XFS_FORCED_SHUTDOWN(mp));
 		return -EIO;
 	}
 	ASSERT(dp->i_df.if_bytes == dp->i_d.di_size);
@@ -1017,7 +1038,7 @@ xfs_dir2_sf_replace(
 	 */
 	else {
 		for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp); i < sfp->count;
-		     i++, sfep = dp->d_ops->sf_nextentry(sfp, sfep)) {
+		     i++, sfep = xfs_dir2_sf_nextentry(mp, sfp, sfep)) {
 			if (xfs_da_compname(args, sfep->name, sfep->namelen) ==
 								XFS_CMP_EXACT) {
 				ino = dp->d_ops->sf_get_ino(sfp, sfep);
@@ -1076,8 +1097,9 @@ static void
 xfs_dir2_sf_toino4(
 	xfs_da_args_t		*args)		/* operation arguments */
 {
+	struct xfs_inode	*dp = args->dp;
+	struct xfs_mount	*mp = dp->i_mount;
 	char			*buf;		/* old dir's buffer */
-	xfs_inode_t		*dp;		/* incore directory inode */
 	int			i;		/* entry index */
 	int			newsize;	/* new inode size */
 	xfs_dir2_sf_entry_t	*oldsfep;	/* old sf entry */
@@ -1088,8 +1110,6 @@ xfs_dir2_sf_toino4(
 
 	trace_xfs_dir2_sf_toino4(args);
 
-	dp = args->dp;
-
 	/*
 	 * Copy the old directory to the buffer.
 	 * Then nuke it from the inode, and add the new buffer to the inode.
@@ -1123,8 +1143,8 @@ xfs_dir2_sf_toino4(
 	for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp),
 		    oldsfep = xfs_dir2_sf_firstentry(oldsfp);
 	     i < sfp->count;
-	     i++, sfep = dp->d_ops->sf_nextentry(sfp, sfep),
-		  oldsfep = dp->d_ops->sf_nextentry(oldsfp, oldsfep)) {
+	     i++, sfep = xfs_dir2_sf_nextentry(mp, sfp, sfep),
+		  oldsfep = xfs_dir2_sf_nextentry(mp, oldsfp, oldsfep)) {
 		sfep->namelen = oldsfep->namelen;
 		memcpy(sfep->offset, oldsfep->offset, sizeof(sfep->offset));
 		memcpy(sfep->name, oldsfep->name, sfep->namelen);
@@ -1149,8 +1169,9 @@ static void
 xfs_dir2_sf_toino8(
 	xfs_da_args_t		*args)		/* operation arguments */
 {
+	struct xfs_inode	*dp = args->dp;
+	struct xfs_mount	*mp = dp->i_mount;
 	char			*buf;		/* old dir's buffer */
-	xfs_inode_t		*dp;		/* incore directory inode */
 	int			i;		/* entry index */
 	int			newsize;	/* new inode size */
 	xfs_dir2_sf_entry_t	*oldsfep;	/* old sf entry */
@@ -1161,8 +1182,6 @@ xfs_dir2_sf_toino8(
 
 	trace_xfs_dir2_sf_toino8(args);
 
-	dp = args->dp;
-
 	/*
 	 * Copy the old directory to the buffer.
 	 * Then nuke it from the inode, and add the new buffer to the inode.
@@ -1196,8 +1215,8 @@ xfs_dir2_sf_toino8(
 	for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp),
 		    oldsfep = xfs_dir2_sf_firstentry(oldsfp);
 	     i < sfp->count;
-	     i++, sfep = dp->d_ops->sf_nextentry(sfp, sfep),
-		  oldsfep = dp->d_ops->sf_nextentry(oldsfp, oldsfep)) {
+	     i++, sfep = xfs_dir2_sf_nextentry(mp, sfp, sfep),
+		  oldsfep = xfs_dir2_sf_nextentry(mp, oldsfp, oldsfep)) {
 		sfep->namelen = oldsfep->namelen;
 		memcpy(sfep->offset, oldsfep->offset, sizeof(sfep->offset));
 		memcpy(sfep->name, oldsfep->name, sfep->namelen);
diff --git a/fs/xfs/xfs_dir2_readdir.c b/fs/xfs/xfs_dir2_readdir.c
index 6f94d2a45174..7d150e914d00 100644
--- a/fs/xfs/xfs_dir2_readdir.c
+++ b/fs/xfs/xfs_dir2_readdir.c
@@ -48,6 +48,7 @@ xfs_dir2_sf_getdents(
 {
 	int			i;		/* shortform entry number */
 	struct xfs_inode	*dp = args->dp;	/* incore directory inode */
+	struct xfs_mount	*mp = dp->i_mount;
 	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 */
@@ -109,7 +110,7 @@ xfs_dir2_sf_getdents(
 				xfs_dir2_sf_get_offset(sfep));
 
 		if (ctx->pos > off) {
-			sfep = dp->d_ops->sf_nextentry(sfp, sfep);
+			sfep = xfs_dir2_sf_nextentry(mp, sfp, sfep);
 			continue;
 		}
 
@@ -122,9 +123,9 @@ xfs_dir2_sf_getdents(
 			return -EFSCORRUPTED;
 		}
 		if (!dir_emit(ctx, (char *)sfep->name, sfep->namelen, ino,
-			    xfs_dir3_get_dtype(dp->i_mount, filetype)))
+			    xfs_dir3_get_dtype(mp, filetype)))
 			return 0;
-		sfep = dp->d_ops->sf_nextentry(sfp, sfep);
+		sfep = xfs_dir2_sf_nextentry(mp, sfp, sfep);
 	}
 
 	ctx->pos = xfs_dir2_db_off_to_dataptr(geo, geo->datablk + 1, 0) &
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 21/34] xfs: devirtualize ->sf_get_ino and ->sf_put_ino
  2019-11-01 22:06 remove m_dirops Christoph Hellwig
                   ` (19 preceding siblings ...)
  2019-11-01 22:07 ` [PATCH 20/34] xfs: devirtualize ->sf_entsize and ->sf_nextentry Christoph Hellwig
@ 2019-11-01 22:07 ` Christoph Hellwig
  2019-11-04 20:33   ` Darrick J. Wong
  2019-11-01 22:07 ` [PATCH 22/34] xfs: devirtualize ->sf_get_ftype and ->sf_put_ftype Christoph Hellwig
                   ` (12 subsequent siblings)
  33 siblings, 1 reply; 81+ messages in thread
From: Christoph Hellwig @ 2019-11-01 22:07 UTC (permalink / raw)
  To: linux-xfs

Replace the ->sf_get_ino and ->sf_put_ino dir ops methods with directly
called xfs_dir2_sf_get_ino nd xfs_dir2_sf_put_ino helpers that take care
of the difference between the directory format with and without the file
type field.  Also move xfs_dir2_sf_get_parent_ino and
xfs_dir2_sf_put_parent_ino to xfs_dir2_sf.c with the rest of the
low-level short form entry handling.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 fs/xfs/libxfs/xfs_da_format.c  | 94 ----------------------------------
 fs/xfs/libxfs/xfs_dir2.h       |  5 --
 fs/xfs/libxfs/xfs_dir2_block.c |  2 +-
 fs/xfs/libxfs/xfs_dir2_priv.h  |  2 +
 fs/xfs/libxfs/xfs_dir2_sf.c    | 90 +++++++++++++++++++++++++++-----
 fs/xfs/xfs_dir2_readdir.c      |  2 +-
 6 files changed, 81 insertions(+), 114 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c
index f80495a38a76..f427f141d001 100644
--- a/fs/xfs/libxfs/xfs_da_format.c
+++ b/fs/xfs/libxfs/xfs_da_format.c
@@ -58,94 +58,6 @@ xfs_dir3_sfe_put_ftype(
 	sfep->name[sfep->namelen] = ftype;
 }
 
-/*
- * Inode numbers in short-form directories can come in two versions,
- * either 4 bytes or 8 bytes wide.  These helpers deal with the
- * two forms transparently by looking at the headers i8count field.
- *
- * For 64-bit inode number the most significant byte must be zero.
- */
-static xfs_ino_t
-xfs_dir2_sf_get_ino(
-	struct xfs_dir2_sf_hdr	*hdr,
-	uint8_t			*from)
-{
-	if (hdr->i8count)
-		return get_unaligned_be64(from) & 0x00ffffffffffffffULL;
-	else
-		return get_unaligned_be32(from);
-}
-
-static void
-xfs_dir2_sf_put_ino(
-	struct xfs_dir2_sf_hdr	*hdr,
-	uint8_t			*to,
-	xfs_ino_t		ino)
-{
-	ASSERT((ino & 0xff00000000000000ULL) == 0);
-
-	if (hdr->i8count)
-		put_unaligned_be64(ino, to);
-	else
-		put_unaligned_be32(ino, to);
-}
-
-xfs_ino_t
-xfs_dir2_sf_get_parent_ino(
-	struct xfs_dir2_sf_hdr	*hdr)
-{
-	return xfs_dir2_sf_get_ino(hdr, hdr->parent);
-}
-
-void
-xfs_dir2_sf_put_parent_ino(
-	struct xfs_dir2_sf_hdr	*hdr,
-	xfs_ino_t		ino)
-{
-	xfs_dir2_sf_put_ino(hdr, hdr->parent, ino);
-}
-
-/*
- * In short-form directory entries the inode numbers are stored at variable
- * offset behind the entry name. If the entry stores a filetype value, then it
- * sits between the name and the inode number. Hence the inode numbers may only
- * be accessed through the helpers below.
- */
-static xfs_ino_t
-xfs_dir2_sfe_get_ino(
-	struct xfs_dir2_sf_hdr	*hdr,
-	struct xfs_dir2_sf_entry *sfep)
-{
-	return xfs_dir2_sf_get_ino(hdr, &sfep->name[sfep->namelen]);
-}
-
-static void
-xfs_dir2_sfe_put_ino(
-	struct xfs_dir2_sf_hdr	*hdr,
-	struct xfs_dir2_sf_entry *sfep,
-	xfs_ino_t		ino)
-{
-	xfs_dir2_sf_put_ino(hdr, &sfep->name[sfep->namelen], ino);
-}
-
-static xfs_ino_t
-xfs_dir3_sfe_get_ino(
-	struct xfs_dir2_sf_hdr	*hdr,
-	struct xfs_dir2_sf_entry *sfep)
-{
-	return xfs_dir2_sf_get_ino(hdr, &sfep->name[sfep->namelen + 1]);
-}
-
-static void
-xfs_dir3_sfe_put_ino(
-	struct xfs_dir2_sf_hdr	*hdr,
-	struct xfs_dir2_sf_entry *sfep,
-	xfs_ino_t		ino)
-{
-	xfs_dir2_sf_put_ino(hdr, &sfep->name[sfep->namelen + 1], ino);
-}
-
-
 /*
  * Directory data block operations
  */
@@ -361,8 +273,6 @@ xfs_dir3_data_unused_p(struct xfs_dir2_data_hdr *hdr)
 static const struct xfs_dir_ops xfs_dir2_ops = {
 	.sf_get_ftype = xfs_dir2_sfe_get_ftype,
 	.sf_put_ftype = xfs_dir2_sfe_put_ftype,
-	.sf_get_ino = xfs_dir2_sfe_get_ino,
-	.sf_put_ino = xfs_dir2_sfe_put_ino,
 
 	.data_entsize = xfs_dir2_data_entsize,
 	.data_get_ftype = xfs_dir2_data_get_ftype,
@@ -388,8 +298,6 @@ static const struct xfs_dir_ops xfs_dir2_ops = {
 static const struct xfs_dir_ops xfs_dir2_ftype_ops = {
 	.sf_get_ftype = xfs_dir3_sfe_get_ftype,
 	.sf_put_ftype = xfs_dir3_sfe_put_ftype,
-	.sf_get_ino = xfs_dir3_sfe_get_ino,
-	.sf_put_ino = xfs_dir3_sfe_put_ino,
 
 	.data_entsize = xfs_dir3_data_entsize,
 	.data_get_ftype = xfs_dir3_data_get_ftype,
@@ -415,8 +323,6 @@ static const struct xfs_dir_ops xfs_dir2_ftype_ops = {
 static const struct xfs_dir_ops xfs_dir3_ops = {
 	.sf_get_ftype = xfs_dir3_sfe_get_ftype,
 	.sf_put_ftype = xfs_dir3_sfe_put_ftype,
-	.sf_get_ino = xfs_dir3_sfe_get_ino,
-	.sf_put_ino = xfs_dir3_sfe_put_ino,
 
 	.data_entsize = xfs_dir3_data_entsize,
 	.data_get_ftype = xfs_dir3_data_get_ftype,
diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h
index c99f0ad6607a..049d844d6a18 100644
--- a/fs/xfs/libxfs/xfs_dir2.h
+++ b/fs/xfs/libxfs/xfs_dir2.h
@@ -35,11 +35,6 @@ struct xfs_dir_ops {
 	uint8_t (*sf_get_ftype)(struct xfs_dir2_sf_entry *sfep);
 	void	(*sf_put_ftype)(struct xfs_dir2_sf_entry *sfep,
 				uint8_t ftype);
-	xfs_ino_t (*sf_get_ino)(struct xfs_dir2_sf_hdr *hdr,
-				struct xfs_dir2_sf_entry *sfep);
-	void	(*sf_put_ino)(struct xfs_dir2_sf_hdr *hdr,
-			      struct xfs_dir2_sf_entry *sfep,
-			      xfs_ino_t ino);
 
 	int	(*data_entsize)(int len);
 	uint8_t (*data_get_ftype)(struct xfs_dir2_data_entry *dep);
diff --git a/fs/xfs/libxfs/xfs_dir2_block.c b/fs/xfs/libxfs/xfs_dir2_block.c
index 88b3d1884c74..0f3024386a5c 100644
--- a/fs/xfs/libxfs/xfs_dir2_block.c
+++ b/fs/xfs/libxfs/xfs_dir2_block.c
@@ -1214,7 +1214,7 @@ xfs_dir2_sf_to_block(
 		 * Copy a real entry.
 		 */
 		dep = (xfs_dir2_data_entry_t *)((char *)hdr + newoffset);
-		dep->inumber = cpu_to_be64(dp->d_ops->sf_get_ino(sfp, sfep));
+		dep->inumber = cpu_to_be64(xfs_dir2_sf_get_ino(mp, sfp, sfep));
 		dep->namelen = sfep->namelen;
 		dp->d_ops->data_put_ftype(dep, dp->d_ops->sf_get_ftype(sfep));
 		memcpy(dep->name, sfep->name, dep->namelen);
diff --git a/fs/xfs/libxfs/xfs_dir2_priv.h b/fs/xfs/libxfs/xfs_dir2_priv.h
index a96b9ba7909b..57c0f7aee7a4 100644
--- a/fs/xfs/libxfs/xfs_dir2_priv.h
+++ b/fs/xfs/libxfs/xfs_dir2_priv.h
@@ -135,6 +135,8 @@ extern int xfs_dir2_free_read(struct xfs_trans *tp, struct xfs_inode *dp,
 		xfs_dablk_t fbno, struct xfs_buf **bpp);
 
 /* xfs_dir2_sf.c */
+xfs_ino_t xfs_dir2_sf_get_ino(struct xfs_mount *mp, struct xfs_dir2_sf_hdr *hdr,
+		struct xfs_dir2_sf_entry *sfep);
 xfs_ino_t xfs_dir2_sf_get_parent_ino(struct xfs_dir2_sf_hdr *hdr);
 void xfs_dir2_sf_put_parent_ino(struct xfs_dir2_sf_hdr *hdr, xfs_ino_t ino);
 struct xfs_dir2_sf_entry *xfs_dir2_sf_nextentry(struct xfs_mount *mp,
diff --git a/fs/xfs/libxfs/xfs_dir2_sf.c b/fs/xfs/libxfs/xfs_dir2_sf.c
index f3a4f0ddfc1a..c33d838b1a5c 100644
--- a/fs/xfs/libxfs/xfs_dir2_sf.c
+++ b/fs/xfs/libxfs/xfs_dir2_sf.c
@@ -63,6 +63,69 @@ xfs_dir2_sf_nextentry(
 		((char *)sfep + xfs_dir2_sf_entsize(mp, hdr, sfep->namelen));
 }
 
+/*
+ * In short-form directory entries the inode numbers are stored at variable
+ * offset behind the entry name. If the entry stores a filetype value, then it
+ * sits between the name and the inode number.  The actual inode numbers can
+ * come in two formats as well, either 4 bytes or 8 bytes wide.
+ */
+xfs_ino_t
+xfs_dir2_sf_get_ino(
+	struct xfs_mount		*mp,
+	struct xfs_dir2_sf_hdr		*hdr,
+	struct xfs_dir2_sf_entry	*sfep)
+{
+	uint8_t				*from = sfep->name + sfep->namelen;
+
+	if (xfs_sb_version_hasftype(&mp->m_sb))
+		from++;
+
+	if (!hdr->i8count)
+		return get_unaligned_be32(from);
+	return get_unaligned_be64(from) & 0x00ffffffffffffffULL;
+}
+
+void
+xfs_dir2_sf_put_ino(
+	struct xfs_mount		*mp,
+	struct xfs_dir2_sf_hdr		*hdr,
+	struct xfs_dir2_sf_entry	*sfep,
+	xfs_ino_t			ino)
+{
+	uint8_t				*to = sfep->name + sfep->namelen;
+
+	ASSERT((ino & 0xff00000000000000ULL) == 0);
+
+	if (xfs_sb_version_hasftype(&mp->m_sb))
+		to++;
+
+	if (hdr->i8count)
+		put_unaligned_be64(ino, to);
+	else
+		put_unaligned_be32(ino, to);
+}
+
+xfs_ino_t
+xfs_dir2_sf_get_parent_ino(
+	struct xfs_dir2_sf_hdr	*hdr)
+{
+	if (!hdr->i8count)
+		return get_unaligned_be32(hdr->parent);
+	return get_unaligned_be64(hdr->parent) & 0x00ffffffffffffffULL;
+}
+
+void
+xfs_dir2_sf_put_parent_ino(
+	struct xfs_dir2_sf_hdr		*hdr,
+	xfs_ino_t			ino)
+{
+	ASSERT((ino & 0xff00000000000000ULL) == 0);
+	if (hdr->i8count)
+		put_unaligned_be64(ino, hdr->parent);
+	else
+		put_unaligned_be32(ino, hdr->parent);
+}
+
 /*
  * Given a block directory (dp/block), calculate its size as a shortform (sf)
  * directory and a header for the sf directory, if it will fit it the
@@ -240,7 +303,7 @@ xfs_dir2_block_to_sf(
 				(xfs_dir2_data_aoff_t)
 				((char *)dep - (char *)hdr));
 			memcpy(sfep->name, dep->name, dep->namelen);
-			dp->d_ops->sf_put_ino(sfp, sfep,
+			xfs_dir2_sf_put_ino(mp, sfp, sfep,
 					      be64_to_cpu(dep->inumber));
 			dp->d_ops->sf_put_ftype(sfep,
 					dp->d_ops->data_get_ftype(dep));
@@ -413,7 +476,7 @@ xfs_dir2_sf_addname_easy(
 	sfep->namelen = args->namelen;
 	xfs_dir2_sf_put_offset(sfep, offset);
 	memcpy(sfep->name, args->name, sfep->namelen);
-	dp->d_ops->sf_put_ino(sfp, sfep, args->inumber);
+	xfs_dir2_sf_put_ino(mp, sfp, sfep, args->inumber);
 	dp->d_ops->sf_put_ftype(sfep, args->filetype);
 
 	/*
@@ -503,7 +566,7 @@ xfs_dir2_sf_addname_hard(
 	sfep->namelen = args->namelen;
 	xfs_dir2_sf_put_offset(sfep, offset);
 	memcpy(sfep->name, args->name, sfep->namelen);
-	dp->d_ops->sf_put_ino(sfp, sfep, args->inumber);
+	xfs_dir2_sf_put_ino(mp, sfp, sfep, args->inumber);
 	dp->d_ops->sf_put_ftype(sfep, args->filetype);
 	sfp->count++;
 	if (args->inumber > XFS_DIR2_MAX_SHORT_INUM && !objchange)
@@ -620,7 +683,7 @@ xfs_dir2_sf_check(
 	     i < sfp->count;
 	     i++, sfep = xfs_dir2_sf_nextentry(dp->i_mount, sfp, sfep)) {
 		ASSERT(xfs_dir2_sf_get_offset(sfep) >= offset);
-		ino = dp->d_ops->sf_get_ino(sfp, sfep);
+		ino = xfs_dir2_sf_get_ino(dp->i_mount, sfp, sfep);
 		i8count += ino > XFS_DIR2_MAX_SHORT_INUM;
 		offset =
 			xfs_dir2_sf_get_offset(sfep) +
@@ -712,7 +775,7 @@ xfs_dir2_sf_verify(
 			return __this_address;
 
 		/* Check the inode number. */
-		ino = dops->sf_get_ino(sfp, sfep);
+		ino = xfs_dir2_sf_get_ino(mp, sfp, sfep);
 		i8count += ino > XFS_DIR2_MAX_SHORT_INUM;
 		error = xfs_dir_ino_validate(mp, ino);
 		if (error)
@@ -861,7 +924,7 @@ xfs_dir2_sf_lookup(
 								sfep->namelen);
 		if (cmp != XFS_CMP_DIFFERENT && cmp != args->cmpresult) {
 			args->cmpresult = cmp;
-			args->inumber = dp->d_ops->sf_get_ino(sfp, sfep);
+			args->inumber = xfs_dir2_sf_get_ino(mp, sfp, sfep);
 			args->filetype = dp->d_ops->sf_get_ftype(sfep);
 			if (cmp == XFS_CMP_EXACT)
 				return -EEXIST;
@@ -920,7 +983,7 @@ xfs_dir2_sf_removename(
 	     i++, sfep = xfs_dir2_sf_nextentry(mp, sfp, sfep)) {
 		if (xfs_da_compname(args, sfep->name, sfep->namelen) ==
 								XFS_CMP_EXACT) {
-			ASSERT(dp->d_ops->sf_get_ino(sfp, sfep) ==
+			ASSERT(xfs_dir2_sf_get_ino(mp, sfp, sfep) ==
 			       args->inumber);
 			break;
 		}
@@ -1041,9 +1104,10 @@ xfs_dir2_sf_replace(
 		     i++, sfep = xfs_dir2_sf_nextentry(mp, sfp, sfep)) {
 			if (xfs_da_compname(args, sfep->name, sfep->namelen) ==
 								XFS_CMP_EXACT) {
-				ino = dp->d_ops->sf_get_ino(sfp, sfep);
+				ino = xfs_dir2_sf_get_ino(mp, sfp, sfep);
 				ASSERT(args->inumber != ino);
-				dp->d_ops->sf_put_ino(sfp, sfep, args->inumber);
+				xfs_dir2_sf_put_ino(mp, sfp, sfep,
+						args->inumber);
 				dp->d_ops->sf_put_ftype(sfep, args->filetype);
 				break;
 			}
@@ -1148,8 +1212,8 @@ xfs_dir2_sf_toino4(
 		sfep->namelen = oldsfep->namelen;
 		memcpy(sfep->offset, oldsfep->offset, sizeof(sfep->offset));
 		memcpy(sfep->name, oldsfep->name, sfep->namelen);
-		dp->d_ops->sf_put_ino(sfp, sfep,
-				      dp->d_ops->sf_get_ino(oldsfp, oldsfep));
+		xfs_dir2_sf_put_ino(mp, sfp, sfep,
+				xfs_dir2_sf_get_ino(mp, oldsfp, oldsfep));
 		dp->d_ops->sf_put_ftype(sfep, dp->d_ops->sf_get_ftype(oldsfep));
 	}
 	/*
@@ -1220,8 +1284,8 @@ xfs_dir2_sf_toino8(
 		sfep->namelen = oldsfep->namelen;
 		memcpy(sfep->offset, oldsfep->offset, sizeof(sfep->offset));
 		memcpy(sfep->name, oldsfep->name, sfep->namelen);
-		dp->d_ops->sf_put_ino(sfp, sfep,
-				      dp->d_ops->sf_get_ino(oldsfp, oldsfep));
+		xfs_dir2_sf_put_ino(mp, sfp, sfep,
+				xfs_dir2_sf_get_ino(mp, oldsfp, oldsfep));
 		dp->d_ops->sf_put_ftype(sfep, dp->d_ops->sf_get_ftype(oldsfep));
 	}
 	/*
diff --git a/fs/xfs/xfs_dir2_readdir.c b/fs/xfs/xfs_dir2_readdir.c
index 7d150e914d00..9d318f091a73 100644
--- a/fs/xfs/xfs_dir2_readdir.c
+++ b/fs/xfs/xfs_dir2_readdir.c
@@ -114,7 +114,7 @@ xfs_dir2_sf_getdents(
 			continue;
 		}
 
-		ino = dp->d_ops->sf_get_ino(sfp, sfep);
+		ino = xfs_dir2_sf_get_ino(mp, sfp, sfep);
 		filetype = dp->d_ops->sf_get_ftype(sfep);
 		ctx->pos = off & 0x7fffffff;
 		if (!xfs_dir2_namecheck(sfep->name, sfep->namelen)) {
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 22/34] xfs: devirtualize ->sf_get_ftype and ->sf_put_ftype
  2019-11-01 22:06 remove m_dirops Christoph Hellwig
                   ` (20 preceding siblings ...)
  2019-11-01 22:07 ` [PATCH 21/34] xfs: devirtualize ->sf_get_ino and ->sf_put_ino Christoph Hellwig
@ 2019-11-01 22:07 ` Christoph Hellwig
  2019-11-04 20:34   ` Darrick J. Wong
  2019-11-01 22:07 ` [PATCH 23/34] xfs: remove the ->data_dot_entry_p and ->data_dotdot_entry_p methods Christoph Hellwig
                   ` (11 subsequent siblings)
  33 siblings, 1 reply; 81+ messages in thread
From: Christoph Hellwig @ 2019-11-01 22:07 UTC (permalink / raw)
  To: linux-xfs

Replace the ->sf_get_ftype and ->sf_put_ftype dir ops methods with
directly called xfs_dir2_sf_get_ftype and xfs_dir2_sf_put_ftype helpers
that takes care of the differences between the directory format with and
without the file type field.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 fs/xfs/libxfs/xfs_da_format.c  | 52 -----------------------------
 fs/xfs/libxfs/xfs_dir2.h       |  4 ---
 fs/xfs/libxfs/xfs_dir2_block.c |  2 +-
 fs/xfs/libxfs/xfs_dir2_priv.h  |  2 ++
 fs/xfs/libxfs/xfs_dir2_sf.c    | 60 ++++++++++++++++++++++++++--------
 fs/xfs/xfs_dir2_readdir.c      |  2 +-
 6 files changed, 50 insertions(+), 72 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c
index f427f141d001..1c72b46344d6 100644
--- a/fs/xfs/libxfs/xfs_da_format.c
+++ b/fs/xfs/libxfs/xfs_da_format.c
@@ -15,49 +15,6 @@
 #include "xfs_dir2.h"
 #include "xfs_dir2_priv.h"
 
-/*
- * For filetype enabled shortform directories, the file type field is stored at
- * the end of the name.  Because it's only a single byte, endian conversion is
- * not necessary. For non-filetype enable directories, the type is always
- * unknown and we never store the value.
- */
-static uint8_t
-xfs_dir2_sfe_get_ftype(
-	struct xfs_dir2_sf_entry *sfep)
-{
-	return XFS_DIR3_FT_UNKNOWN;
-}
-
-static void
-xfs_dir2_sfe_put_ftype(
-	struct xfs_dir2_sf_entry *sfep,
-	uint8_t			ftype)
-{
-	ASSERT(ftype < XFS_DIR3_FT_MAX);
-}
-
-static uint8_t
-xfs_dir3_sfe_get_ftype(
-	struct xfs_dir2_sf_entry *sfep)
-{
-	uint8_t		ftype;
-
-	ftype = sfep->name[sfep->namelen];
-	if (ftype >= XFS_DIR3_FT_MAX)
-		return XFS_DIR3_FT_UNKNOWN;
-	return ftype;
-}
-
-static void
-xfs_dir3_sfe_put_ftype(
-	struct xfs_dir2_sf_entry *sfep,
-	uint8_t			ftype)
-{
-	ASSERT(ftype < XFS_DIR3_FT_MAX);
-
-	sfep->name[sfep->namelen] = ftype;
-}
-
 /*
  * Directory data block operations
  */
@@ -271,9 +228,6 @@ xfs_dir3_data_unused_p(struct xfs_dir2_data_hdr *hdr)
 }
 
 static const struct xfs_dir_ops xfs_dir2_ops = {
-	.sf_get_ftype = xfs_dir2_sfe_get_ftype,
-	.sf_put_ftype = xfs_dir2_sfe_put_ftype,
-
 	.data_entsize = xfs_dir2_data_entsize,
 	.data_get_ftype = xfs_dir2_data_get_ftype,
 	.data_put_ftype = xfs_dir2_data_put_ftype,
@@ -296,9 +250,6 @@ static const struct xfs_dir_ops xfs_dir2_ops = {
 };
 
 static const struct xfs_dir_ops xfs_dir2_ftype_ops = {
-	.sf_get_ftype = xfs_dir3_sfe_get_ftype,
-	.sf_put_ftype = xfs_dir3_sfe_put_ftype,
-
 	.data_entsize = xfs_dir3_data_entsize,
 	.data_get_ftype = xfs_dir3_data_get_ftype,
 	.data_put_ftype = xfs_dir3_data_put_ftype,
@@ -321,9 +272,6 @@ static const struct xfs_dir_ops xfs_dir2_ftype_ops = {
 };
 
 static const struct xfs_dir_ops xfs_dir3_ops = {
-	.sf_get_ftype = xfs_dir3_sfe_get_ftype,
-	.sf_put_ftype = xfs_dir3_sfe_put_ftype,
-
 	.data_entsize = xfs_dir3_data_entsize,
 	.data_get_ftype = xfs_dir3_data_get_ftype,
 	.data_put_ftype = xfs_dir3_data_put_ftype,
diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h
index 049d844d6a18..61cc9ae837d5 100644
--- a/fs/xfs/libxfs/xfs_dir2.h
+++ b/fs/xfs/libxfs/xfs_dir2.h
@@ -32,10 +32,6 @@ extern unsigned char xfs_mode_to_ftype(int mode);
  * directory operations vector for encode/decode routines
  */
 struct xfs_dir_ops {
-	uint8_t (*sf_get_ftype)(struct xfs_dir2_sf_entry *sfep);
-	void	(*sf_put_ftype)(struct xfs_dir2_sf_entry *sfep,
-				uint8_t ftype);
-
 	int	(*data_entsize)(int len);
 	uint8_t (*data_get_ftype)(struct xfs_dir2_data_entry *dep);
 	void	(*data_put_ftype)(struct xfs_dir2_data_entry *dep,
diff --git a/fs/xfs/libxfs/xfs_dir2_block.c b/fs/xfs/libxfs/xfs_dir2_block.c
index 0f3024386a5c..5877272dc63e 100644
--- a/fs/xfs/libxfs/xfs_dir2_block.c
+++ b/fs/xfs/libxfs/xfs_dir2_block.c
@@ -1216,7 +1216,7 @@ xfs_dir2_sf_to_block(
 		dep = (xfs_dir2_data_entry_t *)((char *)hdr + newoffset);
 		dep->inumber = cpu_to_be64(xfs_dir2_sf_get_ino(mp, sfp, sfep));
 		dep->namelen = sfep->namelen;
-		dp->d_ops->data_put_ftype(dep, dp->d_ops->sf_get_ftype(sfep));
+		dp->d_ops->data_put_ftype(dep, xfs_dir2_sf_get_ftype(mp, sfep));
 		memcpy(dep->name, sfep->name, dep->namelen);
 		tagp = dp->d_ops->data_entry_tag_p(dep);
 		*tagp = cpu_to_be16((char *)dep - (char *)hdr);
diff --git a/fs/xfs/libxfs/xfs_dir2_priv.h b/fs/xfs/libxfs/xfs_dir2_priv.h
index 57c0f7aee7a4..a92d9f0f83e0 100644
--- a/fs/xfs/libxfs/xfs_dir2_priv.h
+++ b/fs/xfs/libxfs/xfs_dir2_priv.h
@@ -139,6 +139,8 @@ xfs_ino_t xfs_dir2_sf_get_ino(struct xfs_mount *mp, struct xfs_dir2_sf_hdr *hdr,
 		struct xfs_dir2_sf_entry *sfep);
 xfs_ino_t xfs_dir2_sf_get_parent_ino(struct xfs_dir2_sf_hdr *hdr);
 void xfs_dir2_sf_put_parent_ino(struct xfs_dir2_sf_hdr *hdr, xfs_ino_t ino);
+uint8_t xfs_dir2_sf_get_ftype(struct xfs_mount *mp,
+		struct xfs_dir2_sf_entry *sfep);
 struct xfs_dir2_sf_entry *xfs_dir2_sf_nextentry(struct xfs_mount *mp,
 		struct xfs_dir2_sf_hdr *hdr, struct xfs_dir2_sf_entry *sfep);
 extern int xfs_dir2_block_sfsize(struct xfs_inode *dp,
diff --git a/fs/xfs/libxfs/xfs_dir2_sf.c b/fs/xfs/libxfs/xfs_dir2_sf.c
index c33d838b1a5c..10199261c94c 100644
--- a/fs/xfs/libxfs/xfs_dir2_sf.c
+++ b/fs/xfs/libxfs/xfs_dir2_sf.c
@@ -126,6 +126,37 @@ xfs_dir2_sf_put_parent_ino(
 		put_unaligned_be32(ino, hdr->parent);
 }
 
+/*
+ * The file type field is stored at the end of the name for filetype enabled
+ * shortform directories, or not at all otherwise.
+ */
+uint8_t
+xfs_dir2_sf_get_ftype(
+	struct xfs_mount		*mp,
+	struct xfs_dir2_sf_entry	*sfep)
+{
+	if (xfs_sb_version_hasftype(&mp->m_sb)) {
+		uint8_t			ftype = sfep->name[sfep->namelen];
+
+		if (ftype < XFS_DIR3_FT_MAX)
+			return ftype;
+	}
+
+	return XFS_DIR3_FT_UNKNOWN;
+}
+
+static void
+xfs_dir2_sf_put_ftype(
+	struct xfs_mount	*mp,
+	struct xfs_dir2_sf_entry *sfep,
+	uint8_t			ftype)
+{
+	ASSERT(ftype < XFS_DIR3_FT_MAX);
+
+	if (xfs_sb_version_hasftype(&mp->m_sb))
+		sfep->name[sfep->namelen] = ftype;
+}
+
 /*
  * Given a block directory (dp/block), calculate its size as a shortform (sf)
  * directory and a header for the sf directory, if it will fit it the
@@ -305,7 +336,7 @@ xfs_dir2_block_to_sf(
 			memcpy(sfep->name, dep->name, dep->namelen);
 			xfs_dir2_sf_put_ino(mp, sfp, sfep,
 					      be64_to_cpu(dep->inumber));
-			dp->d_ops->sf_put_ftype(sfep,
+			xfs_dir2_sf_put_ftype(mp, sfep,
 					dp->d_ops->data_get_ftype(dep));
 
 			sfep = xfs_dir2_sf_nextentry(mp, sfp, sfep);
@@ -477,7 +508,7 @@ xfs_dir2_sf_addname_easy(
 	xfs_dir2_sf_put_offset(sfep, offset);
 	memcpy(sfep->name, args->name, sfep->namelen);
 	xfs_dir2_sf_put_ino(mp, sfp, sfep, args->inumber);
-	dp->d_ops->sf_put_ftype(sfep, args->filetype);
+	xfs_dir2_sf_put_ftype(mp, sfep, args->filetype);
 
 	/*
 	 * Update the header and inode.
@@ -567,7 +598,7 @@ xfs_dir2_sf_addname_hard(
 	xfs_dir2_sf_put_offset(sfep, offset);
 	memcpy(sfep->name, args->name, sfep->namelen);
 	xfs_dir2_sf_put_ino(mp, sfp, sfep, args->inumber);
-	dp->d_ops->sf_put_ftype(sfep, args->filetype);
+	xfs_dir2_sf_put_ftype(mp, sfep, args->filetype);
 	sfp->count++;
 	if (args->inumber > XFS_DIR2_MAX_SHORT_INUM && !objchange)
 		sfp->i8count++;
@@ -664,7 +695,8 @@ static void
 xfs_dir2_sf_check(
 	xfs_da_args_t		*args)		/* operation arguments */
 {
-	xfs_inode_t		*dp;		/* incore directory inode */
+	struct xfs_inode	*dp = args->dp;
+	struct xfs_mount	*mp = dp->i_mount;
 	int			i;		/* entry number */
 	int			i8count;	/* number of big inode#s */
 	xfs_ino_t		ino;		/* entry inode number */
@@ -672,8 +704,6 @@ xfs_dir2_sf_check(
 	xfs_dir2_sf_entry_t	*sfep;		/* shortform dir entry */
 	xfs_dir2_sf_hdr_t	*sfp;		/* shortform structure */
 
-	dp = args->dp;
-
 	sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data;
 	offset = dp->d_ops->data_first_offset;
 	ino = xfs_dir2_sf_get_parent_ino(sfp);
@@ -681,14 +711,14 @@ xfs_dir2_sf_check(
 
 	for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp);
 	     i < sfp->count;
-	     i++, sfep = xfs_dir2_sf_nextentry(dp->i_mount, sfp, sfep)) {
+	     i++, sfep = xfs_dir2_sf_nextentry(mp, sfp, sfep)) {
 		ASSERT(xfs_dir2_sf_get_offset(sfep) >= offset);
-		ino = xfs_dir2_sf_get_ino(dp->i_mount, sfp, sfep);
+		ino = xfs_dir2_sf_get_ino(mp, sfp, sfep);
 		i8count += ino > XFS_DIR2_MAX_SHORT_INUM;
 		offset =
 			xfs_dir2_sf_get_offset(sfep) +
 			dp->d_ops->data_entsize(sfep->namelen);
-		ASSERT(dp->d_ops->sf_get_ftype(sfep) < XFS_DIR3_FT_MAX);
+		ASSERT(xfs_dir2_sf_get_ftype(mp, sfep) < XFS_DIR3_FT_MAX);
 	}
 	ASSERT(i8count == sfp->i8count);
 	ASSERT((char *)sfep - (char *)sfp == dp->i_d.di_size);
@@ -782,7 +812,7 @@ xfs_dir2_sf_verify(
 			return __this_address;
 
 		/* Check the file type. */
-		filetype = dops->sf_get_ftype(sfep);
+		filetype = xfs_dir2_sf_get_ftype(mp, sfep);
 		if (filetype >= XFS_DIR3_FT_MAX)
 			return __this_address;
 
@@ -925,7 +955,7 @@ xfs_dir2_sf_lookup(
 		if (cmp != XFS_CMP_DIFFERENT && cmp != args->cmpresult) {
 			args->cmpresult = cmp;
 			args->inumber = xfs_dir2_sf_get_ino(mp, sfp, sfep);
-			args->filetype = dp->d_ops->sf_get_ftype(sfep);
+			args->filetype = xfs_dir2_sf_get_ftype(mp, sfep);
 			if (cmp == XFS_CMP_EXACT)
 				return -EEXIST;
 			ci_sfep = sfep;
@@ -1108,7 +1138,7 @@ xfs_dir2_sf_replace(
 				ASSERT(args->inumber != ino);
 				xfs_dir2_sf_put_ino(mp, sfp, sfep,
 						args->inumber);
-				dp->d_ops->sf_put_ftype(sfep, args->filetype);
+				xfs_dir2_sf_put_ftype(mp, sfep, args->filetype);
 				break;
 			}
 		}
@@ -1214,7 +1244,8 @@ xfs_dir2_sf_toino4(
 		memcpy(sfep->name, oldsfep->name, sfep->namelen);
 		xfs_dir2_sf_put_ino(mp, sfp, sfep,
 				xfs_dir2_sf_get_ino(mp, oldsfp, oldsfep));
-		dp->d_ops->sf_put_ftype(sfep, dp->d_ops->sf_get_ftype(oldsfep));
+		xfs_dir2_sf_put_ftype(mp, sfep,
+				xfs_dir2_sf_get_ftype(mp, oldsfep));
 	}
 	/*
 	 * Clean up the inode.
@@ -1286,7 +1317,8 @@ xfs_dir2_sf_toino8(
 		memcpy(sfep->name, oldsfep->name, sfep->namelen);
 		xfs_dir2_sf_put_ino(mp, sfp, sfep,
 				xfs_dir2_sf_get_ino(mp, oldsfp, oldsfep));
-		dp->d_ops->sf_put_ftype(sfep, dp->d_ops->sf_get_ftype(oldsfep));
+		xfs_dir2_sf_put_ftype(mp, sfep,
+				xfs_dir2_sf_get_ftype(mp, oldsfep));
 	}
 	/*
 	 * Clean up the inode.
diff --git a/fs/xfs/xfs_dir2_readdir.c b/fs/xfs/xfs_dir2_readdir.c
index 9d318f091a73..e18045465455 100644
--- a/fs/xfs/xfs_dir2_readdir.c
+++ b/fs/xfs/xfs_dir2_readdir.c
@@ -115,7 +115,7 @@ xfs_dir2_sf_getdents(
 		}
 
 		ino = xfs_dir2_sf_get_ino(mp, sfp, sfep);
-		filetype = dp->d_ops->sf_get_ftype(sfep);
+		filetype = xfs_dir2_sf_get_ftype(mp, sfep);
 		ctx->pos = off & 0x7fffffff;
 		if (!xfs_dir2_namecheck(sfep->name, sfep->namelen)) {
 			XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW,
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 23/34] xfs: remove the ->data_dot_entry_p and ->data_dotdot_entry_p methods
  2019-11-01 22:06 remove m_dirops Christoph Hellwig
                   ` (21 preceding siblings ...)
  2019-11-01 22:07 ` [PATCH 22/34] xfs: devirtualize ->sf_get_ftype and ->sf_put_ftype Christoph Hellwig
@ 2019-11-01 22:07 ` Christoph Hellwig
  2019-11-04 20:37   ` Darrick J. Wong
  2019-11-01 22:07 ` [PATCH 24/34] xfs: remove the unused ->data_first_entry_p method Christoph Hellwig
                   ` (10 subsequent siblings)
  33 siblings, 1 reply; 81+ messages in thread
From: Christoph Hellwig @ 2019-11-01 22:07 UTC (permalink / raw)
  To: linux-xfs

Replace the only user of the ->data_dot_entry_p and ->data_dotdot_entry_p
dir ops methods with direct calculations using ->data_dot_offset and
->data_dotdot_offset.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 fs/xfs/libxfs/xfs_da_format.c  | 52 ----------------------------------
 fs/xfs/libxfs/xfs_dir2.h       |  4 ---
 fs/xfs/libxfs/xfs_dir2_block.c |  4 +--
 3 files changed, 2 insertions(+), 58 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c
index 1c72b46344d6..84f8355072b4 100644
--- a/fs/xfs/libxfs/xfs_da_format.c
+++ b/fs/xfs/libxfs/xfs_da_format.c
@@ -111,26 +111,6 @@ xfs_dir3_data_entry_tag_p(
 		xfs_dir3_data_entsize(dep->namelen) - sizeof(__be16));
 }
 
-/*
- * location of . and .. in data space (always block 0)
- */
-static struct xfs_dir2_data_entry *
-xfs_dir2_data_dot_entry_p(
-	struct xfs_dir2_data_hdr *hdr)
-{
-	return (struct xfs_dir2_data_entry *)
-		((char *)hdr + sizeof(struct xfs_dir2_data_hdr));
-}
-
-static struct xfs_dir2_data_entry *
-xfs_dir2_data_dotdot_entry_p(
-	struct xfs_dir2_data_hdr *hdr)
-{
-	return (struct xfs_dir2_data_entry *)
-		((char *)hdr + sizeof(struct xfs_dir2_data_hdr) +
-				XFS_DIR2_DATA_ENTSIZE(1));
-}
-
 static struct xfs_dir2_data_entry *
 xfs_dir2_data_first_entry_p(
 	struct xfs_dir2_data_hdr *hdr)
@@ -141,15 +121,6 @@ xfs_dir2_data_first_entry_p(
 				XFS_DIR2_DATA_ENTSIZE(2));
 }
 
-static struct xfs_dir2_data_entry *
-xfs_dir2_ftype_data_dotdot_entry_p(
-	struct xfs_dir2_data_hdr *hdr)
-{
-	return (struct xfs_dir2_data_entry *)
-		((char *)hdr + sizeof(struct xfs_dir2_data_hdr) +
-				XFS_DIR3_DATA_ENTSIZE(1));
-}
-
 static struct xfs_dir2_data_entry *
 xfs_dir2_ftype_data_first_entry_p(
 	struct xfs_dir2_data_hdr *hdr)
@@ -160,23 +131,6 @@ xfs_dir2_ftype_data_first_entry_p(
 				XFS_DIR3_DATA_ENTSIZE(2));
 }
 
-static struct xfs_dir2_data_entry *
-xfs_dir3_data_dot_entry_p(
-	struct xfs_dir2_data_hdr *hdr)
-{
-	return (struct xfs_dir2_data_entry *)
-		((char *)hdr + sizeof(struct xfs_dir3_data_hdr));
-}
-
-static struct xfs_dir2_data_entry *
-xfs_dir3_data_dotdot_entry_p(
-	struct xfs_dir2_data_hdr *hdr)
-{
-	return (struct xfs_dir2_data_entry *)
-		((char *)hdr + sizeof(struct xfs_dir3_data_hdr) +
-				XFS_DIR3_DATA_ENTSIZE(1));
-}
-
 static struct xfs_dir2_data_entry *
 xfs_dir3_data_first_entry_p(
 	struct xfs_dir2_data_hdr *hdr)
@@ -242,8 +196,6 @@ static const struct xfs_dir_ops xfs_dir2_ops = {
 				XFS_DIR2_DATA_ENTSIZE(2),
 	.data_entry_offset = sizeof(struct xfs_dir2_data_hdr),
 
-	.data_dot_entry_p = xfs_dir2_data_dot_entry_p,
-	.data_dotdot_entry_p = xfs_dir2_data_dotdot_entry_p,
 	.data_first_entry_p = xfs_dir2_data_first_entry_p,
 	.data_entry_p = xfs_dir2_data_entry_p,
 	.data_unused_p = xfs_dir2_data_unused_p,
@@ -264,8 +216,6 @@ static const struct xfs_dir_ops xfs_dir2_ftype_ops = {
 				XFS_DIR3_DATA_ENTSIZE(2),
 	.data_entry_offset = sizeof(struct xfs_dir2_data_hdr),
 
-	.data_dot_entry_p = xfs_dir2_data_dot_entry_p,
-	.data_dotdot_entry_p = xfs_dir2_ftype_data_dotdot_entry_p,
 	.data_first_entry_p = xfs_dir2_ftype_data_first_entry_p,
 	.data_entry_p = xfs_dir2_data_entry_p,
 	.data_unused_p = xfs_dir2_data_unused_p,
@@ -286,8 +236,6 @@ static const struct xfs_dir_ops xfs_dir3_ops = {
 				XFS_DIR3_DATA_ENTSIZE(2),
 	.data_entry_offset = sizeof(struct xfs_dir3_data_hdr),
 
-	.data_dot_entry_p = xfs_dir3_data_dot_entry_p,
-	.data_dotdot_entry_p = xfs_dir3_data_dotdot_entry_p,
 	.data_first_entry_p = xfs_dir3_data_first_entry_p,
 	.data_entry_p = xfs_dir3_data_entry_p,
 	.data_unused_p = xfs_dir3_data_unused_p,
diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h
index 61cc9ae837d5..0198887a1c54 100644
--- a/fs/xfs/libxfs/xfs_dir2.h
+++ b/fs/xfs/libxfs/xfs_dir2.h
@@ -45,10 +45,6 @@ struct xfs_dir_ops {
 	xfs_dir2_data_aoff_t data_first_offset;
 	size_t	data_entry_offset;
 
-	struct xfs_dir2_data_entry *
-		(*data_dot_entry_p)(struct xfs_dir2_data_hdr *hdr);
-	struct xfs_dir2_data_entry *
-		(*data_dotdot_entry_p)(struct xfs_dir2_data_hdr *hdr);
 	struct xfs_dir2_data_entry *
 		(*data_first_entry_p)(struct xfs_dir2_data_hdr *hdr);
 	struct xfs_dir2_data_entry *
diff --git a/fs/xfs/libxfs/xfs_dir2_block.c b/fs/xfs/libxfs/xfs_dir2_block.c
index 5877272dc63e..34e0cdf03950 100644
--- a/fs/xfs/libxfs/xfs_dir2_block.c
+++ b/fs/xfs/libxfs/xfs_dir2_block.c
@@ -1148,7 +1148,7 @@ xfs_dir2_sf_to_block(
 	/*
 	 * Create entry for .
 	 */
-	dep = dp->d_ops->data_dot_entry_p(hdr);
+	dep = (void *)hdr + dp->d_ops->data_dot_offset;
 	dep->inumber = cpu_to_be64(dp->i_ino);
 	dep->namelen = 1;
 	dep->name[0] = '.';
@@ -1162,7 +1162,7 @@ xfs_dir2_sf_to_block(
 	/*
 	 * Create entry for ..
 	 */
-	dep = dp->d_ops->data_dotdot_entry_p(hdr);
+	dep = (void *)hdr + dp->d_ops->data_dotdot_offset;
 	dep->inumber = cpu_to_be64(xfs_dir2_sf_get_parent_ino(sfp));
 	dep->namelen = 2;
 	dep->name[0] = dep->name[1] = '.';
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 24/34] xfs: remove the unused ->data_first_entry_p method
  2019-11-01 22:06 remove m_dirops Christoph Hellwig
                   ` (22 preceding siblings ...)
  2019-11-01 22:07 ` [PATCH 23/34] xfs: remove the ->data_dot_entry_p and ->data_dotdot_entry_p methods Christoph Hellwig
@ 2019-11-01 22:07 ` Christoph Hellwig
  2019-11-04 20:38   ` Darrick J. Wong
  2019-11-01 22:07 ` [PATCH 25/34] xfs: remove the ->data_entry_entry_p method Christoph Hellwig
                   ` (9 subsequent siblings)
  33 siblings, 1 reply; 81+ messages in thread
From: Christoph Hellwig @ 2019-11-01 22:07 UTC (permalink / raw)
  To: linux-xfs

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 fs/xfs/libxfs/xfs_da_format.c | 33 ---------------------------------
 fs/xfs/libxfs/xfs_dir2.h      |  2 --
 2 files changed, 35 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c
index 84f8355072b4..35edf470efc8 100644
--- a/fs/xfs/libxfs/xfs_da_format.c
+++ b/fs/xfs/libxfs/xfs_da_format.c
@@ -111,36 +111,6 @@ xfs_dir3_data_entry_tag_p(
 		xfs_dir3_data_entsize(dep->namelen) - sizeof(__be16));
 }
 
-static struct xfs_dir2_data_entry *
-xfs_dir2_data_first_entry_p(
-	struct xfs_dir2_data_hdr *hdr)
-{
-	return (struct xfs_dir2_data_entry *)
-		((char *)hdr + sizeof(struct xfs_dir2_data_hdr) +
-				XFS_DIR2_DATA_ENTSIZE(1) +
-				XFS_DIR2_DATA_ENTSIZE(2));
-}
-
-static struct xfs_dir2_data_entry *
-xfs_dir2_ftype_data_first_entry_p(
-	struct xfs_dir2_data_hdr *hdr)
-{
-	return (struct xfs_dir2_data_entry *)
-		((char *)hdr + sizeof(struct xfs_dir2_data_hdr) +
-				XFS_DIR3_DATA_ENTSIZE(1) +
-				XFS_DIR3_DATA_ENTSIZE(2));
-}
-
-static struct xfs_dir2_data_entry *
-xfs_dir3_data_first_entry_p(
-	struct xfs_dir2_data_hdr *hdr)
-{
-	return (struct xfs_dir2_data_entry *)
-		((char *)hdr + sizeof(struct xfs_dir3_data_hdr) +
-				XFS_DIR3_DATA_ENTSIZE(1) +
-				XFS_DIR3_DATA_ENTSIZE(2));
-}
-
 static struct xfs_dir2_data_free *
 xfs_dir2_data_bestfree_p(struct xfs_dir2_data_hdr *hdr)
 {
@@ -196,7 +166,6 @@ static const struct xfs_dir_ops xfs_dir2_ops = {
 				XFS_DIR2_DATA_ENTSIZE(2),
 	.data_entry_offset = sizeof(struct xfs_dir2_data_hdr),
 
-	.data_first_entry_p = xfs_dir2_data_first_entry_p,
 	.data_entry_p = xfs_dir2_data_entry_p,
 	.data_unused_p = xfs_dir2_data_unused_p,
 };
@@ -216,7 +185,6 @@ static const struct xfs_dir_ops xfs_dir2_ftype_ops = {
 				XFS_DIR3_DATA_ENTSIZE(2),
 	.data_entry_offset = sizeof(struct xfs_dir2_data_hdr),
 
-	.data_first_entry_p = xfs_dir2_ftype_data_first_entry_p,
 	.data_entry_p = xfs_dir2_data_entry_p,
 	.data_unused_p = xfs_dir2_data_unused_p,
 };
@@ -236,7 +204,6 @@ static const struct xfs_dir_ops xfs_dir3_ops = {
 				XFS_DIR3_DATA_ENTSIZE(2),
 	.data_entry_offset = sizeof(struct xfs_dir3_data_hdr),
 
-	.data_first_entry_p = xfs_dir3_data_first_entry_p,
 	.data_entry_p = xfs_dir3_data_entry_p,
 	.data_unused_p = xfs_dir3_data_unused_p,
 };
diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h
index 0198887a1c54..20417c42ca6f 100644
--- a/fs/xfs/libxfs/xfs_dir2.h
+++ b/fs/xfs/libxfs/xfs_dir2.h
@@ -45,8 +45,6 @@ struct xfs_dir_ops {
 	xfs_dir2_data_aoff_t data_first_offset;
 	size_t	data_entry_offset;
 
-	struct xfs_dir2_data_entry *
-		(*data_first_entry_p)(struct xfs_dir2_data_hdr *hdr);
 	struct xfs_dir2_data_entry *
 		(*data_entry_p)(struct xfs_dir2_data_hdr *hdr);
 	struct xfs_dir2_data_unused *
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 25/34] xfs: remove the ->data_entry_entry_p method
  2019-11-01 22:06 remove m_dirops Christoph Hellwig
                   ` (23 preceding siblings ...)
  2019-11-01 22:07 ` [PATCH 24/34] xfs: remove the unused ->data_first_entry_p method Christoph Hellwig
@ 2019-11-01 22:07 ` Christoph Hellwig
  2019-11-04 20:41   ` Darrick J. Wong
  2019-11-01 22:07 ` [PATCH 26/34] xfs: devirtualize ->data_entsize Christoph Hellwig
                   ` (8 subsequent siblings)
  33 siblings, 1 reply; 81+ messages in thread
From: Christoph Hellwig @ 2019-11-01 22:07 UTC (permalink / raw)
  To: linux-xfs

Replace the users of the ->data_entry_entry_p dir ops method with a
direct calculation using ->data_entry_offset.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 fs/xfs/libxfs/xfs_da_format.c  | 37 ----------------------------------
 fs/xfs/libxfs/xfs_dir2.h       |  5 -----
 fs/xfs/libxfs/xfs_dir2_block.c |  2 +-
 fs/xfs/libxfs/xfs_dir2_data.c  |  6 +++---
 fs/xfs/libxfs/xfs_dir2_sf.c    |  2 +-
 fs/xfs/scrub/dir.c             |  4 ++--
 fs/xfs/xfs_dir2_readdir.c      |  4 ++--
 7 files changed, 9 insertions(+), 51 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c
index 35edf470efc8..47c56f6dd872 100644
--- a/fs/xfs/libxfs/xfs_da_format.c
+++ b/fs/xfs/libxfs/xfs_da_format.c
@@ -123,34 +123,6 @@ xfs_dir3_data_bestfree_p(struct xfs_dir2_data_hdr *hdr)
 	return ((struct xfs_dir3_data_hdr *)hdr)->best_free;
 }
 
-static struct xfs_dir2_data_entry *
-xfs_dir2_data_entry_p(struct xfs_dir2_data_hdr *hdr)
-{
-	return (struct xfs_dir2_data_entry *)
-		((char *)hdr + sizeof(struct xfs_dir2_data_hdr));
-}
-
-static struct xfs_dir2_data_unused *
-xfs_dir2_data_unused_p(struct xfs_dir2_data_hdr *hdr)
-{
-	return (struct xfs_dir2_data_unused *)
-		((char *)hdr + sizeof(struct xfs_dir2_data_hdr));
-}
-
-static struct xfs_dir2_data_entry *
-xfs_dir3_data_entry_p(struct xfs_dir2_data_hdr *hdr)
-{
-	return (struct xfs_dir2_data_entry *)
-		((char *)hdr + sizeof(struct xfs_dir3_data_hdr));
-}
-
-static struct xfs_dir2_data_unused *
-xfs_dir3_data_unused_p(struct xfs_dir2_data_hdr *hdr)
-{
-	return (struct xfs_dir2_data_unused *)
-		((char *)hdr + sizeof(struct xfs_dir3_data_hdr));
-}
-
 static const struct xfs_dir_ops xfs_dir2_ops = {
 	.data_entsize = xfs_dir2_data_entsize,
 	.data_get_ftype = xfs_dir2_data_get_ftype,
@@ -165,9 +137,6 @@ static const struct xfs_dir_ops xfs_dir2_ops = {
 				XFS_DIR2_DATA_ENTSIZE(1) +
 				XFS_DIR2_DATA_ENTSIZE(2),
 	.data_entry_offset = sizeof(struct xfs_dir2_data_hdr),
-
-	.data_entry_p = xfs_dir2_data_entry_p,
-	.data_unused_p = xfs_dir2_data_unused_p,
 };
 
 static const struct xfs_dir_ops xfs_dir2_ftype_ops = {
@@ -184,9 +153,6 @@ static const struct xfs_dir_ops xfs_dir2_ftype_ops = {
 				XFS_DIR3_DATA_ENTSIZE(1) +
 				XFS_DIR3_DATA_ENTSIZE(2),
 	.data_entry_offset = sizeof(struct xfs_dir2_data_hdr),
-
-	.data_entry_p = xfs_dir2_data_entry_p,
-	.data_unused_p = xfs_dir2_data_unused_p,
 };
 
 static const struct xfs_dir_ops xfs_dir3_ops = {
@@ -203,9 +169,6 @@ static const struct xfs_dir_ops xfs_dir3_ops = {
 				XFS_DIR3_DATA_ENTSIZE(1) +
 				XFS_DIR3_DATA_ENTSIZE(2),
 	.data_entry_offset = sizeof(struct xfs_dir3_data_hdr),
-
-	.data_entry_p = xfs_dir3_data_entry_p,
-	.data_unused_p = xfs_dir3_data_unused_p,
 };
 
 /*
diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h
index 20417c42ca6f..e9de15e62630 100644
--- a/fs/xfs/libxfs/xfs_dir2.h
+++ b/fs/xfs/libxfs/xfs_dir2.h
@@ -44,11 +44,6 @@ struct xfs_dir_ops {
 	xfs_dir2_data_aoff_t data_dotdot_offset;
 	xfs_dir2_data_aoff_t data_first_offset;
 	size_t	data_entry_offset;
-
-	struct xfs_dir2_data_entry *
-		(*data_entry_p)(struct xfs_dir2_data_hdr *hdr);
-	struct xfs_dir2_data_unused *
-		(*data_unused_p)(struct xfs_dir2_data_hdr *hdr);
 };
 
 extern const struct xfs_dir_ops *
diff --git a/fs/xfs/libxfs/xfs_dir2_block.c b/fs/xfs/libxfs/xfs_dir2_block.c
index 34e0cdf03950..b32beb71b7b2 100644
--- a/fs/xfs/libxfs/xfs_dir2_block.c
+++ b/fs/xfs/libxfs/xfs_dir2_block.c
@@ -1122,7 +1122,7 @@ xfs_dir2_sf_to_block(
 	 * The whole thing is initialized to free by the init routine.
 	 * Say we're using the leaf and tail area.
 	 */
-	dup = dp->d_ops->data_unused_p(hdr);
+	dup = (void *)hdr + dp->d_ops->data_entry_offset;
 	needlog = needscan = 0;
 	error = xfs_dir2_data_use_free(args, bp, dup, args->geo->blksize - i,
 			i, &needlog, &needscan);
diff --git a/fs/xfs/libxfs/xfs_dir2_data.c b/fs/xfs/libxfs/xfs_dir2_data.c
index 2c79be4c3153..edb3fe5c9174 100644
--- a/fs/xfs/libxfs/xfs_dir2_data.c
+++ b/fs/xfs/libxfs/xfs_dir2_data.c
@@ -71,7 +71,7 @@ __xfs_dir3_data_check(
 		return __this_address;
 
 	hdr = bp->b_addr;
-	p = (char *)ops->data_entry_p(hdr);
+	p = (char *)hdr + ops->data_entry_offset;
 
 	switch (hdr->magic) {
 	case cpu_to_be32(XFS_DIR3_BLOCK_MAGIC):
@@ -587,7 +587,7 @@ xfs_dir2_data_freescan_int(
 	/*
 	 * Set up pointers.
 	 */
-	p = (char *)ops->data_entry_p(hdr);
+	p = (char *)hdr + ops->data_entry_offset;
 	endp = xfs_dir3_data_endp(geo, hdr);
 	/*
 	 * Loop over the block's entries.
@@ -685,7 +685,7 @@ xfs_dir3_data_init(
 	/*
 	 * Set up an unused entry for the block's body.
 	 */
-	dup = dp->d_ops->data_unused_p(hdr);
+	dup = (void *)hdr + dp->d_ops->data_entry_offset;
 	dup->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG);
 
 	t = args->geo->blksize - (uint)dp->d_ops->data_entry_offset;
diff --git a/fs/xfs/libxfs/xfs_dir2_sf.c b/fs/xfs/libxfs/xfs_dir2_sf.c
index 10199261c94c..b2c6c492b09d 100644
--- a/fs/xfs/libxfs/xfs_dir2_sf.c
+++ b/fs/xfs/libxfs/xfs_dir2_sf.c
@@ -296,7 +296,7 @@ xfs_dir2_block_to_sf(
 	/*
 	 * Set up to loop over the block's entries.
 	 */
-	ptr = (char *)dp->d_ops->data_entry_p(hdr);
+	ptr = (char *)hdr + dp->d_ops->data_entry_offset;
 	endptr = xfs_dir3_data_endp(args->geo, hdr);
 	sfep = xfs_dir2_sf_firstentry(sfp);
 	/*
diff --git a/fs/xfs/scrub/dir.c b/fs/xfs/scrub/dir.c
index dfaa0fca617e..8d6ecfe09611 100644
--- a/fs/xfs/scrub/dir.c
+++ b/fs/xfs/scrub/dir.c
@@ -241,7 +241,7 @@ xchk_dir_rec(
 	dent = (struct xfs_dir2_data_entry *)(((char *)bp->b_addr) + off);
 
 	/* Make sure we got a real directory entry. */
-	p = (char *)mp->m_dir_inode_ops->data_entry_p(bp->b_addr);
+	p = bp->b_addr + mp->m_dir_inode_ops->data_entry_offset;
 	endp = xfs_dir3_data_endp(mp->m_dir_geo, bp->b_addr);
 	if (!endp) {
 		xchk_fblock_set_corrupt(ds->sc, XFS_DATA_FORK, rec_bno);
@@ -391,7 +391,7 @@ xchk_directory_data_bestfree(
 	}
 
 	/* Make sure the bestfrees are actually the best free spaces. */
-	ptr = (char *)d_ops->data_entry_p(bp->b_addr);
+	ptr = bp->b_addr + d_ops->data_entry_offset;
 	endptr = xfs_dir3_data_endp(mp->m_dir_geo, bp->b_addr);
 
 	/* Iterate the entries, stopping when we hit or go past the end. */
diff --git a/fs/xfs/xfs_dir2_readdir.c b/fs/xfs/xfs_dir2_readdir.c
index e18045465455..04f8c2451b93 100644
--- a/fs/xfs/xfs_dir2_readdir.c
+++ b/fs/xfs/xfs_dir2_readdir.c
@@ -176,7 +176,7 @@ xfs_dir2_block_getdents(
 	/*
 	 * Set up values for the loop.
 	 */
-	ptr = (char *)dp->d_ops->data_entry_p(hdr);
+	ptr = (char *)hdr + dp->d_ops->data_entry_offset;
 	endptr = xfs_dir3_data_endp(geo, hdr);
 
 	/*
@@ -410,7 +410,7 @@ xfs_dir2_leaf_getdents(
 			/*
 			 * Find our position in the block.
 			 */
-			ptr = (char *)dp->d_ops->data_entry_p(hdr);
+			ptr = (char *)hdr + dp->d_ops->data_entry_offset;
 			byteoff = xfs_dir2_byte_to_off(geo, curoff);
 			/*
 			 * Skip past the header.
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 26/34] xfs: devirtualize ->data_entsize
  2019-11-01 22:06 remove m_dirops Christoph Hellwig
                   ` (24 preceding siblings ...)
  2019-11-01 22:07 ` [PATCH 25/34] xfs: remove the ->data_entry_entry_p method Christoph Hellwig
@ 2019-11-01 22:07 ` Christoph Hellwig
  2019-11-04 20:45   ` Darrick J. Wong
  2019-11-01 22:07 ` [PATCH 27/34] xfs: devirtualize ->data_entry_tag_p Christoph Hellwig
                   ` (7 subsequent siblings)
  33 siblings, 1 reply; 81+ messages in thread
From: Christoph Hellwig @ 2019-11-01 22:07 UTC (permalink / raw)
  To: linux-xfs

Replace the ->data_entsize dir ops method with a directly called
xfs_dir2_data_entsize helper that takes care of the differences between
the directory format with and without the file type field.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 fs/xfs/libxfs/xfs_da_format.c  | 22 ++++++++--------------
 fs/xfs/libxfs/xfs_dir2.h       |  3 +--
 fs/xfs/libxfs/xfs_dir2_block.c |  5 +++--
 fs/xfs/libxfs/xfs_dir2_data.c  | 13 ++++++-------
 fs/xfs/libxfs/xfs_dir2_leaf.c  |  5 +++--
 fs/xfs/libxfs/xfs_dir2_node.c  |  7 ++++---
 fs/xfs/libxfs/xfs_dir2_priv.h  |  2 ++
 fs/xfs/libxfs/xfs_dir2_sf.c    | 14 +++++++-------
 fs/xfs/scrub/dir.c             |  4 ++--
 fs/xfs/xfs_dir2_readdir.c      |  9 +++++----
 10 files changed, 41 insertions(+), 43 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c
index 47c56f6dd872..bbff0e7822b8 100644
--- a/fs/xfs/libxfs/xfs_da_format.c
+++ b/fs/xfs/libxfs/xfs_da_format.c
@@ -41,18 +41,15 @@
 		 sizeof(xfs_dir2_data_off_t) + sizeof(uint8_t)),	\
 		XFS_DIR2_DATA_ALIGN)
 
-static int
+int
 xfs_dir2_data_entsize(
+	struct xfs_mount	*mp,
 	int			n)
 {
-	return XFS_DIR2_DATA_ENTSIZE(n);
-}
-
-static int
-xfs_dir3_data_entsize(
-	int			n)
-{
-	return XFS_DIR3_DATA_ENTSIZE(n);
+	if (xfs_sb_version_hasftype(&mp->m_sb))
+		return XFS_DIR3_DATA_ENTSIZE(n);
+	else
+		return XFS_DIR2_DATA_ENTSIZE(n);
 }
 
 static uint8_t
@@ -100,7 +97,7 @@ xfs_dir2_data_entry_tag_p(
 	struct xfs_dir2_data_entry *dep)
 {
 	return (__be16 *)((char *)dep +
-		xfs_dir2_data_entsize(dep->namelen) - sizeof(__be16));
+		XFS_DIR2_DATA_ENTSIZE(dep->namelen) - sizeof(__be16));
 }
 
 static __be16 *
@@ -108,7 +105,7 @@ xfs_dir3_data_entry_tag_p(
 	struct xfs_dir2_data_entry *dep)
 {
 	return (__be16 *)((char *)dep +
-		xfs_dir3_data_entsize(dep->namelen) - sizeof(__be16));
+		XFS_DIR3_DATA_ENTSIZE(dep->namelen) - sizeof(__be16));
 }
 
 static struct xfs_dir2_data_free *
@@ -124,7 +121,6 @@ xfs_dir3_data_bestfree_p(struct xfs_dir2_data_hdr *hdr)
 }
 
 static const struct xfs_dir_ops xfs_dir2_ops = {
-	.data_entsize = xfs_dir2_data_entsize,
 	.data_get_ftype = xfs_dir2_data_get_ftype,
 	.data_put_ftype = xfs_dir2_data_put_ftype,
 	.data_entry_tag_p = xfs_dir2_data_entry_tag_p,
@@ -140,7 +136,6 @@ static const struct xfs_dir_ops xfs_dir2_ops = {
 };
 
 static const struct xfs_dir_ops xfs_dir2_ftype_ops = {
-	.data_entsize = xfs_dir3_data_entsize,
 	.data_get_ftype = xfs_dir3_data_get_ftype,
 	.data_put_ftype = xfs_dir3_data_put_ftype,
 	.data_entry_tag_p = xfs_dir3_data_entry_tag_p,
@@ -156,7 +151,6 @@ static const struct xfs_dir_ops xfs_dir2_ftype_ops = {
 };
 
 static const struct xfs_dir_ops xfs_dir3_ops = {
-	.data_entsize = xfs_dir3_data_entsize,
 	.data_get_ftype = xfs_dir3_data_get_ftype,
 	.data_put_ftype = xfs_dir3_data_put_ftype,
 	.data_entry_tag_p = xfs_dir3_data_entry_tag_p,
diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h
index e9de15e62630..3fb2c514437a 100644
--- a/fs/xfs/libxfs/xfs_dir2.h
+++ b/fs/xfs/libxfs/xfs_dir2.h
@@ -32,7 +32,6 @@ extern unsigned char xfs_mode_to_ftype(int mode);
  * directory operations vector for encode/decode routines
  */
 struct xfs_dir_ops {
-	int	(*data_entsize)(int len);
 	uint8_t (*data_get_ftype)(struct xfs_dir2_data_entry *dep);
 	void	(*data_put_ftype)(struct xfs_dir2_data_entry *dep,
 				uint8_t ftype);
@@ -87,7 +86,7 @@ extern int xfs_dir2_isleaf(struct xfs_da_args *args, int *r);
 extern int xfs_dir2_shrink_inode(struct xfs_da_args *args, xfs_dir2_db_t db,
 				struct xfs_buf *bp);
 
-extern void xfs_dir2_data_freescan_int(struct xfs_da_geometry *geo,
+extern void xfs_dir2_data_freescan_int(struct xfs_mount *mp,
 		const struct xfs_dir_ops *ops,
 		struct xfs_dir2_data_hdr *hdr, int *loghead);
 extern void xfs_dir2_data_freescan(struct xfs_inode *dp,
diff --git a/fs/xfs/libxfs/xfs_dir2_block.c b/fs/xfs/libxfs/xfs_dir2_block.c
index b32beb71b7b2..709423199369 100644
--- a/fs/xfs/libxfs/xfs_dir2_block.c
+++ b/fs/xfs/libxfs/xfs_dir2_block.c
@@ -355,7 +355,7 @@ xfs_dir2_block_addname(
 	if (error)
 		return error;
 
-	len = dp->d_ops->data_entsize(args->namelen);
+	len = xfs_dir2_data_entsize(dp->i_mount, args->namelen);
 
 	/*
 	 * Set up pointers to parts of the block.
@@ -791,7 +791,8 @@ xfs_dir2_block_removename(
 	needlog = needscan = 0;
 	xfs_dir2_data_make_free(args, bp,
 		(xfs_dir2_data_aoff_t)((char *)dep - (char *)hdr),
-		dp->d_ops->data_entsize(dep->namelen), &needlog, &needscan);
+		xfs_dir2_data_entsize(dp->i_mount, dep->namelen), &needlog,
+		&needscan);
 	/*
 	 * Fix up the block tail.
 	 */
diff --git a/fs/xfs/libxfs/xfs_dir2_data.c b/fs/xfs/libxfs/xfs_dir2_data.c
index edb3fe5c9174..7e3d35f0cdb5 100644
--- a/fs/xfs/libxfs/xfs_dir2_data.c
+++ b/fs/xfs/libxfs/xfs_dir2_data.c
@@ -173,7 +173,7 @@ __xfs_dir3_data_check(
 			return __this_address;
 		if (xfs_dir_ino_validate(mp, be64_to_cpu(dep->inumber)))
 			return __this_address;
-		if (endp < p + ops->data_entsize(dep->namelen))
+		if (endp < p + xfs_dir2_data_entsize(mp, dep->namelen))
 			return __this_address;
 		if (be16_to_cpu(*ops->data_entry_tag_p(dep)) !=
 		    (char *)dep - (char *)hdr)
@@ -198,7 +198,7 @@ __xfs_dir3_data_check(
 			if (i >= be32_to_cpu(btp->count))
 				return __this_address;
 		}
-		p += ops->data_entsize(dep->namelen);
+		p += xfs_dir2_data_entsize(mp, dep->namelen);
 	}
 	/*
 	 * Need to have seen all the entries and all the bestfree slots.
@@ -562,7 +562,7 @@ xfs_dir2_data_freeremove(
  */
 void
 xfs_dir2_data_freescan_int(
-	struct xfs_da_geometry	*geo,
+	struct xfs_mount	*mp,
 	const struct xfs_dir_ops *ops,
 	struct xfs_dir2_data_hdr *hdr,
 	int			*loghead)
@@ -588,7 +588,7 @@ xfs_dir2_data_freescan_int(
 	 * Set up pointers.
 	 */
 	p = (char *)hdr + ops->data_entry_offset;
-	endp = xfs_dir3_data_endp(geo, hdr);
+	endp = xfs_dir3_data_endp(mp->m_dir_geo, hdr);
 	/*
 	 * Loop over the block's entries.
 	 */
@@ -610,7 +610,7 @@ xfs_dir2_data_freescan_int(
 			dep = (xfs_dir2_data_entry_t *)p;
 			ASSERT((char *)dep - (char *)hdr ==
 			       be16_to_cpu(*ops->data_entry_tag_p(dep)));
-			p += ops->data_entsize(dep->namelen);
+			p += xfs_dir2_data_entsize(mp, dep->namelen);
 		}
 	}
 }
@@ -621,8 +621,7 @@ xfs_dir2_data_freescan(
 	struct xfs_dir2_data_hdr *hdr,
 	int			*loghead)
 {
-	return xfs_dir2_data_freescan_int(dp->i_mount->m_dir_geo, dp->d_ops,
-			hdr, loghead);
+	return xfs_dir2_data_freescan_int(dp->i_mount, dp->d_ops, hdr, loghead);
 }
 
 /*
diff --git a/fs/xfs/libxfs/xfs_dir2_leaf.c b/fs/xfs/libxfs/xfs_dir2_leaf.c
index 3770107c0695..2f7eda3008a6 100644
--- a/fs/xfs/libxfs/xfs_dir2_leaf.c
+++ b/fs/xfs/libxfs/xfs_dir2_leaf.c
@@ -660,7 +660,7 @@ xfs_dir2_leaf_addname(
 	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);
+	length = xfs_dir2_data_entsize(dp->i_mount, args->namelen);
 
 	/*
 	 * See if there are any entries with the same hash value
@@ -1395,7 +1395,8 @@ xfs_dir2_leaf_removename(
 	 */
 	xfs_dir2_data_make_free(args, dbp,
 		(xfs_dir2_data_aoff_t)((char *)dep - (char *)hdr),
-		dp->d_ops->data_entsize(dep->namelen), &needlog, &needscan);
+		xfs_dir2_data_entsize(dp->i_mount, dep->namelen), &needlog,
+		&needscan);
 	/*
 	 * We just mark the leaf entry stale by putting a null in it.
 	 */
diff --git a/fs/xfs/libxfs/xfs_dir2_node.c b/fs/xfs/libxfs/xfs_dir2_node.c
index ceb5936b58dd..d08a11121dee 100644
--- a/fs/xfs/libxfs/xfs_dir2_node.c
+++ b/fs/xfs/libxfs/xfs_dir2_node.c
@@ -662,7 +662,7 @@ xfs_dir2_leafn_lookup_for_addname(
 		ASSERT(free->hdr.magic == cpu_to_be32(XFS_DIR2_FREE_MAGIC) ||
 		       free->hdr.magic == cpu_to_be32(XFS_DIR3_FREE_MAGIC));
 	}
-	length = dp->d_ops->data_entsize(args->namelen);
+	length = xfs_dir2_data_entsize(mp, args->namelen);
 	/*
 	 * Loop over leaf entries with the right hash value.
 	 */
@@ -1314,7 +1314,8 @@ xfs_dir2_leafn_remove(
 	longest = be16_to_cpu(bf[0].length);
 	needlog = needscan = 0;
 	xfs_dir2_data_make_free(args, dbp, off,
-		dp->d_ops->data_entsize(dep->namelen), &needlog, &needscan);
+		xfs_dir2_data_entsize(dp->i_mount, dep->namelen), &needlog,
+		&needscan);
 	/*
 	 * Rescan the data block freespaces for bestfree.
 	 * Log the data block header if needed.
@@ -1907,7 +1908,7 @@ xfs_dir2_node_addname_int(
 	int			needscan = 0;	/* need to rescan data frees */
 	__be16			*tagp;		/* data entry tag pointer */
 
-	length = dp->d_ops->data_entsize(args->namelen);
+	length = xfs_dir2_data_entsize(dp->i_mount, args->namelen);
 	error = xfs_dir2_node_find_freeblk(args, fblk, &dbno, &fbp, &freehdr,
 					   &findex, length);
 	if (error)
diff --git a/fs/xfs/libxfs/xfs_dir2_priv.h b/fs/xfs/libxfs/xfs_dir2_priv.h
index a92d9f0f83e0..585b7b42c204 100644
--- a/fs/xfs/libxfs/xfs_dir2_priv.h
+++ b/fs/xfs/libxfs/xfs_dir2_priv.h
@@ -47,6 +47,8 @@ extern int xfs_dir2_leaf_to_block(struct xfs_da_args *args,
 		struct xfs_buf *lbp, struct xfs_buf *dbp);
 
 /* xfs_dir2_data.c */
+int xfs_dir2_data_entsize(struct xfs_mount *mp, int n);
+
 #ifdef DEBUG
 extern void xfs_dir3_data_check(struct xfs_inode *dp, struct xfs_buf *bp);
 #else
diff --git a/fs/xfs/libxfs/xfs_dir2_sf.c b/fs/xfs/libxfs/xfs_dir2_sf.c
index b2c6c492b09d..4885a0e920c5 100644
--- a/fs/xfs/libxfs/xfs_dir2_sf.c
+++ b/fs/xfs/libxfs/xfs_dir2_sf.c
@@ -341,7 +341,7 @@ xfs_dir2_block_to_sf(
 
 			sfep = xfs_dir2_sf_nextentry(mp, sfp, sfep);
 		}
-		ptr += dp->d_ops->data_entsize(dep->namelen);
+		ptr += xfs_dir2_data_entsize(mp, dep->namelen);
 	}
 	ASSERT((char *)sfep - (char *)sfp == size);
 
@@ -564,10 +564,10 @@ xfs_dir2_sf_addname_hard(
 	 */
 	for (offset = dp->d_ops->data_first_offset,
 	      oldsfep = xfs_dir2_sf_firstentry(oldsfp),
-	      add_datasize = dp->d_ops->data_entsize(args->namelen),
+	      add_datasize = xfs_dir2_data_entsize(mp, args->namelen),
 	      eof = (char *)oldsfep == &buf[old_isize];
 	     !eof;
-	     offset = new_offset + dp->d_ops->data_entsize(oldsfep->namelen),
+	     offset = new_offset + xfs_dir2_data_entsize(mp, oldsfep->namelen),
 	      oldsfep = xfs_dir2_sf_nextentry(mp, oldsfp, oldsfep),
 	      eof = (char *)oldsfep == &buf[old_isize]) {
 		new_offset = xfs_dir2_sf_get_offset(oldsfep);
@@ -639,7 +639,7 @@ xfs_dir2_sf_addname_pick(
 	int			used;		/* data bytes used */
 
 	sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data;
-	size = dp->d_ops->data_entsize(args->namelen);
+	size = xfs_dir2_data_entsize(mp, args->namelen);
 	offset = dp->d_ops->data_first_offset;
 	sfep = xfs_dir2_sf_firstentry(sfp);
 	holefit = 0;
@@ -652,7 +652,7 @@ xfs_dir2_sf_addname_pick(
 		if (!holefit)
 			holefit = offset + size <= xfs_dir2_sf_get_offset(sfep);
 		offset = xfs_dir2_sf_get_offset(sfep) +
-			 dp->d_ops->data_entsize(sfep->namelen);
+			 xfs_dir2_data_entsize(mp, sfep->namelen);
 		sfep = xfs_dir2_sf_nextentry(mp, sfp, sfep);
 	}
 	/*
@@ -717,7 +717,7 @@ xfs_dir2_sf_check(
 		i8count += ino > XFS_DIR2_MAX_SHORT_INUM;
 		offset =
 			xfs_dir2_sf_get_offset(sfep) +
-			dp->d_ops->data_entsize(sfep->namelen);
+			xfs_dir2_data_entsize(mp, sfep->namelen);
 		ASSERT(xfs_dir2_sf_get_ftype(mp, sfep) < XFS_DIR3_FT_MAX);
 	}
 	ASSERT(i8count == sfp->i8count);
@@ -817,7 +817,7 @@ xfs_dir2_sf_verify(
 			return __this_address;
 
 		offset = xfs_dir2_sf_get_offset(sfep) +
-				dops->data_entsize(sfep->namelen);
+				xfs_dir2_data_entsize(mp, sfep->namelen);
 
 		sfep = next_sfep;
 	}
diff --git a/fs/xfs/scrub/dir.c b/fs/xfs/scrub/dir.c
index 8d6ecfe09611..5ddd95f12b85 100644
--- a/fs/xfs/scrub/dir.c
+++ b/fs/xfs/scrub/dir.c
@@ -259,7 +259,7 @@ xchk_dir_rec(
 		dep = (struct xfs_dir2_data_entry *)p;
 		if (dep == dent)
 			break;
-		p += mp->m_dir_inode_ops->data_entsize(dep->namelen);
+		p += xfs_dir2_data_entsize(mp, dep->namelen);
 	}
 	if (p >= endp) {
 		xchk_fblock_set_corrupt(ds->sc, XFS_DATA_FORK, rec_bno);
@@ -402,7 +402,7 @@ xchk_directory_data_bestfree(
 			struct xfs_dir2_data_entry	*dep;
 
 			dep = (struct xfs_dir2_data_entry *)ptr;
-			newlen = d_ops->data_entsize(dep->namelen);
+			newlen = xfs_dir2_data_entsize(mp, dep->namelen);
 			if (newlen <= 0) {
 				xchk_fblock_set_corrupt(sc, XFS_DATA_FORK,
 						lblk);
diff --git a/fs/xfs/xfs_dir2_readdir.c b/fs/xfs/xfs_dir2_readdir.c
index 04f8c2451b93..4cc4102c85f0 100644
--- a/fs/xfs/xfs_dir2_readdir.c
+++ b/fs/xfs/xfs_dir2_readdir.c
@@ -200,7 +200,7 @@ xfs_dir2_block_getdents(
 		/*
 		 * Bump pointer for the next iteration.
 		 */
-		ptr += dp->d_ops->data_entsize(dep->namelen);
+		ptr += xfs_dir2_data_entsize(dp->i_mount, dep->namelen);
 		/*
 		 * The entry is before the desired starting point, skip it.
 		 */
@@ -355,6 +355,7 @@ xfs_dir2_leaf_getdents(
 	size_t			bufsize)
 {
 	struct xfs_inode	*dp = args->dp;
+	struct xfs_mount	*mp = dp->i_mount;
 	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 */
@@ -432,8 +433,8 @@ xfs_dir2_leaf_getdents(
 						continue;
 					}
 					dep = (xfs_dir2_data_entry_t *)ptr;
-					length =
-					   dp->d_ops->data_entsize(dep->namelen);
+					length = xfs_dir2_data_entsize(mp,
+							dep->namelen);
 					ptr += length;
 				}
 				/*
@@ -464,7 +465,7 @@ xfs_dir2_leaf_getdents(
 		}
 
 		dep = (xfs_dir2_data_entry_t *)ptr;
-		length = dp->d_ops->data_entsize(dep->namelen);
+		length = xfs_dir2_data_entsize(mp, dep->namelen);
 		filetype = dp->d_ops->data_get_ftype(dep);
 
 		ctx->pos = xfs_dir2_byte_to_dataptr(curoff) & 0x7fffffff;
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 27/34] xfs: devirtualize ->data_entry_tag_p
  2019-11-01 22:06 remove m_dirops Christoph Hellwig
                   ` (25 preceding siblings ...)
  2019-11-01 22:07 ` [PATCH 26/34] xfs: devirtualize ->data_entsize Christoph Hellwig
@ 2019-11-01 22:07 ` Christoph Hellwig
  2019-11-04 20:45   ` Darrick J. Wong
  2019-11-01 22:07 ` [PATCH 28/34] xfs: move the dir2 data block fixed offsets to struct xfs_da_geometry Christoph Hellwig
                   ` (6 subsequent siblings)
  33 siblings, 1 reply; 81+ messages in thread
From: Christoph Hellwig @ 2019-11-01 22:07 UTC (permalink / raw)
  To: linux-xfs

Replace the ->data_entry_tag_p dir ops method with a directly called
xfs_dir2_data_entry_tag_p helper that takes care of the differences
between the directory format with and without the file type field.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 fs/xfs/libxfs/xfs_da_format.c  | 22 ----------------------
 fs/xfs/libxfs/xfs_dir2.h       |  1 -
 fs/xfs/libxfs/xfs_dir2_block.c |  8 ++++----
 fs/xfs/libxfs/xfs_dir2_data.c  | 21 ++++++++++++++++++---
 fs/xfs/libxfs/xfs_dir2_leaf.c  |  2 +-
 fs/xfs/libxfs/xfs_dir2_node.c  |  2 +-
 fs/xfs/libxfs/xfs_dir2_priv.h  |  2 ++
 fs/xfs/scrub/dir.c             |  2 +-
 8 files changed, 27 insertions(+), 33 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c
index bbff0e7822b8..9c247223326f 100644
--- a/fs/xfs/libxfs/xfs_da_format.c
+++ b/fs/xfs/libxfs/xfs_da_format.c
@@ -89,25 +89,6 @@ xfs_dir3_data_put_ftype(
 	dep->name[dep->namelen] = type;
 }
 
-/*
- * Pointer to an entry's tag word.
- */
-static __be16 *
-xfs_dir2_data_entry_tag_p(
-	struct xfs_dir2_data_entry *dep)
-{
-	return (__be16 *)((char *)dep +
-		XFS_DIR2_DATA_ENTSIZE(dep->namelen) - sizeof(__be16));
-}
-
-static __be16 *
-xfs_dir3_data_entry_tag_p(
-	struct xfs_dir2_data_entry *dep)
-{
-	return (__be16 *)((char *)dep +
-		XFS_DIR3_DATA_ENTSIZE(dep->namelen) - sizeof(__be16));
-}
-
 static struct xfs_dir2_data_free *
 xfs_dir2_data_bestfree_p(struct xfs_dir2_data_hdr *hdr)
 {
@@ -123,7 +104,6 @@ xfs_dir3_data_bestfree_p(struct xfs_dir2_data_hdr *hdr)
 static const struct xfs_dir_ops xfs_dir2_ops = {
 	.data_get_ftype = xfs_dir2_data_get_ftype,
 	.data_put_ftype = xfs_dir2_data_put_ftype,
-	.data_entry_tag_p = xfs_dir2_data_entry_tag_p,
 	.data_bestfree_p = xfs_dir2_data_bestfree_p,
 
 	.data_dot_offset = sizeof(struct xfs_dir2_data_hdr),
@@ -138,7 +118,6 @@ static const struct xfs_dir_ops xfs_dir2_ops = {
 static const struct xfs_dir_ops xfs_dir2_ftype_ops = {
 	.data_get_ftype = xfs_dir3_data_get_ftype,
 	.data_put_ftype = xfs_dir3_data_put_ftype,
-	.data_entry_tag_p = xfs_dir3_data_entry_tag_p,
 	.data_bestfree_p = xfs_dir2_data_bestfree_p,
 
 	.data_dot_offset = sizeof(struct xfs_dir2_data_hdr),
@@ -153,7 +132,6 @@ static const struct xfs_dir_ops xfs_dir2_ftype_ops = {
 static const struct xfs_dir_ops xfs_dir3_ops = {
 	.data_get_ftype = xfs_dir3_data_get_ftype,
 	.data_put_ftype = xfs_dir3_data_put_ftype,
-	.data_entry_tag_p = xfs_dir3_data_entry_tag_p,
 	.data_bestfree_p = xfs_dir3_data_bestfree_p,
 
 	.data_dot_offset = sizeof(struct xfs_dir3_data_hdr),
diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h
index 3fb2c514437a..8397e35d6b82 100644
--- a/fs/xfs/libxfs/xfs_dir2.h
+++ b/fs/xfs/libxfs/xfs_dir2.h
@@ -35,7 +35,6 @@ struct xfs_dir_ops {
 	uint8_t (*data_get_ftype)(struct xfs_dir2_data_entry *dep);
 	void	(*data_put_ftype)(struct xfs_dir2_data_entry *dep,
 				uint8_t ftype);
-	__be16 * (*data_entry_tag_p)(struct xfs_dir2_data_entry *dep);
 	struct xfs_dir2_data_free *
 		(*data_bestfree_p)(struct xfs_dir2_data_hdr *hdr);
 
diff --git a/fs/xfs/libxfs/xfs_dir2_block.c b/fs/xfs/libxfs/xfs_dir2_block.c
index 709423199369..4230ea945bc4 100644
--- a/fs/xfs/libxfs/xfs_dir2_block.c
+++ b/fs/xfs/libxfs/xfs_dir2_block.c
@@ -542,7 +542,7 @@ xfs_dir2_block_addname(
 	dep->namelen = args->namelen;
 	memcpy(dep->name, args->name, args->namelen);
 	dp->d_ops->data_put_ftype(dep, args->filetype);
-	tagp = dp->d_ops->data_entry_tag_p(dep);
+	tagp = xfs_dir2_data_entry_tag_p(dp->i_mount, dep);
 	*tagp = cpu_to_be16((char *)dep - (char *)hdr);
 	/*
 	 * Clean up the bestfree array and log the header, tail, and entry.
@@ -1154,7 +1154,7 @@ xfs_dir2_sf_to_block(
 	dep->namelen = 1;
 	dep->name[0] = '.';
 	dp->d_ops->data_put_ftype(dep, XFS_DIR3_FT_DIR);
-	tagp = dp->d_ops->data_entry_tag_p(dep);
+	tagp = xfs_dir2_data_entry_tag_p(mp, dep);
 	*tagp = cpu_to_be16((char *)dep - (char *)hdr);
 	xfs_dir2_data_log_entry(args, bp, dep);
 	blp[0].hashval = cpu_to_be32(xfs_dir_hash_dot);
@@ -1168,7 +1168,7 @@ xfs_dir2_sf_to_block(
 	dep->namelen = 2;
 	dep->name[0] = dep->name[1] = '.';
 	dp->d_ops->data_put_ftype(dep, XFS_DIR3_FT_DIR);
-	tagp = dp->d_ops->data_entry_tag_p(dep);
+	tagp = xfs_dir2_data_entry_tag_p(mp, dep);
 	*tagp = cpu_to_be16((char *)dep - (char *)hdr);
 	xfs_dir2_data_log_entry(args, bp, dep);
 	blp[1].hashval = cpu_to_be32(xfs_dir_hash_dotdot);
@@ -1219,7 +1219,7 @@ xfs_dir2_sf_to_block(
 		dep->namelen = sfep->namelen;
 		dp->d_ops->data_put_ftype(dep, xfs_dir2_sf_get_ftype(mp, sfep));
 		memcpy(dep->name, sfep->name, dep->namelen);
-		tagp = dp->d_ops->data_entry_tag_p(dep);
+		tagp = xfs_dir2_data_entry_tag_p(mp, dep);
 		*tagp = cpu_to_be16((char *)dep - (char *)hdr);
 		xfs_dir2_data_log_entry(args, bp, dep);
 		name.name = sfep->name;
diff --git a/fs/xfs/libxfs/xfs_dir2_data.c b/fs/xfs/libxfs/xfs_dir2_data.c
index 7e3d35f0cdb5..750e95997d8c 100644
--- a/fs/xfs/libxfs/xfs_dir2_data.c
+++ b/fs/xfs/libxfs/xfs_dir2_data.c
@@ -17,12 +17,25 @@
 #include "xfs_trans.h"
 #include "xfs_buf_item.h"
 #include "xfs_log.h"
+#include "xfs_dir2_priv.h"
 
 static xfs_failaddr_t xfs_dir2_data_freefind_verify(
 		struct xfs_dir2_data_hdr *hdr, struct xfs_dir2_data_free *bf,
 		struct xfs_dir2_data_unused *dup,
 		struct xfs_dir2_data_free **bf_ent);
 
+/*
+ * Pointer to an entry's tag word.
+ */
+__be16 *
+xfs_dir2_data_entry_tag_p(
+	struct xfs_mount		*mp,
+	struct xfs_dir2_data_entry	*dep)
+{
+	return (__be16 *)((char *)dep +
+		xfs_dir2_data_entsize(mp, dep->namelen) - sizeof(__be16));
+}
+
 /*
  * Check the consistency of the data block.
  * The input can also be a block-format directory.
@@ -175,7 +188,7 @@ __xfs_dir3_data_check(
 			return __this_address;
 		if (endp < p + xfs_dir2_data_entsize(mp, dep->namelen))
 			return __this_address;
-		if (be16_to_cpu(*ops->data_entry_tag_p(dep)) !=
+		if (be16_to_cpu(*xfs_dir2_data_entry_tag_p(mp, dep)) !=
 		    (char *)dep - (char *)hdr)
 			return __this_address;
 		if (ops->data_get_ftype(dep) >= XFS_DIR3_FT_MAX)
@@ -609,7 +622,8 @@ xfs_dir2_data_freescan_int(
 		else {
 			dep = (xfs_dir2_data_entry_t *)p;
 			ASSERT((char *)dep - (char *)hdr ==
-			       be16_to_cpu(*ops->data_entry_tag_p(dep)));
+			       be16_to_cpu(*xfs_dir2_data_entry_tag_p(mp,
+					   dep)));
 			p += xfs_dir2_data_entsize(mp, dep->namelen);
 		}
 	}
@@ -709,6 +723,7 @@ xfs_dir2_data_log_entry(
 	struct xfs_buf		*bp,
 	xfs_dir2_data_entry_t	*dep)		/* data entry pointer */
 {
+	struct xfs_mount	*mp = bp->b_mount;
 	struct xfs_dir2_data_hdr *hdr = bp->b_addr;
 
 	ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) ||
@@ -717,7 +732,7 @@ xfs_dir2_data_log_entry(
 	       hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC));
 
 	xfs_trans_log_buf(args->trans, bp, (uint)((char *)dep - (char *)hdr),
-		(uint)((char *)(args->dp->d_ops->data_entry_tag_p(dep) + 1) -
+		(uint)((char *)(xfs_dir2_data_entry_tag_p(mp, dep) + 1) -
 		       (char *)hdr - 1));
 }
 
diff --git a/fs/xfs/libxfs/xfs_dir2_leaf.c b/fs/xfs/libxfs/xfs_dir2_leaf.c
index 2f7eda3008a6..3a65b7c8aa83 100644
--- a/fs/xfs/libxfs/xfs_dir2_leaf.c
+++ b/fs/xfs/libxfs/xfs_dir2_leaf.c
@@ -866,7 +866,7 @@ xfs_dir2_leaf_addname(
 	dep->namelen = args->namelen;
 	memcpy(dep->name, args->name, dep->namelen);
 	dp->d_ops->data_put_ftype(dep, args->filetype);
-	tagp = dp->d_ops->data_entry_tag_p(dep);
+	tagp = xfs_dir2_data_entry_tag_p(dp->i_mount, dep);
 	*tagp = cpu_to_be16((char *)dep - (char *)hdr);
 	/*
 	 * Need to scan fix up the bestfree table.
diff --git a/fs/xfs/libxfs/xfs_dir2_node.c b/fs/xfs/libxfs/xfs_dir2_node.c
index d08a11121dee..7534e35d8aa2 100644
--- a/fs/xfs/libxfs/xfs_dir2_node.c
+++ b/fs/xfs/libxfs/xfs_dir2_node.c
@@ -1966,7 +1966,7 @@ xfs_dir2_node_addname_int(
 	dep->namelen = args->namelen;
 	memcpy(dep->name, args->name, dep->namelen);
 	dp->d_ops->data_put_ftype(dep, args->filetype);
-	tagp = dp->d_ops->data_entry_tag_p(dep);
+	tagp = xfs_dir2_data_entry_tag_p(dp->i_mount, dep);
 	*tagp = cpu_to_be16((char *)dep - (char *)hdr);
 	xfs_dir2_data_log_entry(args, dbp, dep);
 
diff --git a/fs/xfs/libxfs/xfs_dir2_priv.h b/fs/xfs/libxfs/xfs_dir2_priv.h
index 585b7b42c204..750344407f27 100644
--- a/fs/xfs/libxfs/xfs_dir2_priv.h
+++ b/fs/xfs/libxfs/xfs_dir2_priv.h
@@ -48,6 +48,8 @@ extern int xfs_dir2_leaf_to_block(struct xfs_da_args *args,
 
 /* xfs_dir2_data.c */
 int xfs_dir2_data_entsize(struct xfs_mount *mp, int n);
+__be16 *xfs_dir2_data_entry_tag_p(struct xfs_mount *mp,
+		struct xfs_dir2_data_entry *dep);
 
 #ifdef DEBUG
 extern void xfs_dir3_data_check(struct xfs_inode *dp, struct xfs_buf *bp);
diff --git a/fs/xfs/scrub/dir.c b/fs/xfs/scrub/dir.c
index 5ddd95f12b85..d7ac9423ed86 100644
--- a/fs/xfs/scrub/dir.c
+++ b/fs/xfs/scrub/dir.c
@@ -269,7 +269,7 @@ xchk_dir_rec(
 	/* Retrieve the entry, sanity check it, and compare hashes. */
 	ino = be64_to_cpu(dent->inumber);
 	hash = be32_to_cpu(ent->hashval);
-	tag = be16_to_cpup(dp->d_ops->data_entry_tag_p(dent));
+	tag = be16_to_cpup(xfs_dir2_data_entry_tag_p(mp, dent));
 	if (!xfs_verify_dir_ino(mp, ino) || tag != off)
 		xchk_fblock_set_corrupt(ds->sc, XFS_DATA_FORK, rec_bno);
 	if (dent->namelen == 0) {
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 28/34] xfs: move the dir2 data block fixed offsets to struct xfs_da_geometry
  2019-11-01 22:06 remove m_dirops Christoph Hellwig
                   ` (26 preceding siblings ...)
  2019-11-01 22:07 ` [PATCH 27/34] xfs: devirtualize ->data_entry_tag_p Christoph Hellwig
@ 2019-11-01 22:07 ` Christoph Hellwig
  2019-11-04 20:46   ` Darrick J. Wong
  2019-11-01 22:07 ` [PATCH 29/34] xfs: cleanup xfs_dir2_data_entsize Christoph Hellwig
                   ` (5 subsequent siblings)
  33 siblings, 1 reply; 81+ messages in thread
From: Christoph Hellwig @ 2019-11-01 22:07 UTC (permalink / raw)
  To: linux-xfs

Move the data block fixed offsets towards our structure for dir/attr
geometry parameters.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 fs/xfs/libxfs/xfs_da_btree.h   |  5 +++++
 fs/xfs/libxfs/xfs_da_format.c  | 24 ------------------------
 fs/xfs/libxfs/xfs_dir2.c       |  9 +++++++++
 fs/xfs/libxfs/xfs_dir2.h       |  5 -----
 fs/xfs/libxfs/xfs_dir2_block.c | 11 ++++++-----
 fs/xfs/libxfs/xfs_dir2_data.c  | 18 +++++++++---------
 fs/xfs/libxfs/xfs_dir2_leaf.c  | 22 ++++++++++++----------
 fs/xfs/libxfs/xfs_dir2_node.c  | 24 +++++++++++-------------
 fs/xfs/libxfs/xfs_dir2_sf.c    | 16 +++++-----------
 fs/xfs/scrub/dir.c             |  4 ++--
 fs/xfs/xfs_dir2_readdir.c      | 13 +++++--------
 11 files changed, 64 insertions(+), 87 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_da_btree.h b/fs/xfs/libxfs/xfs_da_btree.h
index e3f4329ab882..a3333e7a084d 100644
--- a/fs/xfs/libxfs/xfs_da_btree.h
+++ b/fs/xfs/libxfs/xfs_da_btree.h
@@ -32,6 +32,11 @@ struct xfs_da_geometry {
 	int		free_hdr_size;	/* dir2 free header size */
 	unsigned int	free_max_bests;	/* # of bests entries in dir2 free */
 	xfs_dablk_t	freeblk;	/* blockno of free data v2 */
+
+	xfs_dir2_data_aoff_t data_dot_offset;
+	xfs_dir2_data_aoff_t data_dotdot_offset;
+	xfs_dir2_data_aoff_t data_first_offset;
+	size_t		data_entry_offset;
 };
 
 /*========================================================================
diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c
index 9c247223326f..0e35e613fbf3 100644
--- a/fs/xfs/libxfs/xfs_da_format.c
+++ b/fs/xfs/libxfs/xfs_da_format.c
@@ -105,42 +105,18 @@ static const struct xfs_dir_ops xfs_dir2_ops = {
 	.data_get_ftype = xfs_dir2_data_get_ftype,
 	.data_put_ftype = xfs_dir2_data_put_ftype,
 	.data_bestfree_p = xfs_dir2_data_bestfree_p,
-
-	.data_dot_offset = sizeof(struct xfs_dir2_data_hdr),
-	.data_dotdot_offset = sizeof(struct xfs_dir2_data_hdr) +
-				XFS_DIR2_DATA_ENTSIZE(1),
-	.data_first_offset =  sizeof(struct xfs_dir2_data_hdr) +
-				XFS_DIR2_DATA_ENTSIZE(1) +
-				XFS_DIR2_DATA_ENTSIZE(2),
-	.data_entry_offset = sizeof(struct xfs_dir2_data_hdr),
 };
 
 static const struct xfs_dir_ops xfs_dir2_ftype_ops = {
 	.data_get_ftype = xfs_dir3_data_get_ftype,
 	.data_put_ftype = xfs_dir3_data_put_ftype,
 	.data_bestfree_p = xfs_dir2_data_bestfree_p,
-
-	.data_dot_offset = sizeof(struct xfs_dir2_data_hdr),
-	.data_dotdot_offset = sizeof(struct xfs_dir2_data_hdr) +
-				XFS_DIR3_DATA_ENTSIZE(1),
-	.data_first_offset =  sizeof(struct xfs_dir2_data_hdr) +
-				XFS_DIR3_DATA_ENTSIZE(1) +
-				XFS_DIR3_DATA_ENTSIZE(2),
-	.data_entry_offset = sizeof(struct xfs_dir2_data_hdr),
 };
 
 static const struct xfs_dir_ops xfs_dir3_ops = {
 	.data_get_ftype = xfs_dir3_data_get_ftype,
 	.data_put_ftype = xfs_dir3_data_put_ftype,
 	.data_bestfree_p = xfs_dir3_data_bestfree_p,
-
-	.data_dot_offset = sizeof(struct xfs_dir3_data_hdr),
-	.data_dotdot_offset = sizeof(struct xfs_dir3_data_hdr) +
-				XFS_DIR3_DATA_ENTSIZE(1),
-	.data_first_offset =  sizeof(struct xfs_dir3_data_hdr) +
-				XFS_DIR3_DATA_ENTSIZE(1) +
-				XFS_DIR3_DATA_ENTSIZE(2),
-	.data_entry_offset = sizeof(struct xfs_dir3_data_hdr),
 };
 
 /*
diff --git a/fs/xfs/libxfs/xfs_dir2.c b/fs/xfs/libxfs/xfs_dir2.c
index 6c46893af17e..33a6e8aacdba 100644
--- a/fs/xfs/libxfs/xfs_dir2.c
+++ b/fs/xfs/libxfs/xfs_dir2.c
@@ -126,16 +126,25 @@ xfs_da_mount(
 		dageo->node_hdr_size = sizeof(struct xfs_da3_node_hdr);
 		dageo->leaf_hdr_size = sizeof(struct xfs_dir3_leaf_hdr);
 		dageo->free_hdr_size = sizeof(struct xfs_dir3_free_hdr);
+		dageo->data_entry_offset = dageo->data_dot_offset =
+				sizeof(struct xfs_dir3_data_hdr);
 	} else {
 		dageo->node_hdr_size = sizeof(struct xfs_da_node_hdr);
 		dageo->leaf_hdr_size = sizeof(struct xfs_dir2_leaf_hdr);
 		dageo->free_hdr_size = sizeof(struct xfs_dir2_free_hdr);
+		dageo->data_entry_offset = dageo->data_dot_offset =
+				sizeof(struct xfs_dir2_data_hdr);
 	}
 	dageo->leaf_max_ents = (dageo->blksize - dageo->leaf_hdr_size) /
 			sizeof(struct xfs_dir2_leaf_entry);
 	dageo->free_max_bests = (dageo->blksize - dageo->free_hdr_size) /
 			sizeof(xfs_dir2_data_off_t);
 
+	dageo->data_dotdot_offset = dageo->data_dot_offset +
+			xfs_dir2_data_entsize(mp, 1);
+	dageo->data_first_offset = dageo->data_dotdot_offset +
+			xfs_dir2_data_entsize(mp, 2);
+
 	/*
 	 * Now we've set up the block conversion variables, we can calculate the
 	 * segment block constants using the geometry structure.
diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h
index 8397e35d6b82..11dba3874da0 100644
--- a/fs/xfs/libxfs/xfs_dir2.h
+++ b/fs/xfs/libxfs/xfs_dir2.h
@@ -37,11 +37,6 @@ struct xfs_dir_ops {
 				uint8_t ftype);
 	struct xfs_dir2_data_free *
 		(*data_bestfree_p)(struct xfs_dir2_data_hdr *hdr);
-
-	xfs_dir2_data_aoff_t data_dot_offset;
-	xfs_dir2_data_aoff_t data_dotdot_offset;
-	xfs_dir2_data_aoff_t data_first_offset;
-	size_t	data_entry_offset;
 };
 
 extern const struct xfs_dir_ops *
diff --git a/fs/xfs/libxfs/xfs_dir2_block.c b/fs/xfs/libxfs/xfs_dir2_block.c
index 4230ea945bc4..d5f4b7187b72 100644
--- a/fs/xfs/libxfs/xfs_dir2_block.c
+++ b/fs/xfs/libxfs/xfs_dir2_block.c
@@ -937,7 +937,7 @@ xfs_dir2_leaf_to_block(
 	while (dp->i_d.di_size > args->geo->blksize) {
 		int hdrsz;
 
-		hdrsz = dp->d_ops->data_entry_offset;
+		hdrsz = args->geo->data_entry_offset;
 		bestsp = xfs_dir2_leaf_bests_p(ltp);
 		if (be16_to_cpu(bestsp[be32_to_cpu(ltp->bestcount) - 1]) ==
 					    args->geo->blksize - hdrsz) {
@@ -1041,6 +1041,7 @@ int						/* error */
 xfs_dir2_sf_to_block(
 	xfs_da_args_t		*args)		/* operation arguments */
 {
+	struct xfs_da_geometry	*geo = args->geo;
 	xfs_dir2_db_t		blkno;		/* dir-relative block # (0) */
 	xfs_dir2_data_hdr_t	*hdr;		/* block header */
 	xfs_dir2_leaf_entry_t	*blp;		/* block leaf entries */
@@ -1123,7 +1124,7 @@ xfs_dir2_sf_to_block(
 	 * The whole thing is initialized to free by the init routine.
 	 * Say we're using the leaf and tail area.
 	 */
-	dup = (void *)hdr + dp->d_ops->data_entry_offset;
+	dup = (void *)hdr + args->geo->data_entry_offset;
 	needlog = needscan = 0;
 	error = xfs_dir2_data_use_free(args, bp, dup, args->geo->blksize - i,
 			i, &needlog, &needscan);
@@ -1149,7 +1150,7 @@ xfs_dir2_sf_to_block(
 	/*
 	 * Create entry for .
 	 */
-	dep = (void *)hdr + dp->d_ops->data_dot_offset;
+	dep = (void *)hdr + geo->data_dot_offset;
 	dep->inumber = cpu_to_be64(dp->i_ino);
 	dep->namelen = 1;
 	dep->name[0] = '.';
@@ -1163,7 +1164,7 @@ xfs_dir2_sf_to_block(
 	/*
 	 * Create entry for ..
 	 */
-	dep = (void *)hdr + dp->d_ops->data_dotdot_offset;
+	dep = (void *)hdr + geo->data_dotdot_offset;
 	dep->inumber = cpu_to_be64(xfs_dir2_sf_get_parent_ino(sfp));
 	dep->namelen = 2;
 	dep->name[0] = dep->name[1] = '.';
@@ -1174,7 +1175,7 @@ xfs_dir2_sf_to_block(
 	blp[1].hashval = cpu_to_be32(xfs_dir_hash_dotdot);
 	blp[1].address = cpu_to_be32(xfs_dir2_byte_to_dataptr(
 				(char *)dep - (char *)hdr));
-	offset = dp->d_ops->data_first_offset;
+	offset = geo->data_first_offset;
 	/*
 	 * Loop over existing entries, stuff them in.
 	 */
diff --git a/fs/xfs/libxfs/xfs_dir2_data.c b/fs/xfs/libxfs/xfs_dir2_data.c
index 750e95997d8c..81ba13854f8d 100644
--- a/fs/xfs/libxfs/xfs_dir2_data.c
+++ b/fs/xfs/libxfs/xfs_dir2_data.c
@@ -84,7 +84,7 @@ __xfs_dir3_data_check(
 		return __this_address;
 
 	hdr = bp->b_addr;
-	p = (char *)hdr + ops->data_entry_offset;
+	p = (char *)hdr + geo->data_entry_offset;
 
 	switch (hdr->magic) {
 	case cpu_to_be32(XFS_DIR3_BLOCK_MAGIC):
@@ -580,6 +580,7 @@ xfs_dir2_data_freescan_int(
 	struct xfs_dir2_data_hdr *hdr,
 	int			*loghead)
 {
+	struct xfs_da_geometry	*geo = mp->m_dir_geo;
 	xfs_dir2_data_entry_t	*dep;		/* active data entry */
 	xfs_dir2_data_unused_t	*dup;		/* unused data entry */
 	struct xfs_dir2_data_free *bf;
@@ -600,8 +601,8 @@ xfs_dir2_data_freescan_int(
 	/*
 	 * Set up pointers.
 	 */
-	p = (char *)hdr + ops->data_entry_offset;
-	endp = xfs_dir3_data_endp(mp->m_dir_geo, hdr);
+	p = (char *)hdr + geo->data_entry_offset;
+	endp = xfs_dir3_data_endp(geo, hdr);
 	/*
 	 * Loop over the block's entries.
 	 */
@@ -689,7 +690,7 @@ xfs_dir3_data_init(
 		hdr->magic = cpu_to_be32(XFS_DIR2_DATA_MAGIC);
 
 	bf = dp->d_ops->data_bestfree_p(hdr);
-	bf[0].offset = cpu_to_be16(dp->d_ops->data_entry_offset);
+	bf[0].offset = cpu_to_be16(args->geo->data_entry_offset);
 	for (i = 1; i < XFS_DIR2_DATA_FD_COUNT; i++) {
 		bf[i].length = 0;
 		bf[i].offset = 0;
@@ -698,10 +699,10 @@ xfs_dir3_data_init(
 	/*
 	 * Set up an unused entry for the block's body.
 	 */
-	dup = (void *)hdr + dp->d_ops->data_entry_offset;
+	dup = (void *)hdr + args->geo->data_entry_offset;
 	dup->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG);
 
-	t = args->geo->blksize - (uint)dp->d_ops->data_entry_offset;
+	t = args->geo->blksize - args->geo->data_entry_offset;
 	bf[0].length = cpu_to_be16(t);
 	dup->length = cpu_to_be16(t);
 	*xfs_dir2_data_unused_tag_p(dup) = cpu_to_be16((char *)dup - (char *)hdr);
@@ -753,8 +754,7 @@ xfs_dir2_data_log_header(
 	       hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC));
 #endif
 
-	xfs_trans_log_buf(args->trans, bp, 0,
-			  args->dp->d_ops->data_entry_offset - 1);
+	xfs_trans_log_buf(args->trans, bp, 0, args->geo->data_entry_offset - 1);
 }
 
 /*
@@ -822,7 +822,7 @@ xfs_dir2_data_make_free(
 	 * If this isn't the start of the block, then back up to
 	 * the previous entry and see if it's free.
 	 */
-	if (offset > args->dp->d_ops->data_entry_offset) {
+	if (offset > args->geo->data_entry_offset) {
 		__be16			*tagp;	/* tag just before us */
 
 		tagp = (__be16 *)((char *)hdr + offset) - 1;
diff --git a/fs/xfs/libxfs/xfs_dir2_leaf.c b/fs/xfs/libxfs/xfs_dir2_leaf.c
index 3a65b7c8aa83..c228ff66b3f0 100644
--- a/fs/xfs/libxfs/xfs_dir2_leaf.c
+++ b/fs/xfs/libxfs/xfs_dir2_leaf.c
@@ -1343,6 +1343,7 @@ int						/* error */
 xfs_dir2_leaf_removename(
 	xfs_da_args_t		*args)		/* operation arguments */
 {
+	struct xfs_da_geometry	*geo = args->geo;
 	__be16			*bestsp;	/* leaf block best freespace */
 	xfs_dir2_data_hdr_t	*hdr;		/* data block header */
 	xfs_dir2_db_t		db;		/* data block number */
@@ -1381,12 +1382,12 @@ xfs_dir2_leaf_removename(
 	 * Point to the leaf entry, use that to point to the data entry.
 	 */
 	lep = &leafhdr.ents[index];
-	db = xfs_dir2_dataptr_to_db(args->geo, be32_to_cpu(lep->address));
+	db = xfs_dir2_dataptr_to_db(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)));
+		xfs_dir2_dataptr_to_off(geo, be32_to_cpu(lep->address)));
 	needscan = needlog = 0;
 	oldbest = be16_to_cpu(bf[0].length);
-	ltp = xfs_dir2_leaf_tail_p(args->geo, leaf);
+	ltp = xfs_dir2_leaf_tail_p(geo, leaf);
 	bestsp = xfs_dir2_leaf_bests_p(ltp);
 	if (be16_to_cpu(bestsp[db]) != oldbest)
 		return -EFSCORRUPTED;
@@ -1428,8 +1429,8 @@ xfs_dir2_leaf_removename(
 	 * If the data block is now empty then get rid of the data block.
 	 */
 	if (be16_to_cpu(bf[0].length) ==
-			args->geo->blksize - dp->d_ops->data_entry_offset) {
-		ASSERT(db != args->geo->datablk);
+	    geo->blksize - geo->data_entry_offset) {
+		ASSERT(db != geo->datablk);
 		if ((error = xfs_dir2_shrink_inode(args, db, dbp))) {
 			/*
 			 * Nope, can't get rid of it because it caused
@@ -1471,7 +1472,7 @@ xfs_dir2_leaf_removename(
 	/*
 	 * If the data block was not the first one, drop it.
 	 */
-	else if (db != args->geo->datablk)
+	else if (db != geo->datablk)
 		dbp = NULL;
 
 	xfs_dir3_leaf_check(dp, lbp);
@@ -1592,6 +1593,7 @@ xfs_dir2_leaf_trim_data(
 	struct xfs_buf		*lbp,		/* leaf buffer */
 	xfs_dir2_db_t		db)		/* data block number */
 {
+	struct xfs_da_geometry	*geo = args->geo;
 	__be16			*bestsp;	/* leaf bests table */
 	struct xfs_buf		*dbp;		/* data block buffer */
 	xfs_inode_t		*dp;		/* incore directory inode */
@@ -1605,13 +1607,13 @@ xfs_dir2_leaf_trim_data(
 	/*
 	 * Read the offending data block.  We need its buffer.
 	 */
-	error = xfs_dir3_data_read(tp, dp, xfs_dir2_db_to_da(args->geo, db),
-				   -1, &dbp);
+	error = xfs_dir3_data_read(tp, dp, xfs_dir2_db_to_da(geo, db), -1,
+				   &dbp);
 	if (error)
 		return error;
 
 	leaf = lbp->b_addr;
-	ltp = xfs_dir2_leaf_tail_p(args->geo, leaf);
+	ltp = xfs_dir2_leaf_tail_p(geo, leaf);
 
 #ifdef DEBUG
 {
@@ -1621,7 +1623,7 @@ xfs_dir2_leaf_trim_data(
 	ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) ||
 	       hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC));
 	ASSERT(be16_to_cpu(bf[0].length) ==
-	       args->geo->blksize - dp->d_ops->data_entry_offset);
+	       geo->blksize - geo->data_entry_offset);
 	ASSERT(db == be32_to_cpu(ltp->bestcount) - 1);
 }
 #endif
diff --git a/fs/xfs/libxfs/xfs_dir2_node.c b/fs/xfs/libxfs/xfs_dir2_node.c
index 7534e35d8aa2..58362169aa57 100644
--- a/fs/xfs/libxfs/xfs_dir2_node.c
+++ b/fs/xfs/libxfs/xfs_dir2_node.c
@@ -1257,6 +1257,7 @@ xfs_dir2_leafn_remove(
 	xfs_da_state_blk_t	*dblk,		/* data block */
 	int			*rval)		/* resulting block needs join */
 {
+	struct xfs_da_geometry	*geo = args->geo;
 	xfs_dir2_data_hdr_t	*hdr;		/* data block header */
 	xfs_dir2_db_t		db;		/* data block number */
 	struct xfs_buf		*dbp;		/* data block buffer */
@@ -1287,9 +1288,9 @@ xfs_dir2_leafn_remove(
 	/*
 	 * Extract the data block and offset from the entry.
 	 */
-	db = xfs_dir2_dataptr_to_db(args->geo, be32_to_cpu(lep->address));
+	db = xfs_dir2_dataptr_to_db(geo, be32_to_cpu(lep->address));
 	ASSERT(dblk->blkno == db);
-	off = xfs_dir2_dataptr_to_off(args->geo, be32_to_cpu(lep->address));
+	off = xfs_dir2_dataptr_to_off(geo, be32_to_cpu(lep->address));
 	ASSERT(dblk->index == off);
 
 	/*
@@ -1340,9 +1341,8 @@ xfs_dir2_leafn_remove(
 		 * Convert the data block number to a free block,
 		 * read in the free block.
 		 */
-		fdb = xfs_dir2_db_to_fdb(args->geo, db);
-		error = xfs_dir2_free_read(tp, dp,
-					   xfs_dir2_db_to_da(args->geo, fdb),
+		fdb = xfs_dir2_db_to_fdb(geo, db);
+		error = xfs_dir2_free_read(tp, dp, xfs_dir2_db_to_da(geo, fdb),
 					   &fbp);
 		if (error)
 			return error;
@@ -1352,22 +1352,20 @@ xfs_dir2_leafn_remove(
 		struct xfs_dir3_icfree_hdr freehdr;
 
 		xfs_dir2_free_hdr_from_disk(dp->i_mount, &freehdr, free);
-		ASSERT(freehdr.firstdb == args->geo->free_max_bests *
-			(fdb - xfs_dir2_byte_to_db(args->geo,
-						   XFS_DIR2_FREE_OFFSET)));
+		ASSERT(freehdr.firstdb == geo->free_max_bests *
+			(fdb - xfs_dir2_byte_to_db(geo, XFS_DIR2_FREE_OFFSET)));
 	}
 #endif
 		/*
 		 * Calculate which entry we need to fix.
 		 */
-		findex = xfs_dir2_db_to_fdindex(args->geo, db);
+		findex = xfs_dir2_db_to_fdindex(geo, db);
 		longest = be16_to_cpu(bf[0].length);
 		/*
 		 * If the data block is now empty we can get rid of it
 		 * (usually).
 		 */
-		if (longest == args->geo->blksize -
-			       dp->d_ops->data_entry_offset) {
+		if (longest == geo->blksize - geo->data_entry_offset) {
 			/*
 			 * Try to punch out the data block.
 			 */
@@ -1399,9 +1397,9 @@ xfs_dir2_leafn_remove(
 	 * Return indication of whether this leaf block is empty enough
 	 * to justify trying to join it with a neighbor.
 	 */
-	*rval = (args->geo->leaf_hdr_size +
+	*rval = (geo->leaf_hdr_size +
 		 (uint)sizeof(leafhdr.ents) * (leafhdr.count - leafhdr.stale)) <
-		args->geo->magicpct;
+		geo->magicpct;
 	return 0;
 }
 
diff --git a/fs/xfs/libxfs/xfs_dir2_sf.c b/fs/xfs/libxfs/xfs_dir2_sf.c
index 4885a0e920c5..8ecbb0828e42 100644
--- a/fs/xfs/libxfs/xfs_dir2_sf.c
+++ b/fs/xfs/libxfs/xfs_dir2_sf.c
@@ -296,7 +296,7 @@ xfs_dir2_block_to_sf(
 	/*
 	 * Set up to loop over the block's entries.
 	 */
-	ptr = (char *)hdr + dp->d_ops->data_entry_offset;
+	ptr = (char *)hdr + args->geo->data_entry_offset;
 	endptr = xfs_dir3_data_endp(args->geo, hdr);
 	sfep = xfs_dir2_sf_firstentry(sfp);
 	/*
@@ -562,7 +562,7 @@ xfs_dir2_sf_addname_hard(
 	 * to insert the new entry.
 	 * If it's going to end up at the end then oldsfep will point there.
 	 */
-	for (offset = dp->d_ops->data_first_offset,
+	for (offset = args->geo->data_first_offset,
 	      oldsfep = xfs_dir2_sf_firstentry(oldsfp),
 	      add_datasize = xfs_dir2_data_entsize(mp, args->namelen),
 	      eof = (char *)oldsfep == &buf[old_isize];
@@ -640,7 +640,7 @@ xfs_dir2_sf_addname_pick(
 
 	sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data;
 	size = xfs_dir2_data_entsize(mp, args->namelen);
-	offset = dp->d_ops->data_first_offset;
+	offset = args->geo->data_first_offset;
 	sfep = xfs_dir2_sf_firstentry(sfp);
 	holefit = 0;
 	/*
@@ -705,7 +705,7 @@ xfs_dir2_sf_check(
 	xfs_dir2_sf_hdr_t	*sfp;		/* shortform structure */
 
 	sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data;
-	offset = dp->d_ops->data_first_offset;
+	offset = args->geo->data_first_offset;
 	ino = xfs_dir2_sf_get_parent_ino(sfp);
 	i8count = ino > XFS_DIR2_MAX_SHORT_INUM;
 
@@ -738,7 +738,6 @@ xfs_dir2_sf_verify(
 	struct xfs_dir2_sf_entry	*sfep;
 	struct xfs_dir2_sf_entry	*next_sfep;
 	char				*endp;
-	const struct xfs_dir_ops	*dops;
 	struct xfs_ifork		*ifp;
 	xfs_ino_t			ino;
 	int				i;
@@ -749,11 +748,6 @@ xfs_dir2_sf_verify(
 	uint8_t				filetype;
 
 	ASSERT(ip->i_d.di_format == XFS_DINODE_FMT_LOCAL);
-	/*
-	 * xfs_iread calls us before xfs_setup_inode sets up ip->d_ops,
-	 * so we can only trust the mountpoint to have the right pointer.
-	 */
-	dops = xfs_dir_get_ops(mp, NULL);
 
 	ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK);
 	sfp = (struct xfs_dir2_sf_hdr *)ifp->if_u1.if_data;
@@ -774,7 +768,7 @@ xfs_dir2_sf_verify(
 	error = xfs_dir_ino_validate(mp, ino);
 	if (error)
 		return __this_address;
-	offset = dops->data_first_offset;
+	offset = mp->m_dir_geo->data_first_offset;
 
 	/* Check all reported entries */
 	sfep = xfs_dir2_sf_firstentry(sfp);
diff --git a/fs/xfs/scrub/dir.c b/fs/xfs/scrub/dir.c
index d7ac9423ed86..d13c863d72a5 100644
--- a/fs/xfs/scrub/dir.c
+++ b/fs/xfs/scrub/dir.c
@@ -241,7 +241,7 @@ xchk_dir_rec(
 	dent = (struct xfs_dir2_data_entry *)(((char *)bp->b_addr) + off);
 
 	/* Make sure we got a real directory entry. */
-	p = bp->b_addr + mp->m_dir_inode_ops->data_entry_offset;
+	p = bp->b_addr + mp->m_dir_geo->data_entry_offset;
 	endp = xfs_dir3_data_endp(mp->m_dir_geo, bp->b_addr);
 	if (!endp) {
 		xchk_fblock_set_corrupt(ds->sc, XFS_DATA_FORK, rec_bno);
@@ -391,7 +391,7 @@ xchk_directory_data_bestfree(
 	}
 
 	/* Make sure the bestfrees are actually the best free spaces. */
-	ptr = bp->b_addr + d_ops->data_entry_offset;
+	ptr = bp->b_addr + mp->m_dir_geo->data_entry_offset;
 	endptr = xfs_dir3_data_endp(mp->m_dir_geo, bp->b_addr);
 
 	/* Iterate the entries, stopping when we hit or go past the end. */
diff --git a/fs/xfs/xfs_dir2_readdir.c b/fs/xfs/xfs_dir2_readdir.c
index 4cc4102c85f0..7519317d7a21 100644
--- a/fs/xfs/xfs_dir2_readdir.c
+++ b/fs/xfs/xfs_dir2_readdir.c
@@ -71,14 +71,11 @@ xfs_dir2_sf_getdents(
 
 	/*
 	 * Precalculate offsets for . and .. as we will always need them.
-	 *
-	 * XXX(hch): the second argument is sometimes 0 and sometimes
-	 * geo->datablk
 	 */
 	dot_offset = xfs_dir2_db_off_to_dataptr(geo, geo->datablk,
-						dp->d_ops->data_dot_offset);
+						geo->data_dot_offset);
 	dotdot_offset = xfs_dir2_db_off_to_dataptr(geo, geo->datablk,
-						dp->d_ops->data_dotdot_offset);
+						geo->data_dotdot_offset);
 
 	/*
 	 * Put . entry unless we're starting past it.
@@ -176,7 +173,7 @@ xfs_dir2_block_getdents(
 	/*
 	 * Set up values for the loop.
 	 */
-	ptr = (char *)hdr + dp->d_ops->data_entry_offset;
+	ptr = (char *)hdr + geo->data_entry_offset;
 	endptr = xfs_dir3_data_endp(geo, hdr);
 
 	/*
@@ -411,13 +408,13 @@ xfs_dir2_leaf_getdents(
 			/*
 			 * Find our position in the block.
 			 */
-			ptr = (char *)hdr + dp->d_ops->data_entry_offset;
+			ptr = (char *)hdr + geo->data_entry_offset;
 			byteoff = xfs_dir2_byte_to_off(geo, curoff);
 			/*
 			 * Skip past the header.
 			 */
 			if (byteoff == 0)
-				curoff += dp->d_ops->data_entry_offset;
+				curoff += geo->data_entry_offset;
 			/*
 			 * Skip past entries until we reach our offset.
 			 */
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 29/34] xfs: cleanup xfs_dir2_data_entsize
  2019-11-01 22:06 remove m_dirops Christoph Hellwig
                   ` (27 preceding siblings ...)
  2019-11-01 22:07 ` [PATCH 28/34] xfs: move the dir2 data block fixed offsets to struct xfs_da_geometry Christoph Hellwig
@ 2019-11-01 22:07 ` Christoph Hellwig
  2019-11-04 20:48   ` Darrick J. Wong
  2019-11-01 22:07 ` [PATCH 30/34] xfs: devirtualize ->data_bestfree_p Christoph Hellwig
                   ` (4 subsequent siblings)
  33 siblings, 1 reply; 81+ messages in thread
From: Christoph Hellwig @ 2019-11-01 22:07 UTC (permalink / raw)
  To: linux-xfs

Remove the XFS_DIR2_DATA_ENTSIZE and XFS_DIR3_DATA_ENTSIZE and open
code them in their only caller.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 fs/xfs/libxfs/xfs_da_format.c | 33 ---------------------------------
 fs/xfs/libxfs/xfs_dir2_data.c | 14 ++++++++++++++
 2 files changed, 14 insertions(+), 33 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c
index 0e35e613fbf3..dd2389748672 100644
--- a/fs/xfs/libxfs/xfs_da_format.c
+++ b/fs/xfs/libxfs/xfs_da_format.c
@@ -19,39 +19,6 @@
  * Directory data block operations
  */
 
-/*
- * For special situations, the dirent size ends up fixed because we always know
- * what the size of the entry is. That's true for the "." and "..", and
- * therefore we know that they are a fixed size and hence their offsets are
- * constant, as is the first entry.
- *
- * Hence, this calculation is written as a macro to be able to be calculated at
- * compile time and so certain offsets can be calculated directly in the
- * structure initaliser via the macro. There are two macros - one for dirents
- * with ftype and without so there are no unresolvable conditionals in the
- * calculations. We also use round_up() as XFS_DIR2_DATA_ALIGN is always a power
- * of 2 and the compiler doesn't reject it (unlike roundup()).
- */
-#define XFS_DIR2_DATA_ENTSIZE(n)					\
-	round_up((offsetof(struct xfs_dir2_data_entry, name[0]) + (n) +	\
-		 sizeof(xfs_dir2_data_off_t)), XFS_DIR2_DATA_ALIGN)
-
-#define XFS_DIR3_DATA_ENTSIZE(n)					\
-	round_up((offsetof(struct xfs_dir2_data_entry, name[0]) + (n) +	\
-		 sizeof(xfs_dir2_data_off_t) + sizeof(uint8_t)),	\
-		XFS_DIR2_DATA_ALIGN)
-
-int
-xfs_dir2_data_entsize(
-	struct xfs_mount	*mp,
-	int			n)
-{
-	if (xfs_sb_version_hasftype(&mp->m_sb))
-		return XFS_DIR3_DATA_ENTSIZE(n);
-	else
-		return XFS_DIR2_DATA_ENTSIZE(n);
-}
-
 static uint8_t
 xfs_dir2_data_get_ftype(
 	struct xfs_dir2_data_entry *dep)
diff --git a/fs/xfs/libxfs/xfs_dir2_data.c b/fs/xfs/libxfs/xfs_dir2_data.c
index 81ba13854f8d..c44c455b961f 100644
--- a/fs/xfs/libxfs/xfs_dir2_data.c
+++ b/fs/xfs/libxfs/xfs_dir2_data.c
@@ -24,6 +24,20 @@ static xfs_failaddr_t xfs_dir2_data_freefind_verify(
 		struct xfs_dir2_data_unused *dup,
 		struct xfs_dir2_data_free **bf_ent);
 
+int
+xfs_dir2_data_entsize(
+	struct xfs_mount	*mp,
+	int			namelen)
+{
+	size_t			len;
+
+	len = offsetof(struct xfs_dir2_data_entry, name[0]) + namelen +
+			sizeof(xfs_dir2_data_off_t) /* tag */;
+	if (xfs_sb_version_hasftype(&mp->m_sb))
+		len += sizeof(uint8_t);
+	return round_up(len, XFS_DIR2_DATA_ALIGN);
+}
+
 /*
  * Pointer to an entry's tag word.
  */
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 30/34] xfs: devirtualize ->data_bestfree_p
  2019-11-01 22:06 remove m_dirops Christoph Hellwig
                   ` (28 preceding siblings ...)
  2019-11-01 22:07 ` [PATCH 29/34] xfs: cleanup xfs_dir2_data_entsize Christoph Hellwig
@ 2019-11-01 22:07 ` Christoph Hellwig
  2019-11-04 20:49   ` Darrick J. Wong
  2019-11-01 22:07 ` [PATCH 31/34] xfs: devirtualize ->data_get_ftype and ->data_put_ftype Christoph Hellwig
                   ` (3 subsequent siblings)
  33 siblings, 1 reply; 81+ messages in thread
From: Christoph Hellwig @ 2019-11-01 22:07 UTC (permalink / raw)
  To: linux-xfs

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

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 fs/xfs/libxfs/xfs_da_format.c  | 15 ---------------
 fs/xfs/libxfs/xfs_dir2.h       |  3 ---
 fs/xfs/libxfs/xfs_dir2_block.c |  6 +++---
 fs/xfs/libxfs/xfs_dir2_data.c  | 23 ++++++++++++++++-------
 fs/xfs/libxfs/xfs_dir2_leaf.c  | 11 ++++++-----
 fs/xfs/libxfs/xfs_dir2_node.c  |  6 +++---
 fs/xfs/libxfs/xfs_dir2_priv.h  |  2 ++
 fs/xfs/scrub/dir.c             |  7 ++-----
 8 files changed, 32 insertions(+), 41 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c
index dd2389748672..b9f9fbf7eee2 100644
--- a/fs/xfs/libxfs/xfs_da_format.c
+++ b/fs/xfs/libxfs/xfs_da_format.c
@@ -56,34 +56,19 @@ xfs_dir3_data_put_ftype(
 	dep->name[dep->namelen] = type;
 }
 
-static struct xfs_dir2_data_free *
-xfs_dir2_data_bestfree_p(struct xfs_dir2_data_hdr *hdr)
-{
-	return hdr->bestfree;
-}
-
-static struct xfs_dir2_data_free *
-xfs_dir3_data_bestfree_p(struct xfs_dir2_data_hdr *hdr)
-{
-	return ((struct xfs_dir3_data_hdr *)hdr)->best_free;
-}
-
 static const struct xfs_dir_ops xfs_dir2_ops = {
 	.data_get_ftype = xfs_dir2_data_get_ftype,
 	.data_put_ftype = xfs_dir2_data_put_ftype,
-	.data_bestfree_p = xfs_dir2_data_bestfree_p,
 };
 
 static const struct xfs_dir_ops xfs_dir2_ftype_ops = {
 	.data_get_ftype = xfs_dir3_data_get_ftype,
 	.data_put_ftype = xfs_dir3_data_put_ftype,
-	.data_bestfree_p = xfs_dir2_data_bestfree_p,
 };
 
 static const struct xfs_dir_ops xfs_dir3_ops = {
 	.data_get_ftype = xfs_dir3_data_get_ftype,
 	.data_put_ftype = xfs_dir3_data_put_ftype,
-	.data_bestfree_p = xfs_dir3_data_bestfree_p,
 };
 
 /*
diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h
index 11dba3874da0..76d6d38154fb 100644
--- a/fs/xfs/libxfs/xfs_dir2.h
+++ b/fs/xfs/libxfs/xfs_dir2.h
@@ -35,8 +35,6 @@ struct xfs_dir_ops {
 	uint8_t (*data_get_ftype)(struct xfs_dir2_data_entry *dep);
 	void	(*data_put_ftype)(struct xfs_dir2_data_entry *dep,
 				uint8_t ftype);
-	struct xfs_dir2_data_free *
-		(*data_bestfree_p)(struct xfs_dir2_data_hdr *hdr);
 };
 
 extern const struct xfs_dir_ops *
@@ -81,7 +79,6 @@ extern int xfs_dir2_shrink_inode(struct xfs_da_args *args, xfs_dir2_db_t db,
 				struct xfs_buf *bp);
 
 extern void xfs_dir2_data_freescan_int(struct xfs_mount *mp,
-		const struct xfs_dir_ops *ops,
 		struct xfs_dir2_data_hdr *hdr, int *loghead);
 extern void xfs_dir2_data_freescan(struct xfs_inode *dp,
 		struct xfs_dir2_data_hdr *hdr, int *loghead);
diff --git a/fs/xfs/libxfs/xfs_dir2_block.c b/fs/xfs/libxfs/xfs_dir2_block.c
index d5f4b7187b72..50b4f1bf25a3 100644
--- a/fs/xfs/libxfs/xfs_dir2_block.c
+++ b/fs/xfs/libxfs/xfs_dir2_block.c
@@ -172,7 +172,7 @@ xfs_dir2_block_need_space(
 	struct xfs_dir2_data_unused	*enddup = NULL;
 
 	*compact = 0;
-	bf = dp->d_ops->data_bestfree_p(hdr);
+	bf = xfs_dir2_data_bestfree_p(dp->i_mount, hdr);
 
 	/*
 	 * If there are stale entries we'll use one for the leaf.
@@ -1207,8 +1207,8 @@ xfs_dir2_sf_to_block(
 				((char *)dup - (char *)hdr));
 			xfs_dir2_data_log_unused(args, bp, dup);
 			xfs_dir2_data_freeinsert(hdr,
-						 dp->d_ops->data_bestfree_p(hdr),
-						 dup, &dummy);
+					xfs_dir2_data_bestfree_p(mp, hdr),
+					dup, &dummy);
 			offset += be16_to_cpu(dup->length);
 			continue;
 		}
diff --git a/fs/xfs/libxfs/xfs_dir2_data.c b/fs/xfs/libxfs/xfs_dir2_data.c
index c44c455b961f..353629c3a1e8 100644
--- a/fs/xfs/libxfs/xfs_dir2_data.c
+++ b/fs/xfs/libxfs/xfs_dir2_data.c
@@ -24,6 +24,16 @@ static xfs_failaddr_t xfs_dir2_data_freefind_verify(
 		struct xfs_dir2_data_unused *dup,
 		struct xfs_dir2_data_free **bf_ent);
 
+struct xfs_dir2_data_free *
+xfs_dir2_data_bestfree_p(
+	struct xfs_mount		*mp,
+	struct xfs_dir2_data_hdr	*hdr)
+{
+	if (xfs_sb_version_hascrc(&mp->m_sb))
+		return ((struct xfs_dir3_data_hdr *)hdr)->best_free;
+	return hdr->bestfree;
+}
+
 int
 xfs_dir2_data_entsize(
 	struct xfs_mount	*mp,
@@ -130,7 +140,7 @@ __xfs_dir3_data_check(
 	/*
 	 * Account for zero bestfree entries.
 	 */
-	bf = ops->data_bestfree_p(hdr);
+	bf = xfs_dir2_data_bestfree_p(mp, hdr);
 	count = lastfree = freeseen = 0;
 	if (!bf[0].length) {
 		if (bf[0].offset)
@@ -590,7 +600,6 @@ xfs_dir2_data_freeremove(
 void
 xfs_dir2_data_freescan_int(
 	struct xfs_mount	*mp,
-	const struct xfs_dir_ops *ops,
 	struct xfs_dir2_data_hdr *hdr,
 	int			*loghead)
 {
@@ -609,7 +618,7 @@ xfs_dir2_data_freescan_int(
 	/*
 	 * Start by clearing the table.
 	 */
-	bf = ops->data_bestfree_p(hdr);
+	bf = xfs_dir2_data_bestfree_p(mp, hdr);
 	memset(bf, 0, sizeof(*bf) * XFS_DIR2_DATA_FD_COUNT);
 	*loghead = 1;
 	/*
@@ -650,7 +659,7 @@ xfs_dir2_data_freescan(
 	struct xfs_dir2_data_hdr *hdr,
 	int			*loghead)
 {
-	return xfs_dir2_data_freescan_int(dp->i_mount, dp->d_ops, hdr, loghead);
+	return xfs_dir2_data_freescan_int(dp->i_mount, hdr, loghead);
 }
 
 /*
@@ -703,7 +712,7 @@ xfs_dir3_data_init(
 	} else
 		hdr->magic = cpu_to_be32(XFS_DIR2_DATA_MAGIC);
 
-	bf = dp->d_ops->data_bestfree_p(hdr);
+	bf = xfs_dir2_data_bestfree_p(mp, hdr);
 	bf[0].offset = cpu_to_be16(args->geo->data_entry_offset);
 	for (i = 1; i < XFS_DIR2_DATA_FD_COUNT; i++) {
 		bf[i].length = 0;
@@ -862,7 +871,7 @@ xfs_dir2_data_make_free(
 	 * Previous and following entries are both free,
 	 * merge everything into a single free entry.
 	 */
-	bf = args->dp->d_ops->data_bestfree_p(hdr);
+	bf = xfs_dir2_data_bestfree_p(args->dp->i_mount, hdr);
 	if (prevdup && postdup) {
 		xfs_dir2_data_free_t	*dfp2;	/* another bestfree pointer */
 
@@ -1053,7 +1062,7 @@ xfs_dir2_data_use_free(
 	 * Look up the entry in the bestfree table.
 	 */
 	oldlen = be16_to_cpu(dup->length);
-	bf = args->dp->d_ops->data_bestfree_p(hdr);
+	bf = xfs_dir2_data_bestfree_p(args->dp->i_mount, hdr);
 	dfp = xfs_dir2_data_freefind(hdr, bf, dup);
 	ASSERT(dfp || oldlen <= be16_to_cpu(bf[2].length));
 	/*
diff --git a/fs/xfs/libxfs/xfs_dir2_leaf.c b/fs/xfs/libxfs/xfs_dir2_leaf.c
index c228ff66b3f0..30ccf44d817a 100644
--- a/fs/xfs/libxfs/xfs_dir2_leaf.c
+++ b/fs/xfs/libxfs/xfs_dir2_leaf.c
@@ -425,7 +425,7 @@ xfs_dir2_block_to_leaf(
 	xfs_dir3_data_check(dp, dbp);
 	btp = xfs_dir2_block_tail_p(args->geo, hdr);
 	blp = xfs_dir2_block_leaf_p(btp);
-	bf = dp->d_ops->data_bestfree_p(hdr);
+	bf = xfs_dir2_data_bestfree_p(dp->i_mount, hdr);
 
 	/*
 	 * Set the counts in the leaf header.
@@ -823,7 +823,7 @@ xfs_dir2_leaf_addname(
 		else
 			xfs_dir3_leaf_log_bests(args, lbp, use_block, use_block);
 		hdr = dbp->b_addr;
-		bf = dp->d_ops->data_bestfree_p(hdr);
+		bf = xfs_dir2_data_bestfree_p(dp->i_mount, hdr);
 		bestsp[use_block] = bf[0].length;
 		grown = 1;
 	} else {
@@ -839,7 +839,7 @@ xfs_dir2_leaf_addname(
 			return error;
 		}
 		hdr = dbp->b_addr;
-		bf = dp->d_ops->data_bestfree_p(hdr);
+		bf = xfs_dir2_data_bestfree_p(dp->i_mount, hdr);
 		grown = 0;
 	}
 	/*
@@ -1376,7 +1376,7 @@ xfs_dir2_leaf_removename(
 	leaf = lbp->b_addr;
 	hdr = dbp->b_addr;
 	xfs_dir3_data_check(dp, dbp);
-	bf = dp->d_ops->data_bestfree_p(hdr);
+	bf = xfs_dir2_data_bestfree_p(dp->i_mount, hdr);
 
 	/*
 	 * Point to the leaf entry, use that to point to the data entry.
@@ -1618,7 +1618,8 @@ xfs_dir2_leaf_trim_data(
 #ifdef DEBUG
 {
 	struct xfs_dir2_data_hdr *hdr = dbp->b_addr;
-	struct xfs_dir2_data_free *bf = dp->d_ops->data_bestfree_p(hdr);
+	struct xfs_dir2_data_free *bf =
+		xfs_dir2_data_bestfree_p(dp->i_mount, hdr);
 
 	ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) ||
 	       hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC));
diff --git a/fs/xfs/libxfs/xfs_dir2_node.c b/fs/xfs/libxfs/xfs_dir2_node.c
index 58362169aa57..d4a1d2455e72 100644
--- a/fs/xfs/libxfs/xfs_dir2_node.c
+++ b/fs/xfs/libxfs/xfs_dir2_node.c
@@ -1311,7 +1311,7 @@ xfs_dir2_leafn_remove(
 	dbp = dblk->bp;
 	hdr = dbp->b_addr;
 	dep = (xfs_dir2_data_entry_t *)((char *)hdr + off);
-	bf = dp->d_ops->data_bestfree_p(hdr);
+	bf = xfs_dir2_data_bestfree_p(dp->i_mount, hdr);
 	longest = be16_to_cpu(bf[0].length);
 	needlog = needscan = 0;
 	xfs_dir2_data_make_free(args, dbp, off,
@@ -1769,7 +1769,7 @@ xfs_dir2_node_add_datablk(
 	}
 
 	/* Update the freespace value for the new block in the table. */
-	bf = dp->d_ops->data_bestfree_p(dbp->b_addr);
+	bf = xfs_dir2_data_bestfree_p(mp, dbp->b_addr);
 	hdr->bests[*findex] = bf[0].length;
 
 	*dbpp = dbp;
@@ -1942,7 +1942,7 @@ xfs_dir2_node_addname_int(
 
 	/* setup for data block up now */
 	hdr = dbp->b_addr;
-	bf = dp->d_ops->data_bestfree_p(hdr);
+	bf = xfs_dir2_data_bestfree_p(dp->i_mount, hdr);
 	ASSERT(be16_to_cpu(bf[0].length) >= length);
 
 	/* Point to the existing unused space. */
diff --git a/fs/xfs/libxfs/xfs_dir2_priv.h b/fs/xfs/libxfs/xfs_dir2_priv.h
index 750344407f27..436693514c7c 100644
--- a/fs/xfs/libxfs/xfs_dir2_priv.h
+++ b/fs/xfs/libxfs/xfs_dir2_priv.h
@@ -47,6 +47,8 @@ extern int xfs_dir2_leaf_to_block(struct xfs_da_args *args,
 		struct xfs_buf *lbp, struct xfs_buf *dbp);
 
 /* xfs_dir2_data.c */
+struct xfs_dir2_data_free *xfs_dir2_data_bestfree_p(struct xfs_mount *mp,
+		struct xfs_dir2_data_hdr *hdr);
 int xfs_dir2_data_entsize(struct xfs_mount *mp, int n);
 __be16 *xfs_dir2_data_entry_tag_p(struct xfs_mount *mp,
 		struct xfs_dir2_data_entry *dep);
diff --git a/fs/xfs/scrub/dir.c b/fs/xfs/scrub/dir.c
index d13c863d72a5..54772ad9a431 100644
--- a/fs/xfs/scrub/dir.c
+++ b/fs/xfs/scrub/dir.c
@@ -327,7 +327,6 @@ xchk_directory_data_bestfree(
 	struct xfs_buf			*bp;
 	struct xfs_dir2_data_free	*bf;
 	struct xfs_mount		*mp = sc->mp;
-	const struct xfs_dir_ops	*d_ops;
 	char				*ptr;
 	char				*endptr;
 	u16				tag;
@@ -338,8 +337,6 @@ xchk_directory_data_bestfree(
 	int				offset;
 	int				error;
 
-	d_ops = sc->ip->d_ops;
-
 	if (is_block) {
 		/* dir block format */
 		if (lblk != XFS_B_TO_FSBT(mp, XFS_DIR2_DATA_OFFSET))
@@ -359,7 +356,7 @@ xchk_directory_data_bestfree(
 		goto out_buf;
 
 	/* Do the bestfrees correspond to actual free space? */
-	bf = d_ops->data_bestfree_p(bp->b_addr);
+	bf = xfs_dir2_data_bestfree_p(mp, bp->b_addr);
 	smallest_bestfree = UINT_MAX;
 	for (dfp = &bf[0]; dfp < &bf[XFS_DIR2_DATA_FD_COUNT]; dfp++) {
 		offset = be16_to_cpu(dfp->offset);
@@ -466,7 +463,7 @@ xchk_directory_check_freesp(
 {
 	struct xfs_dir2_data_free	*dfp;
 
-	dfp = sc->ip->d_ops->data_bestfree_p(dbp->b_addr);
+	dfp = xfs_dir2_data_bestfree_p(sc->mp, dbp->b_addr);
 
 	if (len != be16_to_cpu(dfp->length))
 		xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk);
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 31/34] xfs: devirtualize ->data_get_ftype and ->data_put_ftype
  2019-11-01 22:06 remove m_dirops Christoph Hellwig
                   ` (29 preceding siblings ...)
  2019-11-01 22:07 ` [PATCH 30/34] xfs: devirtualize ->data_bestfree_p Christoph Hellwig
@ 2019-11-01 22:07 ` Christoph Hellwig
  2019-11-04 20:50   ` Darrick J. Wong
  2019-11-01 22:07 ` [PATCH 32/34] xfs: remove the now unused dir ops infrastructure Christoph Hellwig
                   ` (2 subsequent siblings)
  33 siblings, 1 reply; 81+ messages in thread
From: Christoph Hellwig @ 2019-11-01 22:07 UTC (permalink / raw)
  To: linux-xfs

Replace the ->data_get_ftype and ->data_put_ftype dir ops methods with
directly called xfs_dir2_data_get_ftype and xfs_dir2_data_put_ftype
helpers that takes care of the differences between the directory format
with and without the file type field.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 fs/xfs/libxfs/xfs_da_format.c  | 47 ----------------------------------
 fs/xfs/libxfs/xfs_dir2.h       |  3 ---
 fs/xfs/libxfs/xfs_dir2_block.c | 13 +++++-----
 fs/xfs/libxfs/xfs_dir2_data.c  | 47 +++++++++++++++++++++++-----------
 fs/xfs/libxfs/xfs_dir2_leaf.c  |  6 ++---
 fs/xfs/libxfs/xfs_dir2_node.c  |  6 ++---
 fs/xfs/libxfs/xfs_dir2_priv.h  |  4 +++
 fs/xfs/libxfs/xfs_dir2_sf.c    |  2 +-
 fs/xfs/xfs_dir2_readdir.c      |  4 +--
 9 files changed, 52 insertions(+), 80 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c
index b9f9fbf7eee2..498363ac193d 100644
--- a/fs/xfs/libxfs/xfs_da_format.c
+++ b/fs/xfs/libxfs/xfs_da_format.c
@@ -15,60 +15,13 @@
 #include "xfs_dir2.h"
 #include "xfs_dir2_priv.h"
 
-/*
- * Directory data block operations
- */
-
-static uint8_t
-xfs_dir2_data_get_ftype(
-	struct xfs_dir2_data_entry *dep)
-{
-	return XFS_DIR3_FT_UNKNOWN;
-}
-
-static void
-xfs_dir2_data_put_ftype(
-	struct xfs_dir2_data_entry *dep,
-	uint8_t			ftype)
-{
-	ASSERT(ftype < XFS_DIR3_FT_MAX);
-}
-
-static uint8_t
-xfs_dir3_data_get_ftype(
-	struct xfs_dir2_data_entry *dep)
-{
-	uint8_t		ftype = dep->name[dep->namelen];
-
-	if (ftype >= XFS_DIR3_FT_MAX)
-		return XFS_DIR3_FT_UNKNOWN;
-	return ftype;
-}
-
-static void
-xfs_dir3_data_put_ftype(
-	struct xfs_dir2_data_entry *dep,
-	uint8_t			type)
-{
-	ASSERT(type < XFS_DIR3_FT_MAX);
-	ASSERT(dep->namelen != 0);
-
-	dep->name[dep->namelen] = type;
-}
-
 static const struct xfs_dir_ops xfs_dir2_ops = {
-	.data_get_ftype = xfs_dir2_data_get_ftype,
-	.data_put_ftype = xfs_dir2_data_put_ftype,
 };
 
 static const struct xfs_dir_ops xfs_dir2_ftype_ops = {
-	.data_get_ftype = xfs_dir3_data_get_ftype,
-	.data_put_ftype = xfs_dir3_data_put_ftype,
 };
 
 static const struct xfs_dir_ops xfs_dir3_ops = {
-	.data_get_ftype = xfs_dir3_data_get_ftype,
-	.data_put_ftype = xfs_dir3_data_put_ftype,
 };
 
 /*
diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h
index 76d6d38154fb..f869ee01a381 100644
--- a/fs/xfs/libxfs/xfs_dir2.h
+++ b/fs/xfs/libxfs/xfs_dir2.h
@@ -32,9 +32,6 @@ extern unsigned char xfs_mode_to_ftype(int mode);
  * directory operations vector for encode/decode routines
  */
 struct xfs_dir_ops {
-	uint8_t (*data_get_ftype)(struct xfs_dir2_data_entry *dep);
-	void	(*data_put_ftype)(struct xfs_dir2_data_entry *dep,
-				uint8_t ftype);
 };
 
 extern const struct xfs_dir_ops *
diff --git a/fs/xfs/libxfs/xfs_dir2_block.c b/fs/xfs/libxfs/xfs_dir2_block.c
index 50b4f1bf25a3..94d32e515478 100644
--- a/fs/xfs/libxfs/xfs_dir2_block.c
+++ b/fs/xfs/libxfs/xfs_dir2_block.c
@@ -541,7 +541,7 @@ xfs_dir2_block_addname(
 	dep->inumber = cpu_to_be64(args->inumber);
 	dep->namelen = args->namelen;
 	memcpy(dep->name, args->name, args->namelen);
-	dp->d_ops->data_put_ftype(dep, args->filetype);
+	xfs_dir2_data_put_ftype(dp->i_mount, dep, args->filetype);
 	tagp = xfs_dir2_data_entry_tag_p(dp->i_mount, dep);
 	*tagp = cpu_to_be16((char *)dep - (char *)hdr);
 	/*
@@ -633,7 +633,7 @@ xfs_dir2_block_lookup(
 	 * Fill in inode number, CI name if appropriate, release the block.
 	 */
 	args->inumber = be64_to_cpu(dep->inumber);
-	args->filetype = dp->d_ops->data_get_ftype(dep);
+	args->filetype = xfs_dir2_data_get_ftype(dp->i_mount, dep);
 	error = xfs_dir_cilookup_result(args, dep->name, dep->namelen);
 	xfs_trans_brelse(args->trans, bp);
 	return error;
@@ -865,7 +865,7 @@ xfs_dir2_block_replace(
 	 * Change the inode number to the new value.
 	 */
 	dep->inumber = cpu_to_be64(args->inumber);
-	dp->d_ops->data_put_ftype(dep, args->filetype);
+	xfs_dir2_data_put_ftype(dp->i_mount, dep, args->filetype);
 	xfs_dir2_data_log_entry(args, bp, dep);
 	xfs_dir3_data_check(dp, bp);
 	return 0;
@@ -1154,7 +1154,7 @@ xfs_dir2_sf_to_block(
 	dep->inumber = cpu_to_be64(dp->i_ino);
 	dep->namelen = 1;
 	dep->name[0] = '.';
-	dp->d_ops->data_put_ftype(dep, XFS_DIR3_FT_DIR);
+	xfs_dir2_data_put_ftype(mp, dep, XFS_DIR3_FT_DIR);
 	tagp = xfs_dir2_data_entry_tag_p(mp, dep);
 	*tagp = cpu_to_be16((char *)dep - (char *)hdr);
 	xfs_dir2_data_log_entry(args, bp, dep);
@@ -1168,7 +1168,7 @@ xfs_dir2_sf_to_block(
 	dep->inumber = cpu_to_be64(xfs_dir2_sf_get_parent_ino(sfp));
 	dep->namelen = 2;
 	dep->name[0] = dep->name[1] = '.';
-	dp->d_ops->data_put_ftype(dep, XFS_DIR3_FT_DIR);
+	xfs_dir2_data_put_ftype(mp, dep, XFS_DIR3_FT_DIR);
 	tagp = xfs_dir2_data_entry_tag_p(mp, dep);
 	*tagp = cpu_to_be16((char *)dep - (char *)hdr);
 	xfs_dir2_data_log_entry(args, bp, dep);
@@ -1218,7 +1218,8 @@ xfs_dir2_sf_to_block(
 		dep = (xfs_dir2_data_entry_t *)((char *)hdr + newoffset);
 		dep->inumber = cpu_to_be64(xfs_dir2_sf_get_ino(mp, sfp, sfep));
 		dep->namelen = sfep->namelen;
-		dp->d_ops->data_put_ftype(dep, xfs_dir2_sf_get_ftype(mp, sfep));
+		xfs_dir2_data_put_ftype(mp, dep,
+				xfs_dir2_sf_get_ftype(mp, sfep));
 		memcpy(dep->name, sfep->name, dep->namelen);
 		tagp = xfs_dir2_data_entry_tag_p(mp, dep);
 		*tagp = cpu_to_be16((char *)dep - (char *)hdr);
diff --git a/fs/xfs/libxfs/xfs_dir2_data.c b/fs/xfs/libxfs/xfs_dir2_data.c
index 353629c3a1e8..9752a0da5b95 100644
--- a/fs/xfs/libxfs/xfs_dir2_data.c
+++ b/fs/xfs/libxfs/xfs_dir2_data.c
@@ -60,6 +60,34 @@ xfs_dir2_data_entry_tag_p(
 		xfs_dir2_data_entsize(mp, dep->namelen) - sizeof(__be16));
 }
 
+uint8_t
+xfs_dir2_data_get_ftype(
+	struct xfs_mount		*mp,
+	struct xfs_dir2_data_entry	*dep)
+{
+	if (xfs_sb_version_hasftype(&mp->m_sb)) {
+		uint8_t			ftype = dep->name[dep->namelen];
+
+		if (likely(ftype < XFS_DIR3_FT_MAX))
+			return ftype;
+	}
+
+	return XFS_DIR3_FT_UNKNOWN;
+}
+
+void
+xfs_dir2_data_put_ftype(
+	struct xfs_mount		*mp,
+	struct xfs_dir2_data_entry	*dep,
+	uint8_t				ftype)
+{
+	ASSERT(ftype < XFS_DIR3_FT_MAX);
+	ASSERT(dep->namelen != 0);
+
+	if (xfs_sb_version_hasftype(&mp->m_sb))
+		dep->name[dep->namelen] = ftype;
+}
+
 /*
  * Check the consistency of the data block.
  * The input can also be a block-format directory.
@@ -88,23 +116,12 @@ __xfs_dir3_data_check(
 	char			*p;		/* current data position */
 	int			stale;		/* count of stale leaves */
 	struct xfs_name		name;
-	const struct xfs_dir_ops *ops;
-	struct xfs_da_geometry	*geo;
-
-	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);
+	struct xfs_da_geometry	*geo = mp->m_dir_geo;
 
 	/*
-	 * If this isn't a directory, or we don't get handed the dir ops,
-	 * something is seriously wrong.  Bail out.
+	 * If this isn't a directory, something is seriously wrong.  Bail out.
 	 */
-	if ((dp && !S_ISDIR(VFS_I(dp)->i_mode)) ||
-	    ops != xfs_dir_get_ops(mp, NULL))
+	if (dp && !S_ISDIR(VFS_I(dp)->i_mode))
 		return __this_address;
 
 	hdr = bp->b_addr;
@@ -215,7 +232,7 @@ __xfs_dir3_data_check(
 		if (be16_to_cpu(*xfs_dir2_data_entry_tag_p(mp, dep)) !=
 		    (char *)dep - (char *)hdr)
 			return __this_address;
-		if (ops->data_get_ftype(dep) >= XFS_DIR3_FT_MAX)
+		if (xfs_dir2_data_get_ftype(mp, dep) >= XFS_DIR3_FT_MAX)
 			return __this_address;
 		count++;
 		lastfree = 0;
diff --git a/fs/xfs/libxfs/xfs_dir2_leaf.c b/fs/xfs/libxfs/xfs_dir2_leaf.c
index 30ccf44d817a..ff54c8f08ded 100644
--- a/fs/xfs/libxfs/xfs_dir2_leaf.c
+++ b/fs/xfs/libxfs/xfs_dir2_leaf.c
@@ -865,7 +865,7 @@ xfs_dir2_leaf_addname(
 	dep->inumber = cpu_to_be64(args->inumber);
 	dep->namelen = args->namelen;
 	memcpy(dep->name, args->name, dep->namelen);
-	dp->d_ops->data_put_ftype(dep, args->filetype);
+	xfs_dir2_data_put_ftype(dp->i_mount, dep, args->filetype);
 	tagp = xfs_dir2_data_entry_tag_p(dp->i_mount, dep);
 	*tagp = cpu_to_be16((char *)dep - (char *)hdr);
 	/*
@@ -1195,7 +1195,7 @@ xfs_dir2_leaf_lookup(
 	 * Return the found inode number & CI name if appropriate
 	 */
 	args->inumber = be64_to_cpu(dep->inumber);
-	args->filetype = dp->d_ops->data_get_ftype(dep);
+	args->filetype = xfs_dir2_data_get_ftype(dp->i_mount, dep);
 	error = xfs_dir_cilookup_result(args, dep->name, dep->namelen);
 	xfs_trans_brelse(tp, dbp);
 	xfs_trans_brelse(tp, lbp);
@@ -1524,7 +1524,7 @@ xfs_dir2_leaf_replace(
 	 * Put the new inode number in, log it.
 	 */
 	dep->inumber = cpu_to_be64(args->inumber);
-	dp->d_ops->data_put_ftype(dep, args->filetype);
+	xfs_dir2_data_put_ftype(dp->i_mount, dep, args->filetype);
 	tp = args->trans;
 	xfs_dir2_data_log_entry(args, dbp, dep);
 	xfs_dir3_leaf_check(dp, lbp);
diff --git a/fs/xfs/libxfs/xfs_dir2_node.c b/fs/xfs/libxfs/xfs_dir2_node.c
index d4a1d2455e72..e51b103fd429 100644
--- a/fs/xfs/libxfs/xfs_dir2_node.c
+++ b/fs/xfs/libxfs/xfs_dir2_node.c
@@ -878,7 +878,7 @@ xfs_dir2_leafn_lookup_for_entry(
 				xfs_trans_brelse(tp, state->extrablk.bp);
 			args->cmpresult = cmp;
 			args->inumber = be64_to_cpu(dep->inumber);
-			args->filetype = dp->d_ops->data_get_ftype(dep);
+			args->filetype = xfs_dir2_data_get_ftype(mp, dep);
 			*indexp = index;
 			state->extravalid = 1;
 			state->extrablk.bp = curbp;
@@ -1963,7 +1963,7 @@ xfs_dir2_node_addname_int(
 	dep->inumber = cpu_to_be64(args->inumber);
 	dep->namelen = args->namelen;
 	memcpy(dep->name, args->name, dep->namelen);
-	dp->d_ops->data_put_ftype(dep, args->filetype);
+	xfs_dir2_data_put_ftype(dp->i_mount, dep, args->filetype);
 	tagp = xfs_dir2_data_entry_tag_p(dp->i_mount, dep);
 	*tagp = cpu_to_be16((char *)dep - (char *)hdr);
 	xfs_dir2_data_log_entry(args, dbp, dep);
@@ -2247,7 +2247,7 @@ xfs_dir2_node_replace(
 		 * Fill in the new inode number and log the entry.
 		 */
 		dep->inumber = cpu_to_be64(inum);
-		args->dp->d_ops->data_put_ftype(dep, ftype);
+		xfs_dir2_data_put_ftype(state->mp, dep, ftype);
 		xfs_dir2_data_log_entry(args, state->extrablk.bp, dep);
 		rval = 0;
 	}
diff --git a/fs/xfs/libxfs/xfs_dir2_priv.h b/fs/xfs/libxfs/xfs_dir2_priv.h
index 436693514c7c..5258d9da5f12 100644
--- a/fs/xfs/libxfs/xfs_dir2_priv.h
+++ b/fs/xfs/libxfs/xfs_dir2_priv.h
@@ -52,6 +52,10 @@ struct xfs_dir2_data_free *xfs_dir2_data_bestfree_p(struct xfs_mount *mp,
 int xfs_dir2_data_entsize(struct xfs_mount *mp, int n);
 __be16 *xfs_dir2_data_entry_tag_p(struct xfs_mount *mp,
 		struct xfs_dir2_data_entry *dep);
+uint8_t xfs_dir2_data_get_ftype(struct xfs_mount *mp,
+		struct xfs_dir2_data_entry *dep);
+void xfs_dir2_data_put_ftype(struct xfs_mount *mp,
+		struct xfs_dir2_data_entry *dep, uint8_t ftype);
 
 #ifdef DEBUG
 extern void xfs_dir3_data_check(struct xfs_inode *dp, struct xfs_buf *bp);
diff --git a/fs/xfs/libxfs/xfs_dir2_sf.c b/fs/xfs/libxfs/xfs_dir2_sf.c
index 8ecbb0828e42..9a3958aee9f2 100644
--- a/fs/xfs/libxfs/xfs_dir2_sf.c
+++ b/fs/xfs/libxfs/xfs_dir2_sf.c
@@ -337,7 +337,7 @@ xfs_dir2_block_to_sf(
 			xfs_dir2_sf_put_ino(mp, sfp, sfep,
 					      be64_to_cpu(dep->inumber));
 			xfs_dir2_sf_put_ftype(mp, sfep,
-					dp->d_ops->data_get_ftype(dep));
+					xfs_dir2_data_get_ftype(mp, dep));
 
 			sfep = xfs_dir2_sf_nextentry(mp, sfp, sfep);
 		}
diff --git a/fs/xfs/xfs_dir2_readdir.c b/fs/xfs/xfs_dir2_readdir.c
index 7519317d7a21..7885616bdfe5 100644
--- a/fs/xfs/xfs_dir2_readdir.c
+++ b/fs/xfs/xfs_dir2_readdir.c
@@ -208,7 +208,7 @@ xfs_dir2_block_getdents(
 					    (char *)dep - (char *)hdr);
 
 		ctx->pos = cook & 0x7fffffff;
-		filetype = dp->d_ops->data_get_ftype(dep);
+		filetype = xfs_dir2_data_get_ftype(dp->i_mount, dep);
 		/*
 		 * If it didn't fit, set the final offset to here & return.
 		 */
@@ -463,7 +463,7 @@ xfs_dir2_leaf_getdents(
 
 		dep = (xfs_dir2_data_entry_t *)ptr;
 		length = xfs_dir2_data_entsize(mp, dep->namelen);
-		filetype = dp->d_ops->data_get_ftype(dep);
+		filetype = xfs_dir2_data_get_ftype(mp, dep);
 
 		ctx->pos = xfs_dir2_byte_to_dataptr(curoff) & 0x7fffffff;
 		if (!xfs_dir2_namecheck(dep->name, dep->namelen)) {
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 32/34] xfs: remove the now unused dir ops infrastructure
  2019-11-01 22:06 remove m_dirops Christoph Hellwig
                   ` (30 preceding siblings ...)
  2019-11-01 22:07 ` [PATCH 31/34] xfs: devirtualize ->data_get_ftype and ->data_put_ftype Christoph Hellwig
@ 2019-11-01 22:07 ` Christoph Hellwig
  2019-11-04 20:50   ` Darrick J. Wong
  2019-11-01 22:07 ` [PATCH 33/34] xfs: merge xfs_dir2_data_freescan and xfs_dir2_data_freescan_int Christoph Hellwig
  2019-11-01 22:07 ` [PATCH 34/34] xfs: always pass a valid hdr to xfs_dir3_leaf_check_int Christoph Hellwig
  33 siblings, 1 reply; 81+ messages in thread
From: Christoph Hellwig @ 2019-11-01 22:07 UTC (permalink / raw)
  To: linux-xfs

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 fs/xfs/Makefile               |  1 -
 fs/xfs/libxfs/xfs_da_btree.h  |  1 -
 fs/xfs/libxfs/xfs_da_format.c | 46 -----------------------------------
 fs/xfs/libxfs/xfs_dir2.c      |  2 --
 fs/xfs/libxfs/xfs_dir2.h      |  9 -------
 fs/xfs/xfs_inode.h            |  3 ---
 fs/xfs/xfs_iops.c             |  1 -
 fs/xfs/xfs_mount.h            |  2 --
 8 files changed, 65 deletions(-)
 delete mode 100644 fs/xfs/libxfs/xfs_da_format.c

diff --git a/fs/xfs/Makefile b/fs/xfs/Makefile
index 06b68b6115bc..aceca2f9a3db 100644
--- a/fs/xfs/Makefile
+++ b/fs/xfs/Makefile
@@ -27,7 +27,6 @@ xfs-y				+= $(addprefix libxfs/, \
 				   xfs_bmap_btree.o \
 				   xfs_btree.o \
 				   xfs_da_btree.o \
-				   xfs_da_format.o \
 				   xfs_defer.o \
 				   xfs_dir2.o \
 				   xfs_dir2_block.o \
diff --git a/fs/xfs/libxfs/xfs_da_btree.h b/fs/xfs/libxfs/xfs_da_btree.h
index a3333e7a084d..7362e706cda7 100644
--- a/fs/xfs/libxfs/xfs_da_btree.h
+++ b/fs/xfs/libxfs/xfs_da_btree.h
@@ -10,7 +10,6 @@
 struct xfs_inode;
 struct xfs_trans;
 struct zone;
-struct xfs_dir_ops;
 
 /*
  * Directory/attribute geometry information. There will be one of these for each
diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c
deleted file mode 100644
index 498363ac193d..000000000000
--- a/fs/xfs/libxfs/xfs_da_format.c
+++ /dev/null
@@ -1,46 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright (c) 2000,2002,2005 Silicon Graphics, Inc.
- * Copyright (c) 2013 Red Hat, Inc.
- * All Rights Reserved.
- */
-#include "xfs.h"
-#include "xfs_fs.h"
-#include "xfs_shared.h"
-#include "xfs_format.h"
-#include "xfs_log_format.h"
-#include "xfs_trans_resv.h"
-#include "xfs_mount.h"
-#include "xfs_inode.h"
-#include "xfs_dir2.h"
-#include "xfs_dir2_priv.h"
-
-static const struct xfs_dir_ops xfs_dir2_ops = {
-};
-
-static const struct xfs_dir_ops xfs_dir2_ftype_ops = {
-};
-
-static const struct xfs_dir_ops xfs_dir3_ops = {
-};
-
-/*
- * Return the ops structure according to the current config.  If we are passed
- * an inode, then that overrides the default config we use which is based on
- * feature bits.
- */
-const struct xfs_dir_ops *
-xfs_dir_get_ops(
-	struct xfs_mount	*mp,
-	struct xfs_inode	*dp)
-{
-	if (dp)
-		return dp->d_ops;
-	if (mp->m_dir_inode_ops)
-		return mp->m_dir_inode_ops;
-	if (xfs_sb_version_hascrc(&mp->m_sb))
-		return &xfs_dir3_ops;
-	if (xfs_sb_version_hasftype(&mp->m_sb))
-		return &xfs_dir2_ftype_ops;
-	return &xfs_dir2_ops;
-}
diff --git a/fs/xfs/libxfs/xfs_dir2.c b/fs/xfs/libxfs/xfs_dir2.c
index 33a6e8aacdba..b1fc89173ea6 100644
--- a/fs/xfs/libxfs/xfs_dir2.c
+++ b/fs/xfs/libxfs/xfs_dir2.c
@@ -104,8 +104,6 @@ xfs_da_mount(
 	ASSERT(mp->m_sb.sb_versionnum & XFS_SB_VERSION_DIRV2BIT);
 	ASSERT(xfs_dir2_dirblock_bytes(&mp->m_sb) <= XFS_MAX_BLOCKSIZE);
 
-	mp->m_dir_inode_ops = xfs_dir_get_ops(mp, NULL);
-
 	mp->m_dir_geo = kmem_zalloc(sizeof(struct xfs_da_geometry),
 				    KM_MAYFAIL);
 	mp->m_attr_geo = kmem_zalloc(sizeof(struct xfs_da_geometry),
diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h
index f869ee01a381..ccdbc612fb76 100644
--- a/fs/xfs/libxfs/xfs_dir2.h
+++ b/fs/xfs/libxfs/xfs_dir2.h
@@ -28,15 +28,6 @@ extern struct xfs_name	xfs_name_dotdot;
  */
 extern unsigned char xfs_mode_to_ftype(int mode);
 
-/*
- * directory operations vector for encode/decode routines
- */
-struct xfs_dir_ops {
-};
-
-extern const struct xfs_dir_ops *
-	xfs_dir_get_ops(struct xfs_mount *mp, struct xfs_inode *dp);
-
 /*
  * Generic directory interface routines
  */
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h
index bcfb35a9c5ca..6516dd1fc86a 100644
--- a/fs/xfs/xfs_inode.h
+++ b/fs/xfs/xfs_inode.h
@@ -37,9 +37,6 @@ typedef struct xfs_inode {
 	struct xfs_ifork	*i_cowfp;	/* copy on write extents */
 	struct xfs_ifork	i_df;		/* data fork */
 
-	/* operations vectors */
-	const struct xfs_dir_ops *d_ops;		/* directory ops vector */
-
 	/* Transaction and locking information. */
 	struct xfs_inode_log_item *i_itemp;	/* logging information */
 	mrlock_t		i_lock;		/* inode lock */
diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c
index 40d4495e013c..155c9269b7bb 100644
--- a/fs/xfs/xfs_iops.c
+++ b/fs/xfs/xfs_iops.c
@@ -1317,7 +1317,6 @@ xfs_setup_inode(
 		lockdep_set_class(&inode->i_rwsem,
 				  &inode->i_sb->s_type->i_mutex_dir_key);
 		lockdep_set_class(&ip->i_lock.mr_lock, &xfs_dir_ilock_class);
-		ip->d_ops = ip->i_mount->m_dir_inode_ops;
 	} else {
 		lockdep_set_class(&ip->i_lock.mr_lock, &xfs_nondir_ilock_class);
 	}
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
index 3ddc5f4d1053..6dc1ff761572 100644
--- a/fs/xfs/xfs_mount.h
+++ b/fs/xfs/xfs_mount.h
@@ -12,7 +12,6 @@ struct xfs_mru_cache;
 struct xfs_nameops;
 struct xfs_ail;
 struct xfs_quotainfo;
-struct xfs_dir_ops;
 struct xfs_da_geometry;
 
 /* dynamic preallocation free space thresholds, 5% down to 1% */
@@ -158,7 +157,6 @@ typedef struct xfs_mount {
 	int			m_swidth;	/* stripe width */
 	uint8_t			m_sectbb_log;	/* sectlog - BBSHIFT */
 	const struct xfs_nameops *m_dirnameops;	/* vector of dir name ops */
-	const struct xfs_dir_ops *m_dir_inode_ops; /* vector of dir inode ops */
 	uint			m_chsize;	/* size of next field */
 	atomic_t		m_active_trans;	/* number trans frozen */
 	struct xfs_mru_cache	*m_filestream;  /* per-mount filestream data */
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 33/34] xfs: merge xfs_dir2_data_freescan and xfs_dir2_data_freescan_int
  2019-11-01 22:06 remove m_dirops Christoph Hellwig
                   ` (31 preceding siblings ...)
  2019-11-01 22:07 ` [PATCH 32/34] xfs: remove the now unused dir ops infrastructure Christoph Hellwig
@ 2019-11-01 22:07 ` Christoph Hellwig
  2019-11-04 20:51   ` Darrick J. Wong
  2019-11-01 22:07 ` [PATCH 34/34] xfs: always pass a valid hdr to xfs_dir3_leaf_check_int Christoph Hellwig
  33 siblings, 1 reply; 81+ messages in thread
From: Christoph Hellwig @ 2019-11-01 22:07 UTC (permalink / raw)
  To: linux-xfs

There is no real need for xfs_dir2_data_freescan wrapper, so rename
xfs_dir2_data_freescan_int to xfs_dir2_data_freescan and let the
callers dereference the mount pointer from the inode.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 fs/xfs/libxfs/xfs_dir2.h       |  4 +---
 fs/xfs/libxfs/xfs_dir2_block.c | 10 +++++-----
 fs/xfs/libxfs/xfs_dir2_data.c  | 11 +----------
 fs/xfs/libxfs/xfs_dir2_leaf.c  |  6 +++---
 fs/xfs/libxfs/xfs_dir2_node.c  |  4 ++--
 5 files changed, 12 insertions(+), 23 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h
index ccdbc612fb76..8bf4cf227740 100644
--- a/fs/xfs/libxfs/xfs_dir2.h
+++ b/fs/xfs/libxfs/xfs_dir2.h
@@ -66,9 +66,7 @@ extern int xfs_dir2_isleaf(struct xfs_da_args *args, int *r);
 extern int xfs_dir2_shrink_inode(struct xfs_da_args *args, xfs_dir2_db_t db,
 				struct xfs_buf *bp);
 
-extern void xfs_dir2_data_freescan_int(struct xfs_mount *mp,
-		struct xfs_dir2_data_hdr *hdr, int *loghead);
-extern void xfs_dir2_data_freescan(struct xfs_inode *dp,
+extern void xfs_dir2_data_freescan(struct xfs_mount *mp,
 		struct xfs_dir2_data_hdr *hdr, int *loghead);
 extern void xfs_dir2_data_log_entry(struct xfs_da_args *args,
 		struct xfs_buf *bp, struct xfs_dir2_data_entry *dep);
diff --git a/fs/xfs/libxfs/xfs_dir2_block.c b/fs/xfs/libxfs/xfs_dir2_block.c
index 94d32e515478..4b3ea6730775 100644
--- a/fs/xfs/libxfs/xfs_dir2_block.c
+++ b/fs/xfs/libxfs/xfs_dir2_block.c
@@ -311,7 +311,7 @@ xfs_dir2_block_compact(
 	 * This needs to happen before the next call to use_free.
 	 */
 	if (needscan)
-		xfs_dir2_data_freescan(args->dp, hdr, needlog);
+		xfs_dir2_data_freescan(args->dp->i_mount, hdr, needlog);
 }
 
 /*
@@ -458,7 +458,7 @@ xfs_dir2_block_addname(
 		 * This needs to happen before the next call to use_free.
 		 */
 		if (needscan) {
-			xfs_dir2_data_freescan(dp, hdr, &needlog);
+			xfs_dir2_data_freescan(dp->i_mount, hdr, &needlog);
 			needscan = 0;
 		}
 		/*
@@ -548,7 +548,7 @@ xfs_dir2_block_addname(
 	 * Clean up the bestfree array and log the header, tail, and entry.
 	 */
 	if (needscan)
-		xfs_dir2_data_freescan(dp, hdr, &needlog);
+		xfs_dir2_data_freescan(dp->i_mount, hdr, &needlog);
 	if (needlog)
 		xfs_dir2_data_log_header(args, bp);
 	xfs_dir2_block_log_tail(tp, bp);
@@ -807,7 +807,7 @@ xfs_dir2_block_removename(
 	 * Fix up bestfree, log the header if necessary.
 	 */
 	if (needscan)
-		xfs_dir2_data_freescan(dp, hdr, &needlog);
+		xfs_dir2_data_freescan(dp->i_mount, hdr, &needlog);
 	if (needlog)
 		xfs_dir2_data_log_header(args, bp);
 	xfs_dir3_data_check(dp, bp);
@@ -1014,7 +1014,7 @@ xfs_dir2_leaf_to_block(
 	 * Scan the bestfree if we need it and log the data block header.
 	 */
 	if (needscan)
-		xfs_dir2_data_freescan(dp, hdr, &needlog);
+		xfs_dir2_data_freescan(dp->i_mount, hdr, &needlog);
 	if (needlog)
 		xfs_dir2_data_log_header(args, dbp);
 	/*
diff --git a/fs/xfs/libxfs/xfs_dir2_data.c b/fs/xfs/libxfs/xfs_dir2_data.c
index 9752a0da5b95..4304c62796dd 100644
--- a/fs/xfs/libxfs/xfs_dir2_data.c
+++ b/fs/xfs/libxfs/xfs_dir2_data.c
@@ -615,7 +615,7 @@ xfs_dir2_data_freeremove(
  * Given a data block, reconstruct its bestfree map.
  */
 void
-xfs_dir2_data_freescan_int(
+xfs_dir2_data_freescan(
 	struct xfs_mount	*mp,
 	struct xfs_dir2_data_hdr *hdr,
 	int			*loghead)
@@ -670,15 +670,6 @@ xfs_dir2_data_freescan_int(
 	}
 }
 
-void
-xfs_dir2_data_freescan(
-	struct xfs_inode	*dp,
-	struct xfs_dir2_data_hdr *hdr,
-	int			*loghead)
-{
-	return xfs_dir2_data_freescan_int(dp->i_mount, hdr, loghead);
-}
-
 /*
  * Initialize a data block at the given block number in the directory.
  * Give back the buffer for the created block.
diff --git a/fs/xfs/libxfs/xfs_dir2_leaf.c b/fs/xfs/libxfs/xfs_dir2_leaf.c
index ff54c8f08ded..6912264e081e 100644
--- a/fs/xfs/libxfs/xfs_dir2_leaf.c
+++ b/fs/xfs/libxfs/xfs_dir2_leaf.c
@@ -465,7 +465,7 @@ xfs_dir2_block_to_leaf(
 		hdr->magic = cpu_to_be32(XFS_DIR3_DATA_MAGIC);
 
 	if (needscan)
-		xfs_dir2_data_freescan(dp, hdr, &needlog);
+		xfs_dir2_data_freescan(dp->i_mount, hdr, &needlog);
 	/*
 	 * Set up leaf tail and bests table.
 	 */
@@ -872,7 +872,7 @@ xfs_dir2_leaf_addname(
 	 * Need to scan fix up the bestfree table.
 	 */
 	if (needscan)
-		xfs_dir2_data_freescan(dp, hdr, &needlog);
+		xfs_dir2_data_freescan(dp->i_mount, hdr, &needlog);
 	/*
 	 * Need to log the data block's header.
 	 */
@@ -1413,7 +1413,7 @@ xfs_dir2_leaf_removename(
 	 * log the data block header if necessary.
 	 */
 	if (needscan)
-		xfs_dir2_data_freescan(dp, hdr, &needlog);
+		xfs_dir2_data_freescan(dp->i_mount, hdr, &needlog);
 	if (needlog)
 		xfs_dir2_data_log_header(args, dbp);
 	/*
diff --git a/fs/xfs/libxfs/xfs_dir2_node.c b/fs/xfs/libxfs/xfs_dir2_node.c
index e51b103fd429..a131ed5e5f3b 100644
--- a/fs/xfs/libxfs/xfs_dir2_node.c
+++ b/fs/xfs/libxfs/xfs_dir2_node.c
@@ -1322,7 +1322,7 @@ xfs_dir2_leafn_remove(
 	 * Log the data block header if needed.
 	 */
 	if (needscan)
-		xfs_dir2_data_freescan(dp, hdr, &needlog);
+		xfs_dir2_data_freescan(dp->i_mount, hdr, &needlog);
 	if (needlog)
 		xfs_dir2_data_log_header(args, dbp);
 	xfs_dir3_data_check(dp, dbp);
@@ -1970,7 +1970,7 @@ xfs_dir2_node_addname_int(
 
 	/* Rescan the freespace and log the data block if needed. */
 	if (needscan)
-		xfs_dir2_data_freescan(dp, hdr, &needlog);
+		xfs_dir2_data_freescan(dp->i_mount, hdr, &needlog);
 	if (needlog)
 		xfs_dir2_data_log_header(args, dbp);
 
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 34/34] xfs: always pass a valid hdr to xfs_dir3_leaf_check_int
  2019-11-01 22:06 remove m_dirops Christoph Hellwig
                   ` (32 preceding siblings ...)
  2019-11-01 22:07 ` [PATCH 33/34] xfs: merge xfs_dir2_data_freescan and xfs_dir2_data_freescan_int Christoph Hellwig
@ 2019-11-01 22:07 ` Christoph Hellwig
  2019-11-04 20:53   ` Darrick J. Wong
  33 siblings, 1 reply; 81+ messages in thread
From: Christoph Hellwig @ 2019-11-01 22:07 UTC (permalink / raw)
  To: linux-xfs

Move the code for extracting the incore header to the only caller that
didn't already do that.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 fs/xfs/libxfs/xfs_dir2_leaf.c | 31 +++++++++++++------------------
 1 file changed, 13 insertions(+), 18 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_dir2_leaf.c b/fs/xfs/libxfs/xfs_dir2_leaf.c
index 6912264e081e..fecec1ac8e40 100644
--- a/fs/xfs/libxfs/xfs_dir2_leaf.c
+++ b/fs/xfs/libxfs/xfs_dir2_leaf.c
@@ -137,20 +137,14 @@ xfs_dir3_leaf_check(
 
 xfs_failaddr_t
 xfs_dir3_leaf_check_int(
-	struct xfs_mount	*mp,
-	struct xfs_dir3_icleaf_hdr *hdr,
-	struct xfs_dir2_leaf	*leaf)
+	struct xfs_mount		*mp,
+	struct xfs_dir3_icleaf_hdr	*hdr,
+	struct xfs_dir2_leaf		*leaf)
 {
-	xfs_dir2_leaf_tail_t	*ltp;
-	int			stale;
-	int			i;
-	struct xfs_dir3_icleaf_hdr leafhdr;
-	struct xfs_da_geometry	*geo = mp->m_dir_geo;
-
-	if (!hdr) {
-		xfs_dir2_leaf_hdr_from_disk(mp, &leafhdr, leaf);
-		hdr = &leafhdr;
-	}
+	struct xfs_da_geometry		*geo = mp->m_dir_geo;
+	xfs_dir2_leaf_tail_t		*ltp;
+	int				stale;
+	int				i;
 
 	ltp = xfs_dir2_leaf_tail_p(geo, leaf);
 
@@ -190,17 +184,18 @@ xfs_dir3_leaf_check_int(
  */
 static xfs_failaddr_t
 xfs_dir3_leaf_verify(
-	struct xfs_buf		*bp)
+	struct xfs_buf			*bp)
 {
-	struct xfs_mount	*mp = bp->b_mount;
-	struct xfs_dir2_leaf	*leaf = bp->b_addr;
-	xfs_failaddr_t		fa;
+	struct xfs_mount		*mp = bp->b_mount;
+	struct xfs_dir3_icleaf_hdr	leafhdr;
+	xfs_failaddr_t			fa;
 
 	fa = xfs_da3_blkinfo_verify(bp, bp->b_addr);
 	if (fa)
 		return fa;
 
-	return xfs_dir3_leaf_check_int(mp, NULL, leaf);
+	xfs_dir2_leaf_hdr_from_disk(mp, &leafhdr, bp->b_addr);
+	return xfs_dir3_leaf_check_int(mp, &leafhdr, bp->b_addr);
 }
 
 static void
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 81+ messages in thread

* Re: [PATCH 01/34] xfs: move incore structures out of xfs_da_format.h
  2019-11-01 22:06 ` [PATCH 01/34] xfs: move incore structures out of xfs_da_format.h Christoph Hellwig
@ 2019-11-04 18:21   ` Darrick J. Wong
  0 siblings, 0 replies; 81+ messages in thread
From: Darrick J. Wong @ 2019-11-04 18:21 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-xfs

On Fri, Nov 01, 2019 at 03:06:46PM -0700, Christoph Hellwig wrote:
> Move the abstract in-memory version of various btree block headers
> out of xfs_da_format.h as they aren't on-disk formats.
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>

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

--D

> ---
>  fs/xfs/libxfs/xfs_attr_leaf.h | 23 ++++++++++++++
>  fs/xfs/libxfs/xfs_da_btree.h  | 13 ++++++++
>  fs/xfs/libxfs/xfs_da_format.c |  1 +
>  fs/xfs/libxfs/xfs_da_format.h | 57 -----------------------------------
>  fs/xfs/libxfs/xfs_dir2.h      |  2 ++
>  fs/xfs/libxfs/xfs_dir2_priv.h | 20 ++++++++++++
>  6 files changed, 59 insertions(+), 57 deletions(-)
> 
> diff --git a/fs/xfs/libxfs/xfs_attr_leaf.h b/fs/xfs/libxfs/xfs_attr_leaf.h
> index bb0880057ee3..16208a7743df 100644
> --- a/fs/xfs/libxfs/xfs_attr_leaf.h
> +++ b/fs/xfs/libxfs/xfs_attr_leaf.h
> @@ -16,6 +16,29 @@ struct xfs_da_state_blk;
>  struct xfs_inode;
>  struct xfs_trans;
>  
> +/*
> + * Incore version of the attribute leaf header.
> + */
> +struct xfs_attr3_icleaf_hdr {
> +	uint32_t	forw;
> +	uint32_t	back;
> +	uint16_t	magic;
> +	uint16_t	count;
> +	uint16_t	usedbytes;
> +	/*
> +	 * Firstused is 32-bit here instead of 16-bit like the on-disk variant
> +	 * to support maximum fsb size of 64k without overflow issues throughout
> +	 * the attr code. Instead, the overflow condition is handled on
> +	 * conversion to/from disk.
> +	 */
> +	uint32_t	firstused;
> +	__u8		holes;
> +	struct {
> +		uint16_t	base;
> +		uint16_t	size;
> +	} freemap[XFS_ATTR_LEAF_MAPSIZE];
> +};
> +
>  /*
>   * Used to keep a list of "remote value" extents when unlinking an inode.
>   */
> diff --git a/fs/xfs/libxfs/xfs_da_btree.h b/fs/xfs/libxfs/xfs_da_btree.h
> index ae0bbd20d9ca..02f7a21ab3a5 100644
> --- a/fs/xfs/libxfs/xfs_da_btree.h
> +++ b/fs/xfs/libxfs/xfs_da_btree.h
> @@ -124,6 +124,19 @@ typedef struct xfs_da_state {
>  						/* for dirv2 extrablk is data */
>  } xfs_da_state_t;
>  
> +/*
> + * In-core version of the node header to abstract the differences in the v2 and
> + * v3 disk format of the headers. Callers need to convert to/from disk format as
> + * appropriate.
> + */
> +struct xfs_da3_icnode_hdr {
> +	uint32_t		forw;
> +	uint32_t		back;
> +	uint16_t		magic;
> +	uint16_t		count;
> +	uint16_t		level;
> +};
> +
>  /*
>   * Utility macros to aid in logging changed structure fields.
>   */
> diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c
> index b1ae572496b6..31bb250c1899 100644
> --- a/fs/xfs/libxfs/xfs_da_format.c
> +++ b/fs/xfs/libxfs/xfs_da_format.c
> @@ -13,6 +13,7 @@
>  #include "xfs_mount.h"
>  #include "xfs_inode.h"
>  #include "xfs_dir2.h"
> +#include "xfs_dir2_priv.h"
>  
>  /*
>   * Shortform directory ops
> diff --git a/fs/xfs/libxfs/xfs_da_format.h b/fs/xfs/libxfs/xfs_da_format.h
> index ae654e06b2fb..548806060f45 100644
> --- a/fs/xfs/libxfs/xfs_da_format.h
> +++ b/fs/xfs/libxfs/xfs_da_format.h
> @@ -93,19 +93,6 @@ struct xfs_da3_intnode {
>  	struct xfs_da_node_entry __btree[];
>  };
>  
> -/*
> - * In-core version of the node header to abstract the differences in the v2 and
> - * v3 disk format of the headers. Callers need to convert to/from disk format as
> - * appropriate.
> - */
> -struct xfs_da3_icnode_hdr {
> -	uint32_t	forw;
> -	uint32_t	back;
> -	uint16_t	magic;
> -	uint16_t	count;
> -	uint16_t	level;
> -};
> -
>  /*
>   * Directory version 2.
>   *
> @@ -434,14 +421,6 @@ struct xfs_dir3_leaf_hdr {
>  	__be32			pad;		/* 64 bit alignment */
>  };
>  
> -struct xfs_dir3_icleaf_hdr {
> -	uint32_t		forw;
> -	uint32_t		back;
> -	uint16_t		magic;
> -	uint16_t		count;
> -	uint16_t		stale;
> -};
> -
>  /*
>   * Leaf block entry.
>   */
> @@ -520,19 +499,6 @@ struct xfs_dir3_free {
>  
>  #define XFS_DIR3_FREE_CRC_OFF  offsetof(struct xfs_dir3_free, hdr.hdr.crc)
>  
> -/*
> - * In core version of the free block header, abstracted away from on-disk format
> - * differences. Use this in the code, and convert to/from the disk version using
> - * xfs_dir3_free_hdr_from_disk/xfs_dir3_free_hdr_to_disk.
> - */
> -struct xfs_dir3_icfree_hdr {
> -	uint32_t	magic;
> -	uint32_t	firstdb;
> -	uint32_t	nvalid;
> -	uint32_t	nused;
> -
> -};
> -
>  /*
>   * Single block format.
>   *
> @@ -709,29 +675,6 @@ struct xfs_attr3_leafblock {
>  	 */
>  };
>  
> -/*
> - * incore, neutral version of the attribute leaf header
> - */
> -struct xfs_attr3_icleaf_hdr {
> -	uint32_t	forw;
> -	uint32_t	back;
> -	uint16_t	magic;
> -	uint16_t	count;
> -	uint16_t	usedbytes;
> -	/*
> -	 * firstused is 32-bit here instead of 16-bit like the on-disk variant
> -	 * to support maximum fsb size of 64k without overflow issues throughout
> -	 * the attr code. Instead, the overflow condition is handled on
> -	 * conversion to/from disk.
> -	 */
> -	uint32_t	firstused;
> -	__u8		holes;
> -	struct {
> -		uint16_t	base;
> -		uint16_t	size;
> -	} freemap[XFS_ATTR_LEAF_MAPSIZE];
> -};
> -
>  /*
>   * Special value to represent fs block size in the leaf header firstused field.
>   * Only used when block size overflows the 2-bytes available on disk.
> diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h
> index f54244779492..e170792c0acc 100644
> --- a/fs/xfs/libxfs/xfs_dir2.h
> +++ b/fs/xfs/libxfs/xfs_dir2.h
> @@ -18,6 +18,8 @@ struct xfs_dir2_sf_entry;
>  struct xfs_dir2_data_hdr;
>  struct xfs_dir2_data_entry;
>  struct xfs_dir2_data_unused;
> +struct xfs_dir3_icfree_hdr;
> +struct xfs_dir3_icleaf_hdr;
>  
>  extern struct xfs_name	xfs_name_dotdot;
>  
> diff --git a/fs/xfs/libxfs/xfs_dir2_priv.h b/fs/xfs/libxfs/xfs_dir2_priv.h
> index 59f9fb2241a5..973b1527b7ba 100644
> --- a/fs/xfs/libxfs/xfs_dir2_priv.h
> +++ b/fs/xfs/libxfs/xfs_dir2_priv.h
> @@ -8,6 +8,26 @@
>  
>  struct dir_context;
>  
> +/*
> + * In-core version of the leaf and free block headers to abstract the
> + * differences in the v2 and v3 disk format of the headers.
> + */
> +struct xfs_dir3_icleaf_hdr {
> +	uint32_t		forw;
> +	uint32_t		back;
> +	uint16_t		magic;
> +	uint16_t		count;
> +	uint16_t		stale;
> +};
> +
> +struct xfs_dir3_icfree_hdr {
> +	uint32_t		magic;
> +	uint32_t		firstdb;
> +	uint32_t		nvalid;
> +	uint32_t		nused;
> +
> +};
> +
>  /* xfs_dir2.c */
>  extern int xfs_dir2_grow_inode(struct xfs_da_args *args, int space,
>  				xfs_dir2_db_t *dbp);
> -- 
> 2.20.1
> 

^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH 02/34] xfs: refactor btree node scrubbing
  2019-11-01 22:06 ` [PATCH 02/34] xfs: refactor btree node scrubbing Christoph Hellwig
@ 2019-11-04 18:36   ` Darrick J. Wong
  2019-11-05  1:35     ` Christoph Hellwig
  0 siblings, 1 reply; 81+ messages in thread
From: Darrick J. Wong @ 2019-11-04 18:36 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-xfs

On Fri, Nov 01, 2019 at 03:06:47PM -0700, Christoph Hellwig wrote:
> Break up xchk_da_btree_entry and handle looking up leaf node entries
> in the attr / dir callbacks, so that only the generic node handling
> is left in the common core code.  Note that the checks for the crc
> enabled blocks are removed, as the scrubbing code already remaps the
> magic numbers earlier.
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
>  fs/xfs/scrub/attr.c    | 12 ++++++-----
>  fs/xfs/scrub/dabtree.c | 48 ++++++++++--------------------------------
>  fs/xfs/scrub/dabtree.h |  3 +--
>  fs/xfs/scrub/dir.c     | 12 ++++++++---
>  4 files changed, 28 insertions(+), 47 deletions(-)
> 
> diff --git a/fs/xfs/scrub/attr.c b/fs/xfs/scrub/attr.c
> index 0edc7f8eb96e..035d5734e0af 100644
> --- a/fs/xfs/scrub/attr.c
> +++ b/fs/xfs/scrub/attr.c
> @@ -398,15 +398,14 @@ xchk_xattr_block(
>  STATIC int
>  xchk_xattr_rec(
>  	struct xchk_da_btree		*ds,
> -	int				level,
> -	void				*rec)
> +	int				level)
>  {
>  	struct xfs_mount		*mp = ds->state->mp;
> -	struct xfs_attr_leaf_entry	*ent = rec;
> -	struct xfs_da_state_blk		*blk;
> +	struct xfs_da_state_blk		*blk = &ds->state->path.blk[level];
>  	struct xfs_attr_leaf_name_local	*lentry;
>  	struct xfs_attr_leaf_name_remote	*rentry;
>  	struct xfs_buf			*bp;
> +	struct xfs_attr_leaf_entry	*ent;
>  	xfs_dahash_t			calc_hash;
>  	xfs_dahash_t			hash;
>  	int				nameidx;
> @@ -414,7 +413,10 @@ xchk_xattr_rec(
>  	unsigned int			badflags;
>  	int				error;
>  
> -	blk = &ds->state->path.blk[level];
> +	ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC);
> +
> +	ent = (void *)xfs_attr3_leaf_entryp(blk->bp->b_addr) +
> +		(blk->index * sizeof(struct xfs_attr_leaf_entry));

Seeing as this function returns a pointer to struct xfs_attr_leaf_entry,
why not clean this up to:

ent = xfs_attr3_leaf_entryp(...)[blk->index]; ?

Though looking at that, I wonder if a better option would be to
incorporate the index as an argument to xfs_attr3_leaf_entryp?

(And yes, that's material for a separate patch...)

>  
>  	/* Check the whole block, if necessary. */
>  	error = xchk_xattr_block(ds, level);
> diff --git a/fs/xfs/scrub/dabtree.c b/fs/xfs/scrub/dabtree.c
> index 77ff9f97bcda..d1248c223c7f 100644
> --- a/fs/xfs/scrub/dabtree.c
> +++ b/fs/xfs/scrub/dabtree.c
> @@ -77,40 +77,17 @@ xchk_da_set_corrupt(
>  			__return_address);
>  }
>  
> -/* Find an entry at a certain level in a da btree. */
> -STATIC void *
> -xchk_da_btree_entry(
> -	struct xchk_da_btree	*ds,
> -	int			level,
> -	int			rec)
> +static struct xfs_da_node_entry *
> +xchk_da_btree_node_entry(
> +	struct xchk_da_btree		*ds,
> +	int				level)
>  {
> -	char			*ents;
> -	struct xfs_da_state_blk	*blk;
> -	void			*baddr;
> +	struct xfs_da_state_blk		*blk = &ds->state->path.blk[level];
>  
> -	/* Dispatch the entry finding function. */
> -	blk = &ds->state->path.blk[level];
> -	baddr = blk->bp->b_addr;
> -	switch (blk->magic) {
> -	case XFS_ATTR_LEAF_MAGIC:
> -	case XFS_ATTR3_LEAF_MAGIC:
> -		ents = (char *)xfs_attr3_leaf_entryp(baddr);
> -		return ents + (rec * sizeof(struct xfs_attr_leaf_entry));
> -	case XFS_DIR2_LEAFN_MAGIC:
> -	case XFS_DIR3_LEAFN_MAGIC:
> -		ents = (char *)ds->dargs.dp->d_ops->leaf_ents_p(baddr);
> -		return ents + (rec * sizeof(struct xfs_dir2_leaf_entry));
> -	case XFS_DIR2_LEAF1_MAGIC:
> -	case XFS_DIR3_LEAF1_MAGIC:
> -		ents = (char *)ds->dargs.dp->d_ops->leaf_ents_p(baddr);
> -		return ents + (rec * sizeof(struct xfs_dir2_leaf_entry));
> -	case XFS_DA_NODE_MAGIC:
> -	case XFS_DA3_NODE_MAGIC:
> -		ents = (char *)ds->dargs.dp->d_ops->node_tree_p(baddr);
> -		return ents + (rec * sizeof(struct xfs_da_node_entry));
> -	}
> +	ASSERT(blk->magic == XFS_DA_NODE_MAGIC);
>  
> -	return NULL;
> +	return (void *)ds->dargs.dp->d_ops->node_tree_p(blk->bp->b_addr) +
> +		(blk->index * sizeof(struct xfs_da_node_entry));
>  }
>  
>  /* Scrub a da btree hash (key). */
> @@ -136,7 +113,7 @@ xchk_da_btree_hash(
>  
>  	/* Is this hash no larger than the parent hash? */
>  	blks = ds->state->path.blk;

gcc complained that blks is no longer necessary.

--D

> -	entry = xchk_da_btree_entry(ds, level - 1, blks[level - 1].index);
> +	entry = xchk_da_btree_node_entry(ds, level - 1);
>  	parent_hash = be32_to_cpu(entry->hashval);
>  	if (parent_hash < hash)
>  		xchk_da_set_corrupt(ds, level);
> @@ -479,7 +456,6 @@ xchk_da_btree(
>  	struct xfs_mount		*mp = sc->mp;
>  	struct xfs_da_state_blk		*blks;
>  	struct xfs_da_node_entry	*key;
> -	void				*rec;
>  	xfs_dablk_t			blkno;
>  	int				level;
>  	int				error;
> @@ -538,9 +514,7 @@ xchk_da_btree(
>  			}
>  
>  			/* Dispatch record scrubbing. */
> -			rec = xchk_da_btree_entry(&ds, level,
> -					blks[level].index);
> -			error = scrub_fn(&ds, level, rec);
> +			error = scrub_fn(&ds, level);
>  			if (error)
>  				break;
>  			if (xchk_should_terminate(sc, &error) ||
> @@ -562,7 +536,7 @@ xchk_da_btree(
>  		}
>  
>  		/* Hashes in order for scrub? */
> -		key = xchk_da_btree_entry(&ds, level, blks[level].index);
> +		key = xchk_da_btree_node_entry(&ds, level);
>  		error = xchk_da_btree_hash(&ds, level, &key->hashval);
>  		if (error)
>  			goto out;
> diff --git a/fs/xfs/scrub/dabtree.h b/fs/xfs/scrub/dabtree.h
> index cb3f0003245b..1f3515c6d5a8 100644
> --- a/fs/xfs/scrub/dabtree.h
> +++ b/fs/xfs/scrub/dabtree.h
> @@ -28,8 +28,7 @@ struct xchk_da_btree {
>  	int			tree_level;
>  };
>  
> -typedef int (*xchk_da_btree_rec_fn)(struct xchk_da_btree *ds,
> -		int level, void *rec);
> +typedef int (*xchk_da_btree_rec_fn)(struct xchk_da_btree *ds, int level);
>  
>  /* Check for da btree operation errors. */
>  bool xchk_da_process_error(struct xchk_da_btree *ds, int level, int *error);
> diff --git a/fs/xfs/scrub/dir.c b/fs/xfs/scrub/dir.c
> index 1e2e11721eb9..97f274f7cd38 100644
> --- a/fs/xfs/scrub/dir.c
> +++ b/fs/xfs/scrub/dir.c
> @@ -179,14 +179,14 @@ xchk_dir_actor(
>  STATIC int
>  xchk_dir_rec(
>  	struct xchk_da_btree		*ds,
> -	int				level,
> -	void				*rec)
> +	int				level)
>  {
> +	struct xfs_da_state_blk		*blk = &ds->state->path.blk[level];
>  	struct xfs_mount		*mp = ds->state->mp;
> -	struct xfs_dir2_leaf_entry	*ent = rec;
>  	struct xfs_inode		*dp = ds->dargs.dp;
>  	struct xfs_dir2_data_entry	*dent;
>  	struct xfs_buf			*bp;
> +	struct xfs_dir2_leaf_entry	*ent;
>  	char				*p, *endp;
>  	xfs_ino_t			ino;
>  	xfs_dablk_t			rec_bno;
> @@ -198,6 +198,12 @@ xchk_dir_rec(
>  	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));
> +
>  	/* Check the hash of the entry. */
>  	error = xchk_da_btree_hash(ds, level, &ent->hashval);
>  	if (error)
> -- 
> 2.20.1
> 

^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH 03/34] xfs: devirtualize ->node_hdr_from_disk
  2019-11-01 22:06 ` [PATCH 03/34] xfs: devirtualize ->node_hdr_from_disk Christoph Hellwig
@ 2019-11-04 18:37   ` Darrick J. Wong
  0 siblings, 0 replies; 81+ messages in thread
From: Darrick J. Wong @ 2019-11-04 18:37 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-xfs

On Fri, Nov 01, 2019 at 03:06:48PM -0700, Christoph Hellwig wrote:
> Replace the ->node_hdr_from_disk dir ops method with a directly called
> xfs_da_node_hdr_from_disk helper that takes care of the v4 vs v5
> difference.
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>

Seems like a nice cleanup,
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>

--D

> ---
>  fs/xfs/libxfs/xfs_attr_leaf.c |  2 +-
>  fs/xfs/libxfs/xfs_da_btree.c  | 84 ++++++++++++++++++++++-------------
>  fs/xfs/libxfs/xfs_da_btree.h  |  3 ++
>  fs/xfs/libxfs/xfs_da_format.c | 33 --------------
>  fs/xfs/libxfs/xfs_dir2.h      |  2 -
>  fs/xfs/scrub/dabtree.c        |  2 +-
>  fs/xfs/xfs_attr_inactive.c    |  2 +-
>  fs/xfs/xfs_attr_list.c        |  2 +-
>  8 files changed, 60 insertions(+), 70 deletions(-)
> 
> diff --git a/fs/xfs/libxfs/xfs_attr_leaf.c b/fs/xfs/libxfs/xfs_attr_leaf.c
> index 56e62b3d9bb7..131fef677896 100644
> --- a/fs/xfs/libxfs/xfs_attr_leaf.c
> +++ b/fs/xfs/libxfs/xfs_attr_leaf.c
> @@ -1185,7 +1185,7 @@ xfs_attr3_leaf_to_node(
>  	if (error)
>  		goto out;
>  	node = bp1->b_addr;
> -	dp->d_ops->node_hdr_from_disk(&icnodehdr, node);
> +	xfs_da3_node_hdr_from_disk(mp, &icnodehdr, node);
>  	btree = dp->d_ops->node_tree_p(node);
>  
>  	leaf = bp2->b_addr;
> diff --git a/fs/xfs/libxfs/xfs_da_btree.c b/fs/xfs/libxfs/xfs_da_btree.c
> index 4fd1223c1bd5..f7ddc91ed099 100644
> --- a/fs/xfs/libxfs/xfs_da_btree.c
> +++ b/fs/xfs/libxfs/xfs_da_btree.c
> @@ -110,6 +110,31 @@ xfs_da_state_free(xfs_da_state_t *state)
>  	kmem_zone_free(xfs_da_state_zone, state);
>  }
>  
> +void
> +xfs_da3_node_hdr_from_disk(
> +	struct xfs_mount		*mp,
> +	struct xfs_da3_icnode_hdr	*to,
> +	struct xfs_da_intnode		*from)
> +{
> +	if (xfs_sb_version_hascrc(&mp->m_sb)) {
> +		struct xfs_da3_intnode	*from3 = (struct xfs_da3_intnode *)from;
> +
> +		to->forw = be32_to_cpu(from3->hdr.info.hdr.forw);
> +		to->back = be32_to_cpu(from3->hdr.info.hdr.back);
> +		to->magic = be16_to_cpu(from3->hdr.info.hdr.magic);
> +		to->count = be16_to_cpu(from3->hdr.__count);
> +		to->level = be16_to_cpu(from3->hdr.__level);
> +		ASSERT(to->magic == XFS_DA3_NODE_MAGIC);
> +	} else {
> +		to->forw = be32_to_cpu(from->hdr.info.forw);
> +		to->back = be32_to_cpu(from->hdr.info.back);
> +		to->magic = be16_to_cpu(from->hdr.info.magic);
> +		to->count = be16_to_cpu(from->hdr.__count);
> +		to->level = be16_to_cpu(from->hdr.__level);
> +		ASSERT(to->magic == XFS_DA_NODE_MAGIC);
> +	}
> +}
> +
>  /*
>   * Verify an xfs_da3_blkinfo structure. Note that the da3 fields are only
>   * accessible on v5 filesystems. This header format is common across da node,
> @@ -145,12 +170,9 @@ xfs_da3_node_verify(
>  	struct xfs_mount	*mp = bp->b_mount;
>  	struct xfs_da_intnode	*hdr = bp->b_addr;
>  	struct xfs_da3_icnode_hdr ichdr;
> -	const struct xfs_dir_ops *ops;
>  	xfs_failaddr_t		fa;
>  
> -	ops = xfs_dir_get_ops(mp, NULL);
> -
> -	ops->node_hdr_from_disk(&ichdr, hdr);
> +	xfs_da3_node_hdr_from_disk(mp, &ichdr, hdr);
>  
>  	fa = xfs_da3_blkinfo_verify(bp, bp->b_addr);
>  	if (fa)
> @@ -577,7 +599,7 @@ xfs_da3_root_split(
>  	    oldroot->hdr.info.magic == cpu_to_be16(XFS_DA3_NODE_MAGIC)) {
>  		struct xfs_da3_icnode_hdr icnodehdr;
>  
> -		dp->d_ops->node_hdr_from_disk(&icnodehdr, oldroot);
> +		xfs_da3_node_hdr_from_disk(dp->i_mount, &icnodehdr, oldroot);
>  		btree = dp->d_ops->node_tree_p(oldroot);
>  		size = (int)((char *)&btree[icnodehdr.count] - (char *)oldroot);
>  		level = icnodehdr.level;
> @@ -637,7 +659,7 @@ xfs_da3_root_split(
>  		return error;
>  
>  	node = bp->b_addr;
> -	dp->d_ops->node_hdr_from_disk(&nodehdr, node);
> +	xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr, node);
>  	btree = dp->d_ops->node_tree_p(node);
>  	btree[0].hashval = cpu_to_be32(blk1->hashval);
>  	btree[0].before = cpu_to_be32(blk1->blkno);
> @@ -686,7 +708,7 @@ xfs_da3_node_split(
>  	trace_xfs_da_node_split(state->args);
>  
>  	node = oldblk->bp->b_addr;
> -	dp->d_ops->node_hdr_from_disk(&nodehdr, node);
> +	xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr, node);
>  
>  	/*
>  	 * With V2 dirs the extra block is data or freespace.
> @@ -733,7 +755,7 @@ xfs_da3_node_split(
>  	 * If we had double-split op below us, then add the extra block too.
>  	 */
>  	node = oldblk->bp->b_addr;
> -	dp->d_ops->node_hdr_from_disk(&nodehdr, node);
> +	xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr, node);
>  	if (oldblk->index <= nodehdr.count) {
>  		oldblk->index++;
>  		xfs_da3_node_add(state, oldblk, addblk);
> @@ -788,8 +810,8 @@ xfs_da3_node_rebalance(
>  
>  	node1 = blk1->bp->b_addr;
>  	node2 = blk2->bp->b_addr;
> -	dp->d_ops->node_hdr_from_disk(&nodehdr1, node1);
> -	dp->d_ops->node_hdr_from_disk(&nodehdr2, node2);
> +	xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr1, node1);
> +	xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr2, node2);
>  	btree1 = dp->d_ops->node_tree_p(node1);
>  	btree2 = dp->d_ops->node_tree_p(node2);
>  
> @@ -804,8 +826,8 @@ xfs_da3_node_rebalance(
>  		tmpnode = node1;
>  		node1 = node2;
>  		node2 = tmpnode;
> -		dp->d_ops->node_hdr_from_disk(&nodehdr1, node1);
> -		dp->d_ops->node_hdr_from_disk(&nodehdr2, node2);
> +		xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr1, node1);
> +		xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr2, node2);
>  		btree1 = dp->d_ops->node_tree_p(node1);
>  		btree2 = dp->d_ops->node_tree_p(node2);
>  		swap = 1;
> @@ -886,8 +908,8 @@ xfs_da3_node_rebalance(
>  	if (swap) {
>  		node1 = blk1->bp->b_addr;
>  		node2 = blk2->bp->b_addr;
> -		dp->d_ops->node_hdr_from_disk(&nodehdr1, node1);
> -		dp->d_ops->node_hdr_from_disk(&nodehdr2, node2);
> +		xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr1, node1);
> +		xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr2, node2);
>  		btree1 = dp->d_ops->node_tree_p(node1);
>  		btree2 = dp->d_ops->node_tree_p(node2);
>  	}
> @@ -921,7 +943,7 @@ xfs_da3_node_add(
>  	trace_xfs_da_node_add(state->args);
>  
>  	node = oldblk->bp->b_addr;
> -	dp->d_ops->node_hdr_from_disk(&nodehdr, node);
> +	xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr, node);
>  	btree = dp->d_ops->node_tree_p(node);
>  
>  	ASSERT(oldblk->index >= 0 && oldblk->index <= nodehdr.count);
> @@ -1092,7 +1114,7 @@ xfs_da3_root_join(
>  
>  	args = state->args;
>  	oldroot = root_blk->bp->b_addr;
> -	dp->d_ops->node_hdr_from_disk(&oldroothdr, oldroot);
> +	xfs_da3_node_hdr_from_disk(dp->i_mount, &oldroothdr, oldroot);
>  	ASSERT(oldroothdr.forw == 0);
>  	ASSERT(oldroothdr.back == 0);
>  
> @@ -1172,7 +1194,7 @@ xfs_da3_node_toosmall(
>  	blk = &state->path.blk[ state->path.active-1 ];
>  	info = blk->bp->b_addr;
>  	node = (xfs_da_intnode_t *)info;
> -	dp->d_ops->node_hdr_from_disk(&nodehdr, node);
> +	xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr, node);
>  	if (nodehdr.count > (state->args->geo->node_ents >> 1)) {
>  		*action = 0;	/* blk over 50%, don't try to join */
>  		return 0;	/* blk over 50%, don't try to join */
> @@ -1230,7 +1252,7 @@ xfs_da3_node_toosmall(
>  			return error;
>  
>  		node = bp->b_addr;
> -		dp->d_ops->node_hdr_from_disk(&thdr, node);
> +		xfs_da3_node_hdr_from_disk(dp->i_mount, &thdr, node);
>  		xfs_trans_brelse(state->args->trans, bp);
>  
>  		if (count - thdr.count >= 0)
> @@ -1277,7 +1299,7 @@ xfs_da3_node_lasthash(
>  	struct xfs_da3_icnode_hdr nodehdr;
>  
>  	node = bp->b_addr;
> -	dp->d_ops->node_hdr_from_disk(&nodehdr, node);
> +	xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr, node);
>  	if (count)
>  		*count = nodehdr.count;
>  	if (!nodehdr.count)
> @@ -1328,7 +1350,7 @@ xfs_da3_fixhashpath(
>  		struct xfs_da3_icnode_hdr nodehdr;
>  
>  		node = blk->bp->b_addr;
> -		dp->d_ops->node_hdr_from_disk(&nodehdr, node);
> +		xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr, node);
>  		btree = dp->d_ops->node_tree_p(node);
>  		if (be32_to_cpu(btree[blk->index].hashval) == lasthash)
>  			break;
> @@ -1360,7 +1382,7 @@ xfs_da3_node_remove(
>  	trace_xfs_da_node_remove(state->args);
>  
>  	node = drop_blk->bp->b_addr;
> -	dp->d_ops->node_hdr_from_disk(&nodehdr, node);
> +	xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr, node);
>  	ASSERT(drop_blk->index < nodehdr.count);
>  	ASSERT(drop_blk->index >= 0);
>  
> @@ -1416,8 +1438,8 @@ xfs_da3_node_unbalance(
>  
>  	drop_node = drop_blk->bp->b_addr;
>  	save_node = save_blk->bp->b_addr;
> -	dp->d_ops->node_hdr_from_disk(&drop_hdr, drop_node);
> -	dp->d_ops->node_hdr_from_disk(&save_hdr, save_node);
> +	xfs_da3_node_hdr_from_disk(dp->i_mount, &drop_hdr, drop_node);
> +	xfs_da3_node_hdr_from_disk(dp->i_mount, &save_hdr, save_node);
>  	drop_btree = dp->d_ops->node_tree_p(drop_node);
>  	save_btree = dp->d_ops->node_tree_p(save_node);
>  	tp = state->args->trans;
> @@ -1550,7 +1572,7 @@ xfs_da3_node_lookup_int(
>  		 * Search an intermediate node for a match.
>  		 */
>  		node = blk->bp->b_addr;
> -		dp->d_ops->node_hdr_from_disk(&nodehdr, node);
> +		xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr, node);
>  		btree = dp->d_ops->node_tree_p(node);
>  
>  		/* Tree taller than we can handle; bail out! */
> @@ -1678,8 +1700,8 @@ xfs_da3_node_order(
>  
>  	node1 = node1_bp->b_addr;
>  	node2 = node2_bp->b_addr;
> -	dp->d_ops->node_hdr_from_disk(&node1hdr, node1);
> -	dp->d_ops->node_hdr_from_disk(&node2hdr, node2);
> +	xfs_da3_node_hdr_from_disk(dp->i_mount, &node1hdr, node1);
> +	xfs_da3_node_hdr_from_disk(dp->i_mount, &node2hdr, node2);
>  	btree1 = dp->d_ops->node_tree_p(node1);
>  	btree2 = dp->d_ops->node_tree_p(node2);
>  
> @@ -1902,7 +1924,7 @@ xfs_da3_path_shift(
>  	level = (path->active-1) - 1;	/* skip bottom layer in path */
>  	for (blk = &path->blk[level]; level >= 0; blk--, level--) {
>  		node = blk->bp->b_addr;
> -		dp->d_ops->node_hdr_from_disk(&nodehdr, node);
> +		xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr, node);
>  		btree = dp->d_ops->node_tree_p(node);
>  
>  		if (forward && (blk->index < nodehdr.count - 1)) {
> @@ -1963,7 +1985,7 @@ xfs_da3_path_shift(
>  		case XFS_DA3_NODE_MAGIC:
>  			blk->magic = XFS_DA_NODE_MAGIC;
>  			node = (xfs_da_intnode_t *)info;
> -			dp->d_ops->node_hdr_from_disk(&nodehdr, node);
> +			xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr, node);
>  			btree = dp->d_ops->node_tree_p(node);
>  			blk->hashval = be32_to_cpu(btree[nodehdr.count - 1].hashval);
>  			if (forward)
> @@ -2248,7 +2270,7 @@ xfs_da3_swap_lastblock(
>  		struct xfs_da3_icnode_hdr deadhdr;
>  
>  		dead_node = (xfs_da_intnode_t *)dead_info;
> -		dp->d_ops->node_hdr_from_disk(&deadhdr, dead_node);
> +		xfs_da3_node_hdr_from_disk(dp->i_mount, &deadhdr, dead_node);
>  		btree = dp->d_ops->node_tree_p(dead_node);
>  		dead_level = deadhdr.level;
>  		dead_hash = be32_to_cpu(btree[deadhdr.count - 1].hashval);
> @@ -2308,7 +2330,7 @@ xfs_da3_swap_lastblock(
>  		if (error)
>  			goto done;
>  		par_node = par_buf->b_addr;
> -		dp->d_ops->node_hdr_from_disk(&par_hdr, par_node);
> +		xfs_da3_node_hdr_from_disk(dp->i_mount, &par_hdr, par_node);
>  		if (level >= 0 && level != par_hdr.level + 1) {
>  			XFS_ERROR_REPORT("xfs_da_swap_lastblock(4)",
>  					 XFS_ERRLEVEL_LOW, mp);
> @@ -2359,7 +2381,7 @@ xfs_da3_swap_lastblock(
>  		if (error)
>  			goto done;
>  		par_node = par_buf->b_addr;
> -		dp->d_ops->node_hdr_from_disk(&par_hdr, par_node);
> +		xfs_da3_node_hdr_from_disk(dp->i_mount, &par_hdr, par_node);
>  		if (par_hdr.level != level) {
>  			XFS_ERROR_REPORT("xfs_da_swap_lastblock(7)",
>  					 XFS_ERRLEVEL_LOW, mp);
> diff --git a/fs/xfs/libxfs/xfs_da_btree.h b/fs/xfs/libxfs/xfs_da_btree.h
> index 02f7a21ab3a5..eb15b9e76bc8 100644
> --- a/fs/xfs/libxfs/xfs_da_btree.h
> +++ b/fs/xfs/libxfs/xfs_da_btree.h
> @@ -215,6 +215,9 @@ enum xfs_dacmp xfs_da_compname(struct xfs_da_args *args,
>  xfs_da_state_t *xfs_da_state_alloc(void);
>  void xfs_da_state_free(xfs_da_state_t *state);
>  
> +void	xfs_da3_node_hdr_from_disk(struct xfs_mount *mp,
> +		struct xfs_da3_icnode_hdr *to, struct xfs_da_intnode *from);
> +
>  extern struct kmem_zone *xfs_da_state_zone;
>  extern const struct xfs_nameops xfs_default_nameops;
>  
> diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c
> index 31bb250c1899..267aca857126 100644
> --- a/fs/xfs/libxfs/xfs_da_format.c
> +++ b/fs/xfs/libxfs/xfs_da_format.c
> @@ -510,19 +510,6 @@ xfs_da3_node_tree_p(struct xfs_da_intnode *dap)
>  	return ((struct xfs_da3_intnode *)dap)->__btree;
>  }
>  
> -static void
> -xfs_da2_node_hdr_from_disk(
> -	struct xfs_da3_icnode_hdr	*to,
> -	struct xfs_da_intnode		*from)
> -{
> -	ASSERT(from->hdr.info.magic == cpu_to_be16(XFS_DA_NODE_MAGIC));
> -	to->forw = be32_to_cpu(from->hdr.info.forw);
> -	to->back = be32_to_cpu(from->hdr.info.back);
> -	to->magic = be16_to_cpu(from->hdr.info.magic);
> -	to->count = be16_to_cpu(from->hdr.__count);
> -	to->level = be16_to_cpu(from->hdr.__level);
> -}
> -
>  static void
>  xfs_da2_node_hdr_to_disk(
>  	struct xfs_da_intnode		*to,
> @@ -536,21 +523,6 @@ xfs_da2_node_hdr_to_disk(
>  	to->hdr.__level = cpu_to_be16(from->level);
>  }
>  
> -static void
> -xfs_da3_node_hdr_from_disk(
> -	struct xfs_da3_icnode_hdr	*to,
> -	struct xfs_da_intnode		*from)
> -{
> -	struct xfs_da3_node_hdr *hdr3 = (struct xfs_da3_node_hdr *)from;
> -
> -	ASSERT(from->hdr.info.magic == cpu_to_be16(XFS_DA3_NODE_MAGIC));
> -	to->forw = be32_to_cpu(hdr3->info.hdr.forw);
> -	to->back = be32_to_cpu(hdr3->info.hdr.back);
> -	to->magic = be16_to_cpu(hdr3->info.hdr.magic);
> -	to->count = be16_to_cpu(hdr3->__count);
> -	to->level = be16_to_cpu(hdr3->__level);
> -}
> -
>  static void
>  xfs_da3_node_hdr_to_disk(
>  	struct xfs_da_intnode		*to,
> @@ -727,7 +699,6 @@ static const struct xfs_dir_ops xfs_dir2_ops = {
>  
>  	.node_hdr_size = sizeof(struct xfs_da_node_hdr),
>  	.node_hdr_to_disk = xfs_da2_node_hdr_to_disk,
> -	.node_hdr_from_disk = xfs_da2_node_hdr_from_disk,
>  	.node_tree_p = xfs_da2_node_tree_p,
>  
>  	.free_hdr_size = sizeof(struct xfs_dir2_free_hdr),
> @@ -777,7 +748,6 @@ static const struct xfs_dir_ops xfs_dir2_ftype_ops = {
>  
>  	.node_hdr_size = sizeof(struct xfs_da_node_hdr),
>  	.node_hdr_to_disk = xfs_da2_node_hdr_to_disk,
> -	.node_hdr_from_disk = xfs_da2_node_hdr_from_disk,
>  	.node_tree_p = xfs_da2_node_tree_p,
>  
>  	.free_hdr_size = sizeof(struct xfs_dir2_free_hdr),
> @@ -827,7 +797,6 @@ static const struct xfs_dir_ops xfs_dir3_ops = {
>  
>  	.node_hdr_size = sizeof(struct xfs_da3_node_hdr),
>  	.node_hdr_to_disk = xfs_da3_node_hdr_to_disk,
> -	.node_hdr_from_disk = xfs_da3_node_hdr_from_disk,
>  	.node_tree_p = xfs_da3_node_tree_p,
>  
>  	.free_hdr_size = sizeof(struct xfs_dir3_free_hdr),
> @@ -842,14 +811,12 @@ static const struct xfs_dir_ops xfs_dir3_ops = {
>  static const struct xfs_dir_ops xfs_dir2_nondir_ops = {
>  	.node_hdr_size = sizeof(struct xfs_da_node_hdr),
>  	.node_hdr_to_disk = xfs_da2_node_hdr_to_disk,
> -	.node_hdr_from_disk = xfs_da2_node_hdr_from_disk,
>  	.node_tree_p = xfs_da2_node_tree_p,
>  };
>  
>  static const struct xfs_dir_ops xfs_dir3_nondir_ops = {
>  	.node_hdr_size = sizeof(struct xfs_da3_node_hdr),
>  	.node_hdr_to_disk = xfs_da3_node_hdr_to_disk,
> -	.node_hdr_from_disk = xfs_da3_node_hdr_from_disk,
>  	.node_tree_p = xfs_da3_node_tree_p,
>  };
>  
> diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h
> index e170792c0acc..573043f59c85 100644
> --- a/fs/xfs/libxfs/xfs_dir2.h
> +++ b/fs/xfs/libxfs/xfs_dir2.h
> @@ -84,8 +84,6 @@ struct xfs_dir_ops {
>  	int	node_hdr_size;
>  	void	(*node_hdr_to_disk)(struct xfs_da_intnode *to,
>  				    struct xfs_da3_icnode_hdr *from);
> -	void	(*node_hdr_from_disk)(struct xfs_da3_icnode_hdr *to,
> -				      struct xfs_da_intnode *from);
>  	struct xfs_da_node_entry *
>  		(*node_tree_p)(struct xfs_da_intnode *dap);
>  
> diff --git a/fs/xfs/scrub/dabtree.c b/fs/xfs/scrub/dabtree.c
> index d1248c223c7f..be19a48716b7 100644
> --- a/fs/xfs/scrub/dabtree.c
> +++ b/fs/xfs/scrub/dabtree.c
> @@ -410,7 +410,7 @@ xchk_da_btree_block(
>  				XFS_BLFT_DA_NODE_BUF);
>  		blk->magic = XFS_DA_NODE_MAGIC;
>  		node = blk->bp->b_addr;
> -		ip->d_ops->node_hdr_from_disk(&nodehdr, node);
> +		xfs_da3_node_hdr_from_disk(ip->i_mount, &nodehdr, node);
>  		btree = ip->d_ops->node_tree_p(node);
>  		*pmaxrecs = nodehdr.count;
>  		blk->hashval = be32_to_cpu(btree[*pmaxrecs - 1].hashval);
> diff --git a/fs/xfs/xfs_attr_inactive.c b/fs/xfs/xfs_attr_inactive.c
> index f83f11d929e4..c1ce06ccfab0 100644
> --- a/fs/xfs/xfs_attr_inactive.c
> +++ b/fs/xfs/xfs_attr_inactive.c
> @@ -213,7 +213,7 @@ xfs_attr3_node_inactive(
>  	}
>  
>  	node = bp->b_addr;
> -	dp->d_ops->node_hdr_from_disk(&ichdr, node);
> +	xfs_da3_node_hdr_from_disk(dp->i_mount, &ichdr, node);
>  	parent_blkno = bp->b_bn;
>  	if (!ichdr.count) {
>  		xfs_trans_brelse(*trans, bp);
> diff --git a/fs/xfs/xfs_attr_list.c b/fs/xfs/xfs_attr_list.c
> index c02f22d50e45..5b5a3772ed24 100644
> --- a/fs/xfs/xfs_attr_list.c
> +++ b/fs/xfs/xfs_attr_list.c
> @@ -240,7 +240,7 @@ xfs_attr_node_list_lookup(
>  			goto out_corruptbuf;
>  		}
>  
> -		dp->d_ops->node_hdr_from_disk(&nodehdr, node);
> +		xfs_da3_node_hdr_from_disk(mp, &nodehdr, node);
>  
>  		/* Tree taller than we can handle; bail out! */
>  		if (nodehdr.level >= XFS_DA_NODE_MAXDEPTH)
> -- 
> 2.20.1
> 

^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH 04/34] xfs: devirtualize ->node_hdr_to_disk
  2019-11-01 22:06 ` [PATCH 04/34] xfs: devirtualize ->node_hdr_to_disk Christoph Hellwig
@ 2019-11-04 18:39   ` Darrick J. Wong
  0 siblings, 0 replies; 81+ messages in thread
From: Darrick J. Wong @ 2019-11-04 18:39 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-xfs

On Fri, Nov 01, 2019 at 03:06:49PM -0700, Christoph Hellwig wrote:
> Replace the ->node_hdr_to_disk dir ops method with a directly called
> xfs_da_node_hdr_to_disk helper that takes care of the v4 vs v5
> difference.
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>

Nice substitution here too,
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>

--D

> ---
>  fs/xfs/libxfs/xfs_attr_leaf.c |  2 +-
>  fs/xfs/libxfs/xfs_da_btree.c  | 39 ++++++++++++++++++++++++++++-------
>  fs/xfs/libxfs/xfs_da_btree.h  |  2 ++
>  fs/xfs/libxfs/xfs_da_format.c | 34 ------------------------------
>  fs/xfs/libxfs/xfs_dir2.h      |  2 --
>  5 files changed, 35 insertions(+), 44 deletions(-)
> 
> diff --git a/fs/xfs/libxfs/xfs_attr_leaf.c b/fs/xfs/libxfs/xfs_attr_leaf.c
> index 131fef677896..1b0fbee21e14 100644
> --- a/fs/xfs/libxfs/xfs_attr_leaf.c
> +++ b/fs/xfs/libxfs/xfs_attr_leaf.c
> @@ -1196,7 +1196,7 @@ xfs_attr3_leaf_to_node(
>  	btree[0].hashval = entries[icleafhdr.count - 1].hashval;
>  	btree[0].before = cpu_to_be32(blkno);
>  	icnodehdr.count = 1;
> -	dp->d_ops->node_hdr_to_disk(node, &icnodehdr);
> +	xfs_da3_node_hdr_to_disk(dp->i_mount, node, &icnodehdr);
>  	xfs_trans_log_buf(args->trans, bp1, 0, args->geo->blksize - 1);
>  	error = 0;
>  out:
> diff --git a/fs/xfs/libxfs/xfs_da_btree.c b/fs/xfs/libxfs/xfs_da_btree.c
> index f7ddc91ed099..462a245fdad7 100644
> --- a/fs/xfs/libxfs/xfs_da_btree.c
> +++ b/fs/xfs/libxfs/xfs_da_btree.c
> @@ -135,6 +135,31 @@ xfs_da3_node_hdr_from_disk(
>  	}
>  }
>  
> +void
> +xfs_da3_node_hdr_to_disk(
> +	struct xfs_mount		*mp,
> +	struct xfs_da_intnode		*to,
> +	struct xfs_da3_icnode_hdr	*from)
> +{
> +	if (xfs_sb_version_hascrc(&mp->m_sb)) {
> +		struct xfs_da3_intnode	*to3 = (struct xfs_da3_intnode *)to;
> +
> +		ASSERT(from->magic == XFS_DA3_NODE_MAGIC);
> +		to3->hdr.info.hdr.forw = cpu_to_be32(from->forw);
> +		to3->hdr.info.hdr.back = cpu_to_be32(from->back);
> +		to3->hdr.info.hdr.magic = cpu_to_be16(from->magic);
> +		to3->hdr.__count = cpu_to_be16(from->count);
> +		to3->hdr.__level = cpu_to_be16(from->level);
> +	} else {
> +		ASSERT(from->magic == XFS_DA_NODE_MAGIC);
> +		to->hdr.info.forw = cpu_to_be32(from->forw);
> +		to->hdr.info.back = cpu_to_be32(from->back);
> +		to->hdr.info.magic = cpu_to_be16(from->magic);
> +		to->hdr.__count = cpu_to_be16(from->count);
> +		to->hdr.__level = cpu_to_be16(from->level);
> +	}
> +}
> +
>  /*
>   * Verify an xfs_da3_blkinfo structure. Note that the da3 fields are only
>   * accessible on v5 filesystems. This header format is common across da node,
> @@ -385,7 +410,7 @@ xfs_da3_node_create(
>  	}
>  	ichdr.level = level;
>  
> -	dp->d_ops->node_hdr_to_disk(node, &ichdr);
> +	xfs_da3_node_hdr_to_disk(dp->i_mount, node, &ichdr);
>  	xfs_trans_log_buf(tp, bp,
>  		XFS_DA_LOGRANGE(node, &node->hdr, dp->d_ops->node_hdr_size));
>  
> @@ -666,7 +691,7 @@ xfs_da3_root_split(
>  	btree[1].hashval = cpu_to_be32(blk2->hashval);
>  	btree[1].before = cpu_to_be32(blk2->blkno);
>  	nodehdr.count = 2;
> -	dp->d_ops->node_hdr_to_disk(node, &nodehdr);
> +	xfs_da3_node_hdr_to_disk(dp->i_mount, node, &nodehdr);
>  
>  #ifdef DEBUG
>  	if (oldroot->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC) ||
> @@ -891,11 +916,11 @@ xfs_da3_node_rebalance(
>  	/*
>  	 * Log header of node 1 and all current bits of node 2.
>  	 */
> -	dp->d_ops->node_hdr_to_disk(node1, &nodehdr1);
> +	xfs_da3_node_hdr_to_disk(dp->i_mount, node1, &nodehdr1);
>  	xfs_trans_log_buf(tp, blk1->bp,
>  		XFS_DA_LOGRANGE(node1, &node1->hdr, dp->d_ops->node_hdr_size));
>  
> -	dp->d_ops->node_hdr_to_disk(node2, &nodehdr2);
> +	xfs_da3_node_hdr_to_disk(dp->i_mount, node2, &nodehdr2);
>  	xfs_trans_log_buf(tp, blk2->bp,
>  		XFS_DA_LOGRANGE(node2, &node2->hdr,
>  				dp->d_ops->node_hdr_size +
> @@ -967,7 +992,7 @@ xfs_da3_node_add(
>  				tmp + sizeof(*btree)));
>  
>  	nodehdr.count += 1;
> -	dp->d_ops->node_hdr_to_disk(node, &nodehdr);
> +	xfs_da3_node_hdr_to_disk(dp->i_mount, node, &nodehdr);
>  	xfs_trans_log_buf(state->args->trans, oldblk->bp,
>  		XFS_DA_LOGRANGE(node, &node->hdr, dp->d_ops->node_hdr_size));
>  
> @@ -1403,7 +1428,7 @@ xfs_da3_node_remove(
>  	xfs_trans_log_buf(state->args->trans, drop_blk->bp,
>  	    XFS_DA_LOGRANGE(node, &btree[index], sizeof(btree[index])));
>  	nodehdr.count -= 1;
> -	dp->d_ops->node_hdr_to_disk(node, &nodehdr);
> +	xfs_da3_node_hdr_to_disk(dp->i_mount, node, &nodehdr);
>  	xfs_trans_log_buf(state->args->trans, drop_blk->bp,
>  	    XFS_DA_LOGRANGE(node, &node->hdr, dp->d_ops->node_hdr_size));
>  
> @@ -1475,7 +1500,7 @@ xfs_da3_node_unbalance(
>  	memcpy(&save_btree[sindex], &drop_btree[0], tmp);
>  	save_hdr.count += drop_hdr.count;
>  
> -	dp->d_ops->node_hdr_to_disk(save_node, &save_hdr);
> +	xfs_da3_node_hdr_to_disk(dp->i_mount, save_node, &save_hdr);
>  	xfs_trans_log_buf(tp, save_blk->bp,
>  		XFS_DA_LOGRANGE(save_node, &save_node->hdr,
>  				dp->d_ops->node_hdr_size));
> diff --git a/fs/xfs/libxfs/xfs_da_btree.h b/fs/xfs/libxfs/xfs_da_btree.h
> index eb15b9e76bc8..69ebf6a50d85 100644
> --- a/fs/xfs/libxfs/xfs_da_btree.h
> +++ b/fs/xfs/libxfs/xfs_da_btree.h
> @@ -217,6 +217,8 @@ void xfs_da_state_free(xfs_da_state_t *state);
>  
>  void	xfs_da3_node_hdr_from_disk(struct xfs_mount *mp,
>  		struct xfs_da3_icnode_hdr *to, struct xfs_da_intnode *from);
> +void	xfs_da3_node_hdr_to_disk(struct xfs_mount *mp,
> +		struct xfs_da_intnode *to, struct xfs_da3_icnode_hdr *from);
>  
>  extern struct kmem_zone *xfs_da_state_zone;
>  extern const struct xfs_nameops xfs_default_nameops;
> diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c
> index 267aca857126..912096416a86 100644
> --- a/fs/xfs/libxfs/xfs_da_format.c
> +++ b/fs/xfs/libxfs/xfs_da_format.c
> @@ -510,35 +510,6 @@ xfs_da3_node_tree_p(struct xfs_da_intnode *dap)
>  	return ((struct xfs_da3_intnode *)dap)->__btree;
>  }
>  
> -static void
> -xfs_da2_node_hdr_to_disk(
> -	struct xfs_da_intnode		*to,
> -	struct xfs_da3_icnode_hdr	*from)
> -{
> -	ASSERT(from->magic == XFS_DA_NODE_MAGIC);
> -	to->hdr.info.forw = cpu_to_be32(from->forw);
> -	to->hdr.info.back = cpu_to_be32(from->back);
> -	to->hdr.info.magic = cpu_to_be16(from->magic);
> -	to->hdr.__count = cpu_to_be16(from->count);
> -	to->hdr.__level = cpu_to_be16(from->level);
> -}
> -
> -static void
> -xfs_da3_node_hdr_to_disk(
> -	struct xfs_da_intnode		*to,
> -	struct xfs_da3_icnode_hdr	*from)
> -{
> -	struct xfs_da3_node_hdr *hdr3 = (struct xfs_da3_node_hdr *)to;
> -
> -	ASSERT(from->magic == XFS_DA3_NODE_MAGIC);
> -	hdr3->info.hdr.forw = cpu_to_be32(from->forw);
> -	hdr3->info.hdr.back = cpu_to_be32(from->back);
> -	hdr3->info.hdr.magic = cpu_to_be16(from->magic);
> -	hdr3->__count = cpu_to_be16(from->count);
> -	hdr3->__level = cpu_to_be16(from->level);
> -}
> -
> -
>  /*
>   * Directory free space block operations
>   */
> @@ -698,7 +669,6 @@ static const struct xfs_dir_ops xfs_dir2_ops = {
>  	.leaf_ents_p = xfs_dir2_leaf_ents_p,
>  
>  	.node_hdr_size = sizeof(struct xfs_da_node_hdr),
> -	.node_hdr_to_disk = xfs_da2_node_hdr_to_disk,
>  	.node_tree_p = xfs_da2_node_tree_p,
>  
>  	.free_hdr_size = sizeof(struct xfs_dir2_free_hdr),
> @@ -747,7 +717,6 @@ static const struct xfs_dir_ops xfs_dir2_ftype_ops = {
>  	.leaf_ents_p = xfs_dir2_leaf_ents_p,
>  
>  	.node_hdr_size = sizeof(struct xfs_da_node_hdr),
> -	.node_hdr_to_disk = xfs_da2_node_hdr_to_disk,
>  	.node_tree_p = xfs_da2_node_tree_p,
>  
>  	.free_hdr_size = sizeof(struct xfs_dir2_free_hdr),
> @@ -796,7 +765,6 @@ static const struct xfs_dir_ops xfs_dir3_ops = {
>  	.leaf_ents_p = xfs_dir3_leaf_ents_p,
>  
>  	.node_hdr_size = sizeof(struct xfs_da3_node_hdr),
> -	.node_hdr_to_disk = xfs_da3_node_hdr_to_disk,
>  	.node_tree_p = xfs_da3_node_tree_p,
>  
>  	.free_hdr_size = sizeof(struct xfs_dir3_free_hdr),
> @@ -810,13 +778,11 @@ static const struct xfs_dir_ops xfs_dir3_ops = {
>  
>  static const struct xfs_dir_ops xfs_dir2_nondir_ops = {
>  	.node_hdr_size = sizeof(struct xfs_da_node_hdr),
> -	.node_hdr_to_disk = xfs_da2_node_hdr_to_disk,
>  	.node_tree_p = xfs_da2_node_tree_p,
>  };
>  
>  static const struct xfs_dir_ops xfs_dir3_nondir_ops = {
>  	.node_hdr_size = sizeof(struct xfs_da3_node_hdr),
> -	.node_hdr_to_disk = xfs_da3_node_hdr_to_disk,
>  	.node_tree_p = xfs_da3_node_tree_p,
>  };
>  
> diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h
> index 573043f59c85..c16efeae0f2b 100644
> --- a/fs/xfs/libxfs/xfs_dir2.h
> +++ b/fs/xfs/libxfs/xfs_dir2.h
> @@ -82,8 +82,6 @@ struct xfs_dir_ops {
>  		(*leaf_ents_p)(struct xfs_dir2_leaf *lp);
>  
>  	int	node_hdr_size;
> -	void	(*node_hdr_to_disk)(struct xfs_da_intnode *to,
> -				    struct xfs_da3_icnode_hdr *from);
>  	struct xfs_da_node_entry *
>  		(*node_tree_p)(struct xfs_da_intnode *dap);
>  
> -- 
> 2.20.1
> 

^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH 05/34] xfs: add a btree entries pointer to struct xfs_da3_icnode_hdr
  2019-11-01 22:06 ` [PATCH 05/34] xfs: add a btree entries pointer to struct xfs_da3_icnode_hdr Christoph Hellwig
@ 2019-11-04 19:52   ` Darrick J. Wong
  2019-11-05  1:38     ` Christoph Hellwig
  0 siblings, 1 reply; 81+ messages in thread
From: Darrick J. Wong @ 2019-11-04 19:52 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-xfs

On Fri, Nov 01, 2019 at 03:06:50PM -0700, Christoph Hellwig wrote:
> All but two callers of the ->node_tree_p dir operation already have a
> xfs_da3_icnode_hdr from a previous call to xfs_da3_node_hdr_from_disk at
> hand.  Add a pointer to the btree entries to struct xfs_da3_icnode_hdr
> to clean up this pattern.  The two remaining callers now expand the
> whole header as well, but that isn't very expensive and not in a super
> hot path anyway.
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
>  fs/xfs/libxfs/xfs_attr_leaf.c |  6 ++--
>  fs/xfs/libxfs/xfs_da_btree.c  | 68 ++++++++++++++++-------------------
>  fs/xfs/libxfs/xfs_da_btree.h  |  1 +
>  fs/xfs/libxfs/xfs_da_format.c | 21 -----------
>  fs/xfs/libxfs/xfs_dir2.h      |  2 --
>  fs/xfs/scrub/dabtree.c        |  6 ++--
>  fs/xfs/xfs_attr_inactive.c    | 34 +++++++++---------
>  fs/xfs/xfs_attr_list.c        |  2 +-
>  8 files changed, 55 insertions(+), 85 deletions(-)
> 

<snip>

> diff --git a/fs/xfs/libxfs/xfs_da_btree.h b/fs/xfs/libxfs/xfs_da_btree.h
> index 69ebf6a50d85..63ed45057fa5 100644
> --- a/fs/xfs/libxfs/xfs_da_btree.h
> +++ b/fs/xfs/libxfs/xfs_da_btree.h
> @@ -135,6 +135,7 @@ struct xfs_da3_icnode_hdr {
>  	uint16_t		magic;
>  	uint16_t		count;
>  	uint16_t		level;
> +	struct xfs_da_node_entry *btree;

This adds to the incore node header structure a pointer to raw disk
structures, right?  Can we make this a little more explicit by naming
the field "raw_entries" or something?

--D

>  };
>  
>  /*
> diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c
> index 912096416a86..f896d37c845f 100644
> --- a/fs/xfs/libxfs/xfs_da_format.c
> +++ b/fs/xfs/libxfs/xfs_da_format.c
> @@ -494,22 +494,6 @@ xfs_dir3_leaf_hdr_to_disk(
>  	hdr3->stale = cpu_to_be16(from->stale);
>  }
>  
> -
> -/*
> - * Directory/Attribute Node block operations
> - */
> -static struct xfs_da_node_entry *
> -xfs_da2_node_tree_p(struct xfs_da_intnode *dap)
> -{
> -	return dap->__btree;
> -}
> -
> -static struct xfs_da_node_entry *
> -xfs_da3_node_tree_p(struct xfs_da_intnode *dap)
> -{
> -	return ((struct xfs_da3_intnode *)dap)->__btree;
> -}
> -
>  /*
>   * Directory free space block operations
>   */
> @@ -669,7 +653,6 @@ static const struct xfs_dir_ops xfs_dir2_ops = {
>  	.leaf_ents_p = xfs_dir2_leaf_ents_p,
>  
>  	.node_hdr_size = sizeof(struct xfs_da_node_hdr),
> -	.node_tree_p = xfs_da2_node_tree_p,
>  
>  	.free_hdr_size = sizeof(struct xfs_dir2_free_hdr),
>  	.free_hdr_to_disk = xfs_dir2_free_hdr_to_disk,
> @@ -717,7 +700,6 @@ static const struct xfs_dir_ops xfs_dir2_ftype_ops = {
>  	.leaf_ents_p = xfs_dir2_leaf_ents_p,
>  
>  	.node_hdr_size = sizeof(struct xfs_da_node_hdr),
> -	.node_tree_p = xfs_da2_node_tree_p,
>  
>  	.free_hdr_size = sizeof(struct xfs_dir2_free_hdr),
>  	.free_hdr_to_disk = xfs_dir2_free_hdr_to_disk,
> @@ -765,7 +747,6 @@ static const struct xfs_dir_ops xfs_dir3_ops = {
>  	.leaf_ents_p = xfs_dir3_leaf_ents_p,
>  
>  	.node_hdr_size = sizeof(struct xfs_da3_node_hdr),
> -	.node_tree_p = xfs_da3_node_tree_p,
>  
>  	.free_hdr_size = sizeof(struct xfs_dir3_free_hdr),
>  	.free_hdr_to_disk = xfs_dir3_free_hdr_to_disk,
> @@ -778,12 +759,10 @@ static const struct xfs_dir_ops xfs_dir3_ops = {
>  
>  static const struct xfs_dir_ops xfs_dir2_nondir_ops = {
>  	.node_hdr_size = sizeof(struct xfs_da_node_hdr),
> -	.node_tree_p = xfs_da2_node_tree_p,
>  };
>  
>  static const struct xfs_dir_ops xfs_dir3_nondir_ops = {
>  	.node_hdr_size = sizeof(struct xfs_da3_node_hdr),
> -	.node_tree_p = xfs_da3_node_tree_p,
>  };
>  
>  /*
> diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h
> index c16efeae0f2b..6eee4c1b20da 100644
> --- a/fs/xfs/libxfs/xfs_dir2.h
> +++ b/fs/xfs/libxfs/xfs_dir2.h
> @@ -82,8 +82,6 @@ struct xfs_dir_ops {
>  		(*leaf_ents_p)(struct xfs_dir2_leaf *lp);
>  
>  	int	node_hdr_size;
> -	struct xfs_da_node_entry *
> -		(*node_tree_p)(struct xfs_da_intnode *dap);
>  
>  	int	free_hdr_size;
>  	void	(*free_hdr_to_disk)(struct xfs_dir2_free *to,
> diff --git a/fs/xfs/scrub/dabtree.c b/fs/xfs/scrub/dabtree.c
> index be19a48716b7..52aa69743dfa 100644
> --- a/fs/xfs/scrub/dabtree.c
> +++ b/fs/xfs/scrub/dabtree.c
> @@ -83,10 +83,12 @@ xchk_da_btree_node_entry(
>  	int				level)
>  {
>  	struct xfs_da_state_blk		*blk = &ds->state->path.blk[level];
> +	struct xfs_da3_icnode_hdr	hdr;
>  
>  	ASSERT(blk->magic == XFS_DA_NODE_MAGIC);
>  
> -	return (void *)ds->dargs.dp->d_ops->node_tree_p(blk->bp->b_addr) +
> +	xfs_da3_node_hdr_from_disk(ds->sc->mp, &hdr, blk->bp->b_addr);
> +	return (void *)hdr.btree +
>  		(blk->index * sizeof(struct xfs_da_node_entry));
>  }
>  
> @@ -411,7 +413,7 @@ xchk_da_btree_block(
>  		blk->magic = XFS_DA_NODE_MAGIC;
>  		node = blk->bp->b_addr;
>  		xfs_da3_node_hdr_from_disk(ip->i_mount, &nodehdr, node);
> -		btree = ip->d_ops->node_tree_p(node);
> +		btree = nodehdr.btree;
>  		*pmaxrecs = nodehdr.count;
>  		blk->hashval = be32_to_cpu(btree[*pmaxrecs - 1].hashval);
>  		if (level == 0) {
> diff --git a/fs/xfs/xfs_attr_inactive.c b/fs/xfs/xfs_attr_inactive.c
> index c1ce06ccfab0..f6d8967f0a8e 100644
> --- a/fs/xfs/xfs_attr_inactive.c
> +++ b/fs/xfs/xfs_attr_inactive.c
> @@ -190,19 +190,17 @@ xfs_attr3_leaf_inactive(
>   */
>  STATIC int
>  xfs_attr3_node_inactive(
> -	struct xfs_trans **trans,
> -	struct xfs_inode *dp,
> -	struct xfs_buf	*bp,
> -	int		level)
> +	struct xfs_trans	**trans,
> +	struct xfs_inode	*dp,
> +	struct xfs_buf		*bp,
> +	int			level)
>  {
> -	xfs_da_blkinfo_t *info;
> -	xfs_da_intnode_t *node;
> -	xfs_dablk_t child_fsb;
> -	xfs_daddr_t parent_blkno, child_blkno;
> -	int error, i;
> -	struct xfs_buf *child_bp;
> -	struct xfs_da_node_entry *btree;
> +	struct xfs_da_blkinfo	*info;
> +	xfs_dablk_t		child_fsb;
> +	xfs_daddr_t		parent_blkno, child_blkno;
> +	struct xfs_buf		*child_bp;
>  	struct xfs_da3_icnode_hdr ichdr;
> +	int			error, i;
>  
>  	/*
>  	 * Since this code is recursive (gasp!) we must protect ourselves.
> @@ -212,15 +210,13 @@ xfs_attr3_node_inactive(
>  		return -EFSCORRUPTED;
>  	}
>  
> -	node = bp->b_addr;
> -	xfs_da3_node_hdr_from_disk(dp->i_mount, &ichdr, node);
> +	xfs_da3_node_hdr_from_disk(dp->i_mount, &ichdr, bp->b_addr);
>  	parent_blkno = bp->b_bn;
>  	if (!ichdr.count) {
>  		xfs_trans_brelse(*trans, bp);
>  		return 0;
>  	}
> -	btree = dp->d_ops->node_tree_p(node);
> -	child_fsb = be32_to_cpu(btree[0].before);
> +	child_fsb = be32_to_cpu(ichdr.btree[0].before);
>  	xfs_trans_brelse(*trans, bp);	/* no locks for later trans */
>  
>  	/*
> @@ -279,13 +275,15 @@ xfs_attr3_node_inactive(
>  		 * child block number.
>  		 */
>  		if (i + 1 < ichdr.count) {
> +			struct xfs_da3_icnode_hdr phdr;
> +
>  			error = xfs_da3_node_read(*trans, dp, 0, parent_blkno,
>  						 &bp, XFS_ATTR_FORK);
>  			if (error)
>  				return error;
> -			node = bp->b_addr;
> -			btree = dp->d_ops->node_tree_p(node);
> -			child_fsb = be32_to_cpu(btree[i + 1].before);
> +			xfs_da3_node_hdr_from_disk(dp->i_mount, &phdr,
> +						  bp->b_addr);
> +			child_fsb = be32_to_cpu(phdr.btree[i + 1].before);
>  			xfs_trans_brelse(*trans, bp);
>  		}
>  		/*
> diff --git a/fs/xfs/xfs_attr_list.c b/fs/xfs/xfs_attr_list.c
> index 5b5a3772ed24..032920952aa2 100644
> --- a/fs/xfs/xfs_attr_list.c
> +++ b/fs/xfs/xfs_attr_list.c
> @@ -254,7 +254,7 @@ xfs_attr_node_list_lookup(
>  		else
>  			expected_level--;
>  
> -		btree = dp->d_ops->node_tree_p(node);
> +		btree = nodehdr.btree;
>  		for (i = 0; i < nodehdr.count; btree++, i++) {
>  			if (cursor->hashval <= be32_to_cpu(btree->hashval)) {
>  				cursor->blkno = be32_to_cpu(btree->before);
> -- 
> 2.20.1
> 

^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH 06/34] xfs: move the node header size to struct xfs_da_geometry
  2019-11-01 22:06 ` [PATCH 06/34] xfs: move the node header size to struct xfs_da_geometry Christoph Hellwig
@ 2019-11-04 19:58   ` Darrick J. Wong
  0 siblings, 0 replies; 81+ messages in thread
From: Darrick J. Wong @ 2019-11-04 19:58 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-xfs

On Fri, Nov 01, 2019 at 03:06:51PM -0700, Christoph Hellwig wrote:
> Move the node header size field to struct xfs_da_geometry, and remove
> the now unused non-directory dir ops infrastructure.
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>

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

--D

> ---
>  fs/xfs/libxfs/xfs_da_btree.c  | 14 ++++++++------
>  fs/xfs/libxfs/xfs_da_btree.h  |  1 +
>  fs/xfs/libxfs/xfs_da_format.c | 28 ----------------------------
>  fs/xfs/libxfs/xfs_dir2.c      | 12 +++++++-----
>  fs/xfs/libxfs/xfs_dir2.h      |  4 ----
>  fs/xfs/xfs_iops.c             |  1 -
>  fs/xfs/xfs_mount.h            |  1 -
>  7 files changed, 16 insertions(+), 45 deletions(-)
> 
> diff --git a/fs/xfs/libxfs/xfs_da_btree.c b/fs/xfs/libxfs/xfs_da_btree.c
> index d8f062343bab..26ad79d96205 100644
> --- a/fs/xfs/libxfs/xfs_da_btree.c
> +++ b/fs/xfs/libxfs/xfs_da_btree.c
> @@ -414,7 +414,7 @@ xfs_da3_node_create(
>  
>  	xfs_da3_node_hdr_to_disk(dp->i_mount, node, &ichdr);
>  	xfs_trans_log_buf(tp, bp,
> -		XFS_DA_LOGRANGE(node, &node->hdr, dp->d_ops->node_hdr_size));
> +		XFS_DA_LOGRANGE(node, &node->hdr, args->geo->node_hdr_size));
>  
>  	*bpp = bp;
>  	return 0;
> @@ -920,12 +920,13 @@ xfs_da3_node_rebalance(
>  	 */
>  	xfs_da3_node_hdr_to_disk(dp->i_mount, node1, &nodehdr1);
>  	xfs_trans_log_buf(tp, blk1->bp,
> -		XFS_DA_LOGRANGE(node1, &node1->hdr, dp->d_ops->node_hdr_size));
> +		XFS_DA_LOGRANGE(node1, &node1->hdr,
> +				state->args->geo->node_hdr_size));
>  
>  	xfs_da3_node_hdr_to_disk(dp->i_mount, node2, &nodehdr2);
>  	xfs_trans_log_buf(tp, blk2->bp,
>  		XFS_DA_LOGRANGE(node2, &node2->hdr,
> -				dp->d_ops->node_hdr_size +
> +				state->args->geo->node_hdr_size +
>  				(sizeof(btree2[0]) * nodehdr2.count)));
>  
>  	/*
> @@ -996,7 +997,8 @@ xfs_da3_node_add(
>  	nodehdr.count += 1;
>  	xfs_da3_node_hdr_to_disk(dp->i_mount, node, &nodehdr);
>  	xfs_trans_log_buf(state->args->trans, oldblk->bp,
> -		XFS_DA_LOGRANGE(node, &node->hdr, dp->d_ops->node_hdr_size));
> +		XFS_DA_LOGRANGE(node, &node->hdr,
> +				state->args->geo->node_hdr_size));
>  
>  	/*
>  	 * Copy the last hash value from the oldblk to propagate upwards.
> @@ -1426,7 +1428,7 @@ xfs_da3_node_remove(
>  	nodehdr.count -= 1;
>  	xfs_da3_node_hdr_to_disk(dp->i_mount, node, &nodehdr);
>  	xfs_trans_log_buf(state->args->trans, drop_blk->bp,
> -	    XFS_DA_LOGRANGE(node, &node->hdr, dp->d_ops->node_hdr_size));
> +	    XFS_DA_LOGRANGE(node, &node->hdr, state->args->geo->node_hdr_size));
>  
>  	/*
>  	 * Copy the last hash value from the block to propagate upwards.
> @@ -1499,7 +1501,7 @@ xfs_da3_node_unbalance(
>  	xfs_da3_node_hdr_to_disk(dp->i_mount, save_node, &save_hdr);
>  	xfs_trans_log_buf(tp, save_blk->bp,
>  		XFS_DA_LOGRANGE(save_node, &save_node->hdr,
> -				dp->d_ops->node_hdr_size));
> +				state->args->geo->node_hdr_size));
>  
>  	/*
>  	 * Save the last hashval in the remaining block for upward propagation.
> diff --git a/fs/xfs/libxfs/xfs_da_btree.h b/fs/xfs/libxfs/xfs_da_btree.h
> index 63ed45057fa5..11b2d75f83ad 100644
> --- a/fs/xfs/libxfs/xfs_da_btree.h
> +++ b/fs/xfs/libxfs/xfs_da_btree.h
> @@ -22,6 +22,7 @@ struct xfs_da_geometry {
>  	int		fsbcount;	/* da block size in filesystem blocks */
>  	uint8_t		fsblog;		/* log2 of _filesystem_ block size */
>  	uint8_t		blklog;		/* log2 of da block size */
> +	int		node_hdr_size;	/* danode header size in bytes */
>  	uint		node_ents;	/* # of entries in a danode */
>  	int		magicpct;	/* 37% of block size in bytes */
>  	xfs_dablk_t	datablk;	/* blockno of dir data v2 */
> diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c
> index f896d37c845f..68dff1de61e9 100644
> --- a/fs/xfs/libxfs/xfs_da_format.c
> +++ b/fs/xfs/libxfs/xfs_da_format.c
> @@ -652,8 +652,6 @@ static const struct xfs_dir_ops xfs_dir2_ops = {
>  	.leaf_max_ents = xfs_dir2_max_leaf_ents,
>  	.leaf_ents_p = xfs_dir2_leaf_ents_p,
>  
> -	.node_hdr_size = sizeof(struct xfs_da_node_hdr),
> -
>  	.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,
> @@ -699,8 +697,6 @@ static const struct xfs_dir_ops xfs_dir2_ftype_ops = {
>  	.leaf_max_ents = xfs_dir2_max_leaf_ents,
>  	.leaf_ents_p = xfs_dir2_leaf_ents_p,
>  
> -	.node_hdr_size = sizeof(struct xfs_da_node_hdr),
> -
>  	.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,
> @@ -746,8 +742,6 @@ static const struct xfs_dir_ops xfs_dir3_ops = {
>  	.leaf_max_ents = xfs_dir3_max_leaf_ents,
>  	.leaf_ents_p = xfs_dir3_leaf_ents_p,
>  
> -	.node_hdr_size = sizeof(struct xfs_da3_node_hdr),
> -
>  	.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,
> @@ -757,14 +751,6 @@ static const struct xfs_dir_ops xfs_dir3_ops = {
>  	.db_to_fdindex = xfs_dir3_db_to_fdindex,
>  };
>  
> -static const struct xfs_dir_ops xfs_dir2_nondir_ops = {
> -	.node_hdr_size = sizeof(struct xfs_da_node_hdr),
> -};
> -
> -static const struct xfs_dir_ops xfs_dir3_nondir_ops = {
> -	.node_hdr_size = sizeof(struct xfs_da3_node_hdr),
> -};
> -
>  /*
>   * Return the ops structure according to the current config.  If we are passed
>   * an inode, then that overrides the default config we use which is based on
> @@ -785,17 +771,3 @@ xfs_dir_get_ops(
>  		return &xfs_dir2_ftype_ops;
>  	return &xfs_dir2_ops;
>  }
> -
> -const struct xfs_dir_ops *
> -xfs_nondir_get_ops(
> -	struct xfs_mount	*mp,
> -	struct xfs_inode	*dp)
> -{
> -	if (dp)
> -		return dp->d_ops;
> -	if (mp->m_nondir_inode_ops)
> -		return mp->m_nondir_inode_ops;
> -	if (xfs_sb_version_hascrc(&mp->m_sb))
> -		return &xfs_dir3_nondir_ops;
> -	return &xfs_dir2_nondir_ops;
> -}
> diff --git a/fs/xfs/libxfs/xfs_dir2.c b/fs/xfs/libxfs/xfs_dir2.c
> index 867c5dee0751..aef20ec6e140 100644
> --- a/fs/xfs/libxfs/xfs_dir2.c
> +++ b/fs/xfs/libxfs/xfs_dir2.c
> @@ -99,16 +99,13 @@ xfs_da_mount(
>  	struct xfs_mount	*mp)
>  {
>  	struct xfs_da_geometry	*dageo;
> -	int			nodehdr_size;
>  
>  
>  	ASSERT(mp->m_sb.sb_versionnum & XFS_SB_VERSION_DIRV2BIT);
>  	ASSERT(xfs_dir2_dirblock_bytes(&mp->m_sb) <= XFS_MAX_BLOCKSIZE);
>  
>  	mp->m_dir_inode_ops = xfs_dir_get_ops(mp, NULL);
> -	mp->m_nondir_inode_ops = xfs_nondir_get_ops(mp, NULL);
>  
> -	nodehdr_size = mp->m_dir_inode_ops->node_hdr_size;
>  	mp->m_dir_geo = kmem_zalloc(sizeof(struct xfs_da_geometry),
>  				    KM_MAYFAIL);
>  	mp->m_attr_geo = kmem_zalloc(sizeof(struct xfs_da_geometry),
> @@ -125,6 +122,10 @@ xfs_da_mount(
>  	dageo->fsblog = mp->m_sb.sb_blocklog;
>  	dageo->blksize = xfs_dir2_dirblock_bytes(&mp->m_sb);
>  	dageo->fsbcount = 1 << mp->m_sb.sb_dirblklog;
> +	if (xfs_sb_version_hascrc(&mp->m_sb))
> +		dageo->node_hdr_size = sizeof(struct xfs_da3_node_hdr);
> +	else
> +		dageo->node_hdr_size = sizeof(struct xfs_da_node_hdr);
>  
>  	/*
>  	 * Now we've set up the block conversion variables, we can calculate the
> @@ -133,7 +134,7 @@ xfs_da_mount(
>  	dageo->datablk = xfs_dir2_byte_to_da(dageo, XFS_DIR2_DATA_OFFSET);
>  	dageo->leafblk = xfs_dir2_byte_to_da(dageo, XFS_DIR2_LEAF_OFFSET);
>  	dageo->freeblk = xfs_dir2_byte_to_da(dageo, XFS_DIR2_FREE_OFFSET);
> -	dageo->node_ents = (dageo->blksize - nodehdr_size) /
> +	dageo->node_ents = (dageo->blksize - dageo->node_hdr_size) /
>  				(uint)sizeof(xfs_da_node_entry_t);
>  	dageo->magicpct = (dageo->blksize * 37) / 100;
>  
> @@ -143,7 +144,8 @@ xfs_da_mount(
>  	dageo->fsblog = mp->m_sb.sb_blocklog;
>  	dageo->blksize = 1 << dageo->blklog;
>  	dageo->fsbcount = 1;
> -	dageo->node_ents = (dageo->blksize - nodehdr_size) /
> +	dageo->node_hdr_size = mp->m_dir_geo->node_hdr_size;
> +	dageo->node_ents = (dageo->blksize - dageo->node_hdr_size) /
>  				(uint)sizeof(xfs_da_node_entry_t);
>  	dageo->magicpct = (dageo->blksize * 37) / 100;
>  
> diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h
> index 6eee4c1b20da..87fe876e90ed 100644
> --- a/fs/xfs/libxfs/xfs_dir2.h
> +++ b/fs/xfs/libxfs/xfs_dir2.h
> @@ -81,8 +81,6 @@ struct xfs_dir_ops {
>  	struct xfs_dir2_leaf_entry *
>  		(*leaf_ents_p)(struct xfs_dir2_leaf *lp);
>  
> -	int	node_hdr_size;
> -
>  	int	free_hdr_size;
>  	void	(*free_hdr_to_disk)(struct xfs_dir2_free *to,
>  				    struct xfs_dir3_icfree_hdr *from);
> @@ -98,8 +96,6 @@ struct xfs_dir_ops {
>  
>  extern const struct xfs_dir_ops *
>  	xfs_dir_get_ops(struct xfs_mount *mp, struct xfs_inode *dp);
> -extern const struct xfs_dir_ops *
> -	xfs_nondir_get_ops(struct xfs_mount *mp, struct xfs_inode *dp);
>  
>  /*
>   * Generic directory interface routines
> diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c
> index 18e45e3a3f9f..40d4495e013c 100644
> --- a/fs/xfs/xfs_iops.c
> +++ b/fs/xfs/xfs_iops.c
> @@ -1319,7 +1319,6 @@ xfs_setup_inode(
>  		lockdep_set_class(&ip->i_lock.mr_lock, &xfs_dir_ilock_class);
>  		ip->d_ops = ip->i_mount->m_dir_inode_ops;
>  	} else {
> -		ip->d_ops = ip->i_mount->m_nondir_inode_ops;
>  		lockdep_set_class(&ip->i_lock.mr_lock, &xfs_nondir_ilock_class);
>  	}
>  
> diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
> index a46cb3fd24b1..3ddc5f4d1053 100644
> --- a/fs/xfs/xfs_mount.h
> +++ b/fs/xfs/xfs_mount.h
> @@ -159,7 +159,6 @@ typedef struct xfs_mount {
>  	uint8_t			m_sectbb_log;	/* sectlog - BBSHIFT */
>  	const struct xfs_nameops *m_dirnameops;	/* vector of dir name ops */
>  	const struct xfs_dir_ops *m_dir_inode_ops; /* vector of dir inode ops */
> -	const struct xfs_dir_ops *m_nondir_inode_ops; /* !dir inode ops */
>  	uint			m_chsize;	/* size of next field */
>  	atomic_t		m_active_trans;	/* number trans frozen */
>  	struct xfs_mru_cache	*m_filestream;  /* per-mount filestream data */
> -- 
> 2.20.1
> 

^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH 07/34] xfs: devirtualize ->leaf_hdr_from_disk
  2019-11-01 22:06 ` [PATCH 07/34] xfs: devirtualize ->leaf_hdr_from_disk Christoph Hellwig
@ 2019-11-04 19:59   ` Darrick J. Wong
  0 siblings, 0 replies; 81+ messages in thread
From: Darrick J. Wong @ 2019-11-04 19:59 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-xfs

On Fri, Nov 01, 2019 at 03:06:52PM -0700, Christoph Hellwig wrote:
> Replace the ->leaf_hdr_from_disk dir ops method with a directly called
> xfs_dir2_leaf_hdr_from_disk helper that takes care of the differences
> between the v4 and v5 on-disk format.
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>

Mmmm nice cleanup,
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>

--D

> ---
>  fs/xfs/libxfs/xfs_da_btree.c   |  5 ++--
>  fs/xfs/libxfs/xfs_da_format.c  | 35 --------------------------
>  fs/xfs/libxfs/xfs_dir2.h       |  2 --
>  fs/xfs/libxfs/xfs_dir2_block.c |  2 +-
>  fs/xfs/libxfs/xfs_dir2_leaf.c  | 45 ++++++++++++++++++++++++++++------
>  fs/xfs/libxfs/xfs_dir2_node.c  | 28 ++++++++++-----------
>  fs/xfs/libxfs/xfs_dir2_priv.h  |  2 ++
>  fs/xfs/scrub/dir.c             |  2 +-
>  8 files changed, 58 insertions(+), 63 deletions(-)
> 
> diff --git a/fs/xfs/libxfs/xfs_da_btree.c b/fs/xfs/libxfs/xfs_da_btree.c
> index 26ad79d96205..aeb1884fd8c7 100644
> --- a/fs/xfs/libxfs/xfs_da_btree.c
> +++ b/fs/xfs/libxfs/xfs_da_btree.c
> @@ -641,7 +641,7 @@ xfs_da3_root_split(
>  		struct xfs_dir2_leaf_entry *ents;
>  
>  		leaf = (xfs_dir2_leaf_t *)oldroot;
> -		dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf);
> +		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 ||
> @@ -2283,7 +2283,8 @@ xfs_da3_swap_lastblock(
>  		struct xfs_dir2_leaf_entry *ents;
>  
>  		dead_leaf2 = (xfs_dir2_leaf_t *)dead_info;
> -		dp->d_ops->leaf_hdr_from_disk(&leafhdr, dead_leaf2);
> +		xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &leafhdr,
> +					    dead_leaf2);
>  		ents = dp->d_ops->leaf_ents_p(dead_leaf2);
>  		dead_level = 0;
>  		dead_hash = be32_to_cpu(ents[leafhdr.count - 1].hashval);
> diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c
> index 68dff1de61e9..c848cab41be5 100644
> --- a/fs/xfs/libxfs/xfs_da_format.c
> +++ b/fs/xfs/libxfs/xfs_da_format.c
> @@ -430,21 +430,6 @@ xfs_dir3_leaf_ents_p(struct xfs_dir2_leaf *lp)
>  	return ((struct xfs_dir3_leaf *)lp)->__ents;
>  }
>  
> -static void
> -xfs_dir2_leaf_hdr_from_disk(
> -	struct xfs_dir3_icleaf_hdr	*to,
> -	struct xfs_dir2_leaf		*from)
> -{
> -	to->forw = be32_to_cpu(from->hdr.info.forw);
> -	to->back = be32_to_cpu(from->hdr.info.back);
> -	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);
> -
> -	ASSERT(to->magic == XFS_DIR2_LEAF1_MAGIC ||
> -	       to->magic == XFS_DIR2_LEAFN_MAGIC);
> -}
> -
>  static void
>  xfs_dir2_leaf_hdr_to_disk(
>  	struct xfs_dir2_leaf		*to,
> @@ -460,23 +445,6 @@ xfs_dir2_leaf_hdr_to_disk(
>  	to->hdr.stale = cpu_to_be16(from->stale);
>  }
>  
> -static void
> -xfs_dir3_leaf_hdr_from_disk(
> -	struct xfs_dir3_icleaf_hdr	*to,
> -	struct xfs_dir2_leaf		*from)
> -{
> -	struct xfs_dir3_leaf_hdr *hdr3 = (struct xfs_dir3_leaf_hdr *)from;
> -
> -	to->forw = be32_to_cpu(hdr3->info.hdr.forw);
> -	to->back = be32_to_cpu(hdr3->info.hdr.back);
> -	to->magic = be16_to_cpu(hdr3->info.hdr.magic);
> -	to->count = be16_to_cpu(hdr3->count);
> -	to->stale = be16_to_cpu(hdr3->stale);
> -
> -	ASSERT(to->magic == XFS_DIR3_LEAF1_MAGIC ||
> -	       to->magic == XFS_DIR3_LEAFN_MAGIC);
> -}
> -
>  static void
>  xfs_dir3_leaf_hdr_to_disk(
>  	struct xfs_dir2_leaf		*to,
> @@ -648,7 +616,6 @@ static const struct xfs_dir_ops xfs_dir2_ops = {
>  
>  	.leaf_hdr_size = sizeof(struct xfs_dir2_leaf_hdr),
>  	.leaf_hdr_to_disk = xfs_dir2_leaf_hdr_to_disk,
> -	.leaf_hdr_from_disk = xfs_dir2_leaf_hdr_from_disk,
>  	.leaf_max_ents = xfs_dir2_max_leaf_ents,
>  	.leaf_ents_p = xfs_dir2_leaf_ents_p,
>  
> @@ -693,7 +660,6 @@ static const struct xfs_dir_ops xfs_dir2_ftype_ops = {
>  
>  	.leaf_hdr_size = sizeof(struct xfs_dir2_leaf_hdr),
>  	.leaf_hdr_to_disk = xfs_dir2_leaf_hdr_to_disk,
> -	.leaf_hdr_from_disk = xfs_dir2_leaf_hdr_from_disk,
>  	.leaf_max_ents = xfs_dir2_max_leaf_ents,
>  	.leaf_ents_p = xfs_dir2_leaf_ents_p,
>  
> @@ -738,7 +704,6 @@ static const struct xfs_dir_ops xfs_dir3_ops = {
>  
>  	.leaf_hdr_size = sizeof(struct xfs_dir3_leaf_hdr),
>  	.leaf_hdr_to_disk = xfs_dir3_leaf_hdr_to_disk,
> -	.leaf_hdr_from_disk = xfs_dir3_leaf_hdr_from_disk,
>  	.leaf_max_ents = xfs_dir3_max_leaf_ents,
>  	.leaf_ents_p = xfs_dir3_leaf_ents_p,
>  
> diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h
> index 87fe876e90ed..74c592496bf0 100644
> --- a/fs/xfs/libxfs/xfs_dir2.h
> +++ b/fs/xfs/libxfs/xfs_dir2.h
> @@ -75,8 +75,6 @@ struct xfs_dir_ops {
>  	int	leaf_hdr_size;
>  	void	(*leaf_hdr_to_disk)(struct xfs_dir2_leaf *to,
>  				    struct xfs_dir3_icleaf_hdr *from);
> -	void	(*leaf_hdr_from_disk)(struct xfs_dir3_icleaf_hdr *to,
> -				      struct xfs_dir2_leaf *from);
>  	int	(*leaf_max_ents)(struct xfs_da_geometry *geo);
>  	struct xfs_dir2_leaf_entry *
>  		(*leaf_ents_p)(struct xfs_dir2_leaf *lp);
> diff --git a/fs/xfs/libxfs/xfs_dir2_block.c b/fs/xfs/libxfs/xfs_dir2_block.c
> index 49e4bc39e7bb..e6ed90a6f19b 100644
> --- a/fs/xfs/libxfs/xfs_dir2_block.c
> +++ b/fs/xfs/libxfs/xfs_dir2_block.c
> @@ -923,7 +923,7 @@ xfs_dir2_leaf_to_block(
>  	tp = args->trans;
>  	mp = dp->i_mount;
>  	leaf = lbp->b_addr;
> -	dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf);
> +	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);
>  
> diff --git a/fs/xfs/libxfs/xfs_dir2_leaf.c b/fs/xfs/libxfs/xfs_dir2_leaf.c
> index a53e4585a2f3..137ffd0a538b 100644
> --- a/fs/xfs/libxfs/xfs_dir2_leaf.c
> +++ b/fs/xfs/libxfs/xfs_dir2_leaf.c
> @@ -30,6 +30,35 @@ static void xfs_dir3_leaf_log_bests(struct xfs_da_args *args,
>  static void xfs_dir3_leaf_log_tail(struct xfs_da_args *args,
>  				   struct xfs_buf *bp);
>  
> +void
> +xfs_dir2_leaf_hdr_from_disk(
> +	struct xfs_mount		*mp,
> +	struct xfs_dir3_icleaf_hdr	*to,
> +	struct xfs_dir2_leaf		*from)
> +{
> +	if (xfs_sb_version_hascrc(&mp->m_sb)) {
> +		struct xfs_dir3_leaf *from3 = (struct xfs_dir3_leaf *)from;
> +
> +		to->forw = be32_to_cpu(from3->hdr.info.hdr.forw);
> +		to->back = be32_to_cpu(from3->hdr.info.hdr.back);
> +		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);
> +
> +		ASSERT(to->magic == XFS_DIR3_LEAF1_MAGIC ||
> +		       to->magic == XFS_DIR3_LEAFN_MAGIC);
> +	} else {
> +		to->forw = be32_to_cpu(from->hdr.info.forw);
> +		to->back = be32_to_cpu(from->hdr.info.back);
> +		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);
> +
> +		ASSERT(to->magic == XFS_DIR2_LEAF1_MAGIC ||
> +		       to->magic == XFS_DIR2_LEAFN_MAGIC);
> +	}
> +}
> +
>  /*
>   * Check the internal consistency of a leaf1 block.
>   * Pop an assert if something is wrong.
> @@ -43,7 +72,7 @@ xfs_dir3_leaf1_check(
>  	struct xfs_dir2_leaf	*leaf = bp->b_addr;
>  	struct xfs_dir3_icleaf_hdr leafhdr;
>  
> -	dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf);
> +	xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &leafhdr, leaf);
>  
>  	if (leafhdr.magic == XFS_DIR3_LEAF1_MAGIC) {
>  		struct xfs_dir3_leaf_hdr *leaf3 = bp->b_addr;
> @@ -96,7 +125,7 @@ xfs_dir3_leaf_check_int(
>  	ops = xfs_dir_get_ops(mp, dp);
>  
>  	if (!hdr) {
> -		ops->leaf_hdr_from_disk(&leafhdr, leaf);
> +		xfs_dir2_leaf_hdr_from_disk(mp, &leafhdr, leaf);
>  		hdr = &leafhdr;
>  	}
>  
> @@ -381,7 +410,7 @@ xfs_dir2_block_to_leaf(
>  	/*
>  	 * Set the counts in the leaf header.
>  	 */
> -	dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf);
> +	xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &leafhdr, leaf);
>  	leafhdr.count = be32_to_cpu(btp->count);
>  	leafhdr.stale = be32_to_cpu(btp->stale);
>  	dp->d_ops->leaf_hdr_to_disk(leaf, &leafhdr);
> @@ -608,7 +637,7 @@ xfs_dir2_leaf_addname(
>  	leaf = lbp->b_addr;
>  	ltp = xfs_dir2_leaf_tail_p(args->geo, leaf);
>  	ents = dp->d_ops->leaf_ents_p(leaf);
> -	dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf);
> +	xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &leafhdr, leaf);
>  	bestsp = xfs_dir2_leaf_bests_p(ltp);
>  	length = dp->d_ops->data_entsize(args->namelen);
>  
> @@ -1197,7 +1226,7 @@ xfs_dir2_leaf_lookup_int(
>  	leaf = lbp->b_addr;
>  	xfs_dir3_leaf_check(dp, lbp);
>  	ents = dp->d_ops->leaf_ents_p(leaf);
> -	dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf);
> +	xfs_dir2_leaf_hdr_from_disk(mp, &leafhdr, leaf);
>  
>  	/*
>  	 * Look for the first leaf entry with our hash value.
> @@ -1330,7 +1359,7 @@ xfs_dir2_leaf_removename(
>  	hdr = dbp->b_addr;
>  	xfs_dir3_data_check(dp, dbp);
>  	bf = dp->d_ops->data_bestfree_p(hdr);
> -	dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf);
> +	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.
> @@ -1509,7 +1538,7 @@ xfs_dir2_leaf_search_hash(
>  
>  	leaf = lbp->b_addr;
>  	ents = args->dp->d_ops->leaf_ents_p(leaf);
> -	args->dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf);
> +	xfs_dir2_leaf_hdr_from_disk(args->dp->i_mount, &leafhdr, leaf);
>  
>  	/*
>  	 * Note, the table cannot be empty, so we have to go through the loop.
> @@ -1697,7 +1726,7 @@ xfs_dir2_node_to_leaf(
>  		return 0;
>  	lbp = state->path.blk[0].bp;
>  	leaf = lbp->b_addr;
> -	dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf);
> +	xfs_dir2_leaf_hdr_from_disk(mp, &leafhdr, leaf);
>  
>  	ASSERT(leafhdr.magic == XFS_DIR2_LEAFN_MAGIC ||
>  	       leafhdr.magic == XFS_DIR3_LEAFN_MAGIC);
> diff --git a/fs/xfs/libxfs/xfs_dir2_node.c b/fs/xfs/libxfs/xfs_dir2_node.c
> index 705c4f562758..736a3ea2b92c 100644
> --- a/fs/xfs/libxfs/xfs_dir2_node.c
> +++ b/fs/xfs/libxfs/xfs_dir2_node.c
> @@ -45,7 +45,7 @@ xfs_dir3_leafn_check(
>  	struct xfs_dir2_leaf	*leaf = bp->b_addr;
>  	struct xfs_dir3_icleaf_hdr leafhdr;
>  
> -	dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf);
> +	xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &leafhdr, leaf);
>  
>  	if (leafhdr.magic == XFS_DIR3_LEAFN_MAGIC) {
>  		struct xfs_dir3_leaf_hdr *leaf3 = bp->b_addr;
> @@ -438,7 +438,7 @@ xfs_dir2_leafn_add(
>  
>  	trace_xfs_dir2_leafn_add(args, index);
>  
> -	dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf);
> +	xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &leafhdr, leaf);
>  	ents = dp->d_ops->leaf_ents_p(leaf);
>  
>  	/*
> @@ -534,7 +534,7 @@ xfs_dir2_leaf_lasthash(
>  	struct xfs_dir2_leaf_entry *ents;
>  	struct xfs_dir3_icleaf_hdr leafhdr;
>  
> -	dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf);
> +	xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &leafhdr, leaf);
>  
>  	ASSERT(leafhdr.magic == XFS_DIR2_LEAFN_MAGIC ||
>  	       leafhdr.magic == XFS_DIR3_LEAFN_MAGIC ||
> @@ -583,7 +583,7 @@ xfs_dir2_leafn_lookup_for_addname(
>  	tp = args->trans;
>  	mp = dp->i_mount;
>  	leaf = bp->b_addr;
> -	dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf);
> +	xfs_dir2_leaf_hdr_from_disk(mp, &leafhdr, leaf);
>  	ents = dp->d_ops->leaf_ents_p(leaf);
>  
>  	xfs_dir3_leaf_check(dp, bp);
> @@ -735,7 +735,7 @@ xfs_dir2_leafn_lookup_for_entry(
>  	tp = args->trans;
>  	mp = dp->i_mount;
>  	leaf = bp->b_addr;
> -	dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf);
> +	xfs_dir2_leaf_hdr_from_disk(mp, &leafhdr, leaf);
>  	ents = dp->d_ops->leaf_ents_p(leaf);
>  
>  	xfs_dir3_leaf_check(dp, bp);
> @@ -971,8 +971,8 @@ xfs_dir2_leafn_order(
>  	struct xfs_dir3_icleaf_hdr hdr1;
>  	struct xfs_dir3_icleaf_hdr hdr2;
>  
> -	dp->d_ops->leaf_hdr_from_disk(&hdr1, leaf1);
> -	dp->d_ops->leaf_hdr_from_disk(&hdr2, leaf2);
> +	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);
>  
> @@ -1024,8 +1024,8 @@ xfs_dir2_leafn_rebalance(
>  
>  	leaf1 = blk1->bp->b_addr;
>  	leaf2 = blk2->bp->b_addr;
> -	dp->d_ops->leaf_hdr_from_disk(&hdr1, leaf1);
> -	dp->d_ops->leaf_hdr_from_disk(&hdr2, leaf2);
> +	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);
>  
> @@ -1222,7 +1222,7 @@ xfs_dir2_leafn_remove(
>  	dp = args->dp;
>  	tp = args->trans;
>  	leaf = bp->b_addr;
> -	dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf);
> +	xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &leafhdr, leaf);
>  	ents = dp->d_ops->leaf_ents_p(leaf);
>  
>  	/*
> @@ -1444,7 +1444,7 @@ xfs_dir2_leafn_toosmall(
>  	 */
>  	blk = &state->path.blk[state->path.active - 1];
>  	leaf = blk->bp->b_addr;
> -	dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf);
> +	xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &leafhdr, leaf);
>  	ents = dp->d_ops->leaf_ents_p(leaf);
>  	xfs_dir3_leaf_check(dp, blk->bp);
>  
> @@ -1507,7 +1507,7 @@ xfs_dir2_leafn_toosmall(
>  			(state->args->geo->blksize >> 2);
>  
>  		leaf = bp->b_addr;
> -		dp->d_ops->leaf_hdr_from_disk(&hdr2, leaf);
> +		xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &hdr2, leaf);
>  		ents = dp->d_ops->leaf_ents_p(leaf);
>  		count += hdr2.count - hdr2.stale;
>  		bytes -= count * sizeof(ents[0]);
> @@ -1570,8 +1570,8 @@ xfs_dir2_leafn_unbalance(
>  	drop_leaf = drop_blk->bp->b_addr;
>  	save_leaf = save_blk->bp->b_addr;
>  
> -	dp->d_ops->leaf_hdr_from_disk(&savehdr, save_leaf);
> -	dp->d_ops->leaf_hdr_from_disk(&drophdr, drop_leaf);
> +	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);
>  
> diff --git a/fs/xfs/libxfs/xfs_dir2_priv.h b/fs/xfs/libxfs/xfs_dir2_priv.h
> index 973b1527b7ba..434bb60c718c 100644
> --- a/fs/xfs/libxfs/xfs_dir2_priv.h
> +++ b/fs/xfs/libxfs/xfs_dir2_priv.h
> @@ -67,6 +67,8 @@ extern int xfs_dir3_data_init(struct xfs_da_args *args, xfs_dir2_db_t blkno,
>  		struct xfs_buf **bpp);
>  
>  /* xfs_dir2_leaf.c */
> +void xfs_dir2_leaf_hdr_from_disk(struct xfs_mount *mp,
> +		struct xfs_dir3_icleaf_hdr *to, struct xfs_dir2_leaf *from);
>  extern int xfs_dir3_leaf_read(struct xfs_trans *tp, struct xfs_inode *dp,
>  		xfs_dablk_t fbno, xfs_daddr_t mappedbno, struct xfs_buf **bpp);
>  extern int xfs_dir3_leafn_read(struct xfs_trans *tp, struct xfs_inode *dp,
> diff --git a/fs/xfs/scrub/dir.c b/fs/xfs/scrub/dir.c
> index 97f274f7cd38..5b004d1f6bef 100644
> --- a/fs/xfs/scrub/dir.c
> +++ b/fs/xfs/scrub/dir.c
> @@ -504,7 +504,7 @@ xchk_directory_leaf1_bestfree(
>  	xchk_buffer_recheck(sc, bp);
>  
>  	leaf = bp->b_addr;
> -	d_ops->leaf_hdr_from_disk(&leafhdr, leaf);
> +	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);
> -- 
> 2.20.1
> 

^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH 08/34] xfs: devirtualize ->leaf_hdr_to_disk
  2019-11-01 22:06 ` [PATCH 08/34] xfs: devirtualize ->leaf_hdr_to_disk Christoph Hellwig
@ 2019-11-04 20:00   ` Darrick J. Wong
  0 siblings, 0 replies; 81+ messages in thread
From: Darrick J. Wong @ 2019-11-04 20:00 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-xfs

On Fri, Nov 01, 2019 at 03:06:53PM -0700, Christoph Hellwig wrote:
> Replace the ->leaf_hdr_to_disk dir ops method with a directly called
> xfs_dir_leaf_hdr_to_disk helper that takes care of the differences
> between the v4 and v5 on-disk format.
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>

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

--D

> ---
>  fs/xfs/libxfs/xfs_da_format.c | 35 -------------------------------
>  fs/xfs/libxfs/xfs_dir2.h      |  2 --
>  fs/xfs/libxfs/xfs_dir2_leaf.c | 39 ++++++++++++++++++++++++++++++-----
>  fs/xfs/libxfs/xfs_dir2_node.c | 12 +++++------
>  fs/xfs/libxfs/xfs_dir2_priv.h |  2 ++
>  5 files changed, 42 insertions(+), 48 deletions(-)
> 
> diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c
> index c848cab41be5..193708d12459 100644
> --- a/fs/xfs/libxfs/xfs_da_format.c
> +++ b/fs/xfs/libxfs/xfs_da_format.c
> @@ -430,38 +430,6 @@ xfs_dir3_leaf_ents_p(struct xfs_dir2_leaf *lp)
>  	return ((struct xfs_dir3_leaf *)lp)->__ents;
>  }
>  
> -static void
> -xfs_dir2_leaf_hdr_to_disk(
> -	struct xfs_dir2_leaf		*to,
> -	struct xfs_dir3_icleaf_hdr	*from)
> -{
> -	ASSERT(from->magic == XFS_DIR2_LEAF1_MAGIC ||
> -	       from->magic == XFS_DIR2_LEAFN_MAGIC);
> -
> -	to->hdr.info.forw = cpu_to_be32(from->forw);
> -	to->hdr.info.back = cpu_to_be32(from->back);
> -	to->hdr.info.magic = cpu_to_be16(from->magic);
> -	to->hdr.count = cpu_to_be16(from->count);
> -	to->hdr.stale = cpu_to_be16(from->stale);
> -}
> -
> -static void
> -xfs_dir3_leaf_hdr_to_disk(
> -	struct xfs_dir2_leaf		*to,
> -	struct xfs_dir3_icleaf_hdr	*from)
> -{
> -	struct xfs_dir3_leaf_hdr *hdr3 = (struct xfs_dir3_leaf_hdr *)to;
> -
> -	ASSERT(from->magic == XFS_DIR3_LEAF1_MAGIC ||
> -	       from->magic == XFS_DIR3_LEAFN_MAGIC);
> -
> -	hdr3->info.hdr.forw = cpu_to_be32(from->forw);
> -	hdr3->info.hdr.back = cpu_to_be32(from->back);
> -	hdr3->info.hdr.magic = cpu_to_be16(from->magic);
> -	hdr3->count = cpu_to_be16(from->count);
> -	hdr3->stale = cpu_to_be16(from->stale);
> -}
> -
>  /*
>   * Directory free space block operations
>   */
> @@ -615,7 +583,6 @@ static const struct xfs_dir_ops xfs_dir2_ops = {
>  	.data_unused_p = xfs_dir2_data_unused_p,
>  
>  	.leaf_hdr_size = sizeof(struct xfs_dir2_leaf_hdr),
> -	.leaf_hdr_to_disk = xfs_dir2_leaf_hdr_to_disk,
>  	.leaf_max_ents = xfs_dir2_max_leaf_ents,
>  	.leaf_ents_p = xfs_dir2_leaf_ents_p,
>  
> @@ -659,7 +626,6 @@ static const struct xfs_dir_ops xfs_dir2_ftype_ops = {
>  	.data_unused_p = xfs_dir2_data_unused_p,
>  
>  	.leaf_hdr_size = sizeof(struct xfs_dir2_leaf_hdr),
> -	.leaf_hdr_to_disk = xfs_dir2_leaf_hdr_to_disk,
>  	.leaf_max_ents = xfs_dir2_max_leaf_ents,
>  	.leaf_ents_p = xfs_dir2_leaf_ents_p,
>  
> @@ -703,7 +669,6 @@ static const struct xfs_dir_ops xfs_dir3_ops = {
>  	.data_unused_p = xfs_dir3_data_unused_p,
>  
>  	.leaf_hdr_size = sizeof(struct xfs_dir3_leaf_hdr),
> -	.leaf_hdr_to_disk = xfs_dir3_leaf_hdr_to_disk,
>  	.leaf_max_ents = xfs_dir3_max_leaf_ents,
>  	.leaf_ents_p = xfs_dir3_leaf_ents_p,
>  
> diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h
> index 74c592496bf0..15a1a72dc126 100644
> --- a/fs/xfs/libxfs/xfs_dir2.h
> +++ b/fs/xfs/libxfs/xfs_dir2.h
> @@ -73,8 +73,6 @@ struct xfs_dir_ops {
>  		(*data_unused_p)(struct xfs_dir2_data_hdr *hdr);
>  
>  	int	leaf_hdr_size;
> -	void	(*leaf_hdr_to_disk)(struct xfs_dir2_leaf *to,
> -				    struct xfs_dir3_icleaf_hdr *from);
>  	int	(*leaf_max_ents)(struct xfs_da_geometry *geo);
>  	struct xfs_dir2_leaf_entry *
>  		(*leaf_ents_p)(struct xfs_dir2_leaf *lp);
> diff --git a/fs/xfs/libxfs/xfs_dir2_leaf.c b/fs/xfs/libxfs/xfs_dir2_leaf.c
> index 137ffd0a538b..56aae0b4cf89 100644
> --- a/fs/xfs/libxfs/xfs_dir2_leaf.c
> +++ b/fs/xfs/libxfs/xfs_dir2_leaf.c
> @@ -59,6 +59,35 @@ xfs_dir2_leaf_hdr_from_disk(
>  	}
>  }
>  
> +void
> +xfs_dir2_leaf_hdr_to_disk(
> +	struct xfs_mount		*mp,
> +	struct xfs_dir2_leaf		*to,
> +	struct xfs_dir3_icleaf_hdr	*from)
> +{
> +	if (xfs_sb_version_hascrc(&mp->m_sb)) {
> +		struct xfs_dir3_leaf *to3 = (struct xfs_dir3_leaf *)to;
> +
> +		ASSERT(from->magic == XFS_DIR3_LEAF1_MAGIC ||
> +		       from->magic == XFS_DIR3_LEAFN_MAGIC);
> +
> +		to3->hdr.info.hdr.forw = cpu_to_be32(from->forw);
> +		to3->hdr.info.hdr.back = cpu_to_be32(from->back);
> +		to3->hdr.info.hdr.magic = cpu_to_be16(from->magic);
> +		to3->hdr.count = cpu_to_be16(from->count);
> +		to3->hdr.stale = cpu_to_be16(from->stale);
> +	} else {
> +		ASSERT(from->magic == XFS_DIR2_LEAF1_MAGIC ||
> +		       from->magic == XFS_DIR2_LEAFN_MAGIC);
> +
> +		to->hdr.info.forw = cpu_to_be32(from->forw);
> +		to->hdr.info.back = cpu_to_be32(from->back);
> +		to->hdr.info.magic = cpu_to_be16(from->magic);
> +		to->hdr.count = cpu_to_be16(from->count);
> +		to->hdr.stale = cpu_to_be16(from->stale);
> +	}
> +}
> +
>  /*
>   * Check the internal consistency of a leaf1 block.
>   * Pop an assert if something is wrong.
> @@ -413,7 +442,7 @@ xfs_dir2_block_to_leaf(
>  	xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &leafhdr, leaf);
>  	leafhdr.count = be32_to_cpu(btp->count);
>  	leafhdr.stale = be32_to_cpu(btp->stale);
> -	dp->d_ops->leaf_hdr_to_disk(leaf, &leafhdr);
> +	xfs_dir2_leaf_hdr_to_disk(dp->i_mount, leaf, &leafhdr);
>  	xfs_dir3_leaf_log_header(args, lbp);
>  
>  	/*
> @@ -881,7 +910,7 @@ xfs_dir2_leaf_addname(
>  	/*
>  	 * Log the leaf fields and give up the buffers.
>  	 */
> -	dp->d_ops->leaf_hdr_to_disk(leaf, &leafhdr);
> +	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_check(dp, lbp);
> @@ -934,7 +963,7 @@ xfs_dir3_leaf_compact(
>  	leafhdr->count -= leafhdr->stale;
>  	leafhdr->stale = 0;
>  
> -	dp->d_ops->leaf_hdr_to_disk(leaf, leafhdr);
> +	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);
> @@ -1384,7 +1413,7 @@ xfs_dir2_leaf_removename(
>  	 * We just mark the leaf entry stale by putting a null in it.
>  	 */
>  	leafhdr.stale++;
> -	dp->d_ops->leaf_hdr_to_disk(leaf, &leafhdr);
> +	xfs_dir2_leaf_hdr_to_disk(dp->i_mount, leaf, &leafhdr);
>  	xfs_dir3_leaf_log_header(args, lbp);
>  
>  	lep->address = cpu_to_be32(XFS_DIR2_NULL_DATAPTR);
> @@ -1775,7 +1804,7 @@ xfs_dir2_node_to_leaf(
>  	memcpy(xfs_dir2_leaf_bests_p(ltp), dp->d_ops->free_bests_p(free),
>  		freehdr.nvalid * sizeof(xfs_dir2_data_off_t));
>  
> -	dp->d_ops->leaf_hdr_to_disk(leaf, &leafhdr);
> +	xfs_dir2_leaf_hdr_to_disk(mp, leaf, &leafhdr);
>  	xfs_dir3_leaf_log_header(args, lbp);
>  	xfs_dir3_leaf_log_bests(args, lbp, 0, be32_to_cpu(ltp->bestcount) - 1);
>  	xfs_dir3_leaf_log_tail(args, lbp);
> diff --git a/fs/xfs/libxfs/xfs_dir2_node.c b/fs/xfs/libxfs/xfs_dir2_node.c
> index 736a3ea2b92c..207ef9b4fe50 100644
> --- a/fs/xfs/libxfs/xfs_dir2_node.c
> +++ b/fs/xfs/libxfs/xfs_dir2_node.c
> @@ -493,7 +493,7 @@ xfs_dir2_leafn_add(
>  	lep->address = cpu_to_be32(xfs_dir2_db_off_to_dataptr(args->geo,
>  				args->blkno, args->index));
>  
> -	dp->d_ops->leaf_hdr_to_disk(leaf, &leafhdr);
> +	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_check(dp, bp);
> @@ -1073,8 +1073,8 @@ xfs_dir2_leafn_rebalance(
>  	ASSERT(hdr1.stale + hdr2.stale == oldstale);
>  
>  	/* log the changes made when moving the entries */
> -	dp->d_ops->leaf_hdr_to_disk(leaf1, &hdr1);
> -	dp->d_ops->leaf_hdr_to_disk(leaf2, &hdr2);
> +	xfs_dir2_leaf_hdr_to_disk(dp->i_mount, leaf1, &hdr1);
> +	xfs_dir2_leaf_hdr_to_disk(dp->i_mount, leaf2, &hdr2);
>  	xfs_dir3_leaf_log_header(args, blk1->bp);
>  	xfs_dir3_leaf_log_header(args, blk2->bp);
>  
> @@ -1243,7 +1243,7 @@ xfs_dir2_leafn_remove(
>  	 * Log the leaf block changes.
>  	 */
>  	leafhdr.stale++;
> -	dp->d_ops->leaf_hdr_to_disk(leaf, &leafhdr);
> +	xfs_dir2_leaf_hdr_to_disk(dp->i_mount, leaf, &leafhdr);
>  	xfs_dir3_leaf_log_header(args, bp);
>  
>  	lep->address = cpu_to_be32(XFS_DIR2_NULL_DATAPTR);
> @@ -1599,8 +1599,8 @@ xfs_dir2_leafn_unbalance(
>  	save_blk->hashval = be32_to_cpu(sents[savehdr.count - 1].hashval);
>  
>  	/* log the changes made when moving the entries */
> -	dp->d_ops->leaf_hdr_to_disk(save_leaf, &savehdr);
> -	dp->d_ops->leaf_hdr_to_disk(drop_leaf, &drophdr);
> +	xfs_dir2_leaf_hdr_to_disk(dp->i_mount, save_leaf, &savehdr);
> +	xfs_dir2_leaf_hdr_to_disk(dp->i_mount, drop_leaf, &drophdr);
>  	xfs_dir3_leaf_log_header(args, save_blk->bp);
>  	xfs_dir3_leaf_log_header(args, drop_blk->bp);
>  
> diff --git a/fs/xfs/libxfs/xfs_dir2_priv.h b/fs/xfs/libxfs/xfs_dir2_priv.h
> index 434bb60c718c..b402a2391f49 100644
> --- a/fs/xfs/libxfs/xfs_dir2_priv.h
> +++ b/fs/xfs/libxfs/xfs_dir2_priv.h
> @@ -69,6 +69,8 @@ extern int xfs_dir3_data_init(struct xfs_da_args *args, xfs_dir2_db_t blkno,
>  /* xfs_dir2_leaf.c */
>  void xfs_dir2_leaf_hdr_from_disk(struct xfs_mount *mp,
>  		struct xfs_dir3_icleaf_hdr *to, struct xfs_dir2_leaf *from);
> +void xfs_dir2_leaf_hdr_to_disk(struct xfs_mount *mp, struct xfs_dir2_leaf *to,
> +		struct xfs_dir3_icleaf_hdr *from);
>  extern int xfs_dir3_leaf_read(struct xfs_trans *tp, struct xfs_inode *dp,
>  		xfs_dablk_t fbno, xfs_daddr_t mappedbno, struct xfs_buf **bpp);
>  extern int xfs_dir3_leafn_read(struct xfs_trans *tp, struct xfs_inode *dp,
> -- 
> 2.20.1
> 

^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH 09/34] xfs: add a entries pointer to struct xfs_dir3_icleaf_hdr
  2019-11-01 22:06 ` [PATCH 09/34] xfs: add a entries pointer to struct xfs_dir3_icleaf_hdr Christoph Hellwig
@ 2019-11-04 20:04   ` Darrick J. Wong
  0 siblings, 0 replies; 81+ messages in thread
From: Darrick J. Wong @ 2019-11-04 20:04 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-xfs

On Fri, Nov 01, 2019 at 03:06:54PM -0700, 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@lst.de>

Mostly looks ok...

<snip>

> diff --git a/fs/xfs/libxfs/xfs_dir2_priv.h b/fs/xfs/libxfs/xfs_dir2_priv.h
> index b402a2391f49..07cea5751783 100644
> --- a/fs/xfs/libxfs/xfs_dir2_priv.h
> +++ b/fs/xfs/libxfs/xfs_dir2_priv.h
> @@ -18,6 +18,7 @@ struct xfs_dir3_icleaf_hdr {
>  	uint16_t		magic;
>  	uint16_t		count;
>  	uint16_t		stale;
> +	struct xfs_dir2_leaf_entry *ents;

...except for the same suggestion I had a few patches ago about being
more explicit that this is a pointer to an array of raw on-disk
structures which haven't been converted to cpu endianness.

--D

>  };
>  
>  struct xfs_dir3_icfree_hdr {
> @@ -25,7 +26,6 @@ struct xfs_dir3_icfree_hdr {
>  	uint32_t		firstdb;
>  	uint32_t		nvalid;
>  	uint32_t		nused;
> -
>  };
>  
>  /* xfs_dir2.c */
> @@ -86,7 +86,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..27fdf8978467 100644
> --- a/fs/xfs/scrub/dir.c
> +++ b/fs/xfs/scrub/dir.c
> @@ -195,13 +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) +
> +	xfs_dir2_leaf_hdr_from_disk(mp, &hdr, blk->bp->b_addr);
> +	ent = (void *)hdr.ents +
>  		(blk->index * sizeof(struct xfs_dir2_leaf_entry));
>  
>  	/* Check the hash of the entry. */
> @@ -481,7 +483,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 +506,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 +533,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
> 

^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH 10/34] xfs: move the dir2 leaf header size to struct xfs_da_geometry
  2019-11-01 22:06 ` [PATCH 10/34] xfs: move the dir2 leaf header size to struct xfs_da_geometry Christoph Hellwig
@ 2019-11-04 20:05   ` Darrick J. Wong
  0 siblings, 0 replies; 81+ messages in thread
From: Darrick J. Wong @ 2019-11-04 20:05 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-xfs

On Fri, Nov 01, 2019 at 03:06:55PM -0700, Christoph Hellwig wrote:
> Move the leaf header size towards our structure for dir/attr geometry
> parameters.
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>

Looks reasonable,
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>

--D

> ---
>  fs/xfs/libxfs/xfs_da_btree.h  | 1 +
>  fs/xfs/libxfs/xfs_da_format.c | 3 ---
>  fs/xfs/libxfs/xfs_dir2.c      | 7 +++++--
>  fs/xfs/libxfs/xfs_dir2.h      | 1 -
>  fs/xfs/libxfs/xfs_dir2_leaf.c | 2 +-
>  fs/xfs/libxfs/xfs_dir2_node.c | 4 ++--
>  6 files changed, 9 insertions(+), 9 deletions(-)
> 
> diff --git a/fs/xfs/libxfs/xfs_da_btree.h b/fs/xfs/libxfs/xfs_da_btree.h
> index 11b2d75f83ad..5e3e954fee77 100644
> --- a/fs/xfs/libxfs/xfs_da_btree.h
> +++ b/fs/xfs/libxfs/xfs_da_btree.h
> @@ -26,6 +26,7 @@ struct xfs_da_geometry {
>  	uint		node_ents;	/* # of entries in a danode */
>  	int		magicpct;	/* 37% of block size in bytes */
>  	xfs_dablk_t	datablk;	/* blockno of dir data v2 */
> +	int		leaf_hdr_size;	/* dir2 leaf header size */
>  	xfs_dablk_t	leafblk;	/* blockno of leaf data v2 */
>  	xfs_dablk_t	freeblk;	/* blockno of free data v2 */
>  };
> diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c
> index ed21ce01502f..a3e87f4788e0 100644
> --- a/fs/xfs/libxfs/xfs_da_format.c
> +++ b/fs/xfs/libxfs/xfs_da_format.c
> @@ -570,7 +570,6 @@ static const struct xfs_dir_ops xfs_dir2_ops = {
>  	.data_entry_p = xfs_dir2_data_entry_p,
>  	.data_unused_p = xfs_dir2_data_unused_p,
>  
> -	.leaf_hdr_size = sizeof(struct xfs_dir2_leaf_hdr),
>  	.leaf_max_ents = xfs_dir2_max_leaf_ents,
>  
>  	.free_hdr_size = sizeof(struct xfs_dir2_free_hdr),
> @@ -612,7 +611,6 @@ static const struct xfs_dir_ops xfs_dir2_ftype_ops = {
>  	.data_entry_p = xfs_dir2_data_entry_p,
>  	.data_unused_p = xfs_dir2_data_unused_p,
>  
> -	.leaf_hdr_size = sizeof(struct xfs_dir2_leaf_hdr),
>  	.leaf_max_ents = xfs_dir2_max_leaf_ents,
>  
>  	.free_hdr_size = sizeof(struct xfs_dir2_free_hdr),
> @@ -654,7 +652,6 @@ static const struct xfs_dir_ops xfs_dir3_ops = {
>  	.data_entry_p = xfs_dir3_data_entry_p,
>  	.data_unused_p = xfs_dir3_data_unused_p,
>  
> -	.leaf_hdr_size = sizeof(struct xfs_dir3_leaf_hdr),
>  	.leaf_max_ents = xfs_dir3_max_leaf_ents,
>  
>  	.free_hdr_size = sizeof(struct xfs_dir3_free_hdr),
> diff --git a/fs/xfs/libxfs/xfs_dir2.c b/fs/xfs/libxfs/xfs_dir2.c
> index aef20ec6e140..94badb28fd1a 100644
> --- a/fs/xfs/libxfs/xfs_dir2.c
> +++ b/fs/xfs/libxfs/xfs_dir2.c
> @@ -122,10 +122,13 @@ xfs_da_mount(
>  	dageo->fsblog = mp->m_sb.sb_blocklog;
>  	dageo->blksize = xfs_dir2_dirblock_bytes(&mp->m_sb);
>  	dageo->fsbcount = 1 << mp->m_sb.sb_dirblklog;
> -	if (xfs_sb_version_hascrc(&mp->m_sb))
> +	if (xfs_sb_version_hascrc(&mp->m_sb)) {
>  		dageo->node_hdr_size = sizeof(struct xfs_da3_node_hdr);
> -	else
> +		dageo->leaf_hdr_size = sizeof(struct xfs_dir3_leaf_hdr);
> +	} else {
>  		dageo->node_hdr_size = sizeof(struct xfs_da_node_hdr);
> +		dageo->leaf_hdr_size = sizeof(struct xfs_dir2_leaf_hdr);
> +	}
>  
>  	/*
>  	 * Now we've set up the block conversion variables, we can calculate the
> diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h
> index b46657974134..544adee5dd12 100644
> --- a/fs/xfs/libxfs/xfs_dir2.h
> +++ b/fs/xfs/libxfs/xfs_dir2.h
> @@ -72,7 +72,6 @@ struct xfs_dir_ops {
>  	struct xfs_dir2_data_unused *
>  		(*data_unused_p)(struct xfs_dir2_data_hdr *hdr);
>  
> -	int	leaf_hdr_size;
>  	int	(*leaf_max_ents)(struct xfs_da_geometry *geo);
>  
>  	int	free_hdr_size;
> diff --git a/fs/xfs/libxfs/xfs_dir2_leaf.c b/fs/xfs/libxfs/xfs_dir2_leaf.c
> index d6581f40f0a4..f72fd8182223 100644
> --- a/fs/xfs/libxfs/xfs_dir2_leaf.c
> +++ b/fs/xfs/libxfs/xfs_dir2_leaf.c
> @@ -1132,7 +1132,7 @@ xfs_dir3_leaf_log_header(
>  
>  	xfs_trans_log_buf(args->trans, bp,
>  			  (uint)((char *)&leaf->hdr - (char *)leaf),
> -			  args->dp->d_ops->leaf_hdr_size - 1);
> +			  args->geo->leaf_hdr_size - 1);
>  }
>  
>  /*
> diff --git a/fs/xfs/libxfs/xfs_dir2_node.c b/fs/xfs/libxfs/xfs_dir2_node.c
> index 76c896da8352..76f31909376e 100644
> --- a/fs/xfs/libxfs/xfs_dir2_node.c
> +++ b/fs/xfs/libxfs/xfs_dir2_node.c
> @@ -1334,7 +1334,7 @@ xfs_dir2_leafn_remove(
>  	 * Return indication of whether this leaf block is empty enough
>  	 * to justify trying to join it with a neighbor.
>  	 */
> -	*rval = (dp->d_ops->leaf_hdr_size +
> +	*rval = (args->geo->leaf_hdr_size +
>  		 (uint)sizeof(leafhdr.ents) * (leafhdr.count - leafhdr.stale)) <
>  		args->geo->magicpct;
>  	return 0;
> @@ -1440,7 +1440,7 @@ xfs_dir2_leafn_toosmall(
>  	xfs_dir3_leaf_check(dp, blk->bp);
>  
>  	count = leafhdr.count - leafhdr.stale;
> -	bytes = dp->d_ops->leaf_hdr_size + count * sizeof(ents[0]);
> +	bytes = state->args->geo->leaf_hdr_size + count * sizeof(ents[0]);
>  	if (bytes > (state->args->geo->blksize >> 1)) {
>  		/*
>  		 * Blk over 50%, don't try to join.
> -- 
> 2.20.1
> 

^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH 11/34] xfs: move the max dir2 leaf entries count to struct xfs_da_geometry
  2019-11-01 22:06 ` [PATCH 11/34] xfs: move the max dir2 leaf entries count " Christoph Hellwig
@ 2019-11-04 20:07   ` Darrick J. Wong
  2019-11-05  1:42     ` Christoph Hellwig
  0 siblings, 1 reply; 81+ messages in thread
From: Darrick J. Wong @ 2019-11-04 20:07 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-xfs

On Fri, Nov 01, 2019 at 03:06:56PM -0700, Christoph Hellwig wrote:
> Move the max leaf entries count towards our structure for dir/attr
> geometry parameters.
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
>  fs/xfs/libxfs/xfs_da_btree.h  |  1 +
>  fs/xfs/libxfs/xfs_da_format.c | 23 -----------------------
>  fs/xfs/libxfs/xfs_dir2.c      |  2 ++
>  fs/xfs/libxfs/xfs_dir2.h      |  2 --
>  fs/xfs/libxfs/xfs_dir2_leaf.c |  2 +-
>  fs/xfs/libxfs/xfs_dir2_node.c |  2 +-
>  fs/xfs/scrub/dir.c            |  3 +--
>  7 files changed, 6 insertions(+), 29 deletions(-)
> 
> diff --git a/fs/xfs/libxfs/xfs_da_btree.h b/fs/xfs/libxfs/xfs_da_btree.h
> index 5e3e954fee77..c8b137685ca7 100644
> --- a/fs/xfs/libxfs/xfs_da_btree.h
> +++ b/fs/xfs/libxfs/xfs_da_btree.h
> @@ -27,6 +27,7 @@ struct xfs_da_geometry {
>  	int		magicpct;	/* 37% of block size in bytes */
>  	xfs_dablk_t	datablk;	/* blockno of dir data v2 */
>  	int		leaf_hdr_size;	/* dir2 leaf header size */
> +	unsigned int	leaf_max_ents;	/* # of entries in dir2 leaf */

Why does this one get 'unsigned' but the header size fields don't?
Or maybe I should rephase that: Why aren't the header sizes unsigned
too?

Looks good to me otherwise,
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>

--D

>  	xfs_dablk_t	leafblk;	/* blockno of leaf data v2 */
>  	xfs_dablk_t	freeblk;	/* blockno of free data v2 */
>  };
> diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c
> index a3e87f4788e0..fe9e20698719 100644
> --- a/fs/xfs/libxfs/xfs_da_format.c
> +++ b/fs/xfs/libxfs/xfs_da_format.c
> @@ -401,23 +401,6 @@ xfs_dir3_data_unused_p(struct xfs_dir2_data_hdr *hdr)
>  }
>  
>  
> -/*
> - * Directory Leaf block operations
> - */
> -static int
> -xfs_dir2_max_leaf_ents(struct xfs_da_geometry *geo)
> -{
> -	return (geo->blksize - sizeof(struct xfs_dir2_leaf_hdr)) /
> -		(uint)sizeof(struct xfs_dir2_leaf_entry);
> -}
> -
> -static int
> -xfs_dir3_max_leaf_ents(struct xfs_da_geometry *geo)
> -{
> -	return (geo->blksize - sizeof(struct xfs_dir3_leaf_hdr)) /
> -		(uint)sizeof(struct xfs_dir2_leaf_entry);
> -}
> -
>  /*
>   * Directory free space block operations
>   */
> @@ -570,8 +553,6 @@ static const struct xfs_dir_ops xfs_dir2_ops = {
>  	.data_entry_p = xfs_dir2_data_entry_p,
>  	.data_unused_p = xfs_dir2_data_unused_p,
>  
> -	.leaf_max_ents = xfs_dir2_max_leaf_ents,
> -
>  	.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,
> @@ -611,8 +592,6 @@ static const struct xfs_dir_ops xfs_dir2_ftype_ops = {
>  	.data_entry_p = xfs_dir2_data_entry_p,
>  	.data_unused_p = xfs_dir2_data_unused_p,
>  
> -	.leaf_max_ents = xfs_dir2_max_leaf_ents,
> -
>  	.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,
> @@ -652,8 +631,6 @@ static const struct xfs_dir_ops xfs_dir3_ops = {
>  	.data_entry_p = xfs_dir3_data_entry_p,
>  	.data_unused_p = xfs_dir3_data_unused_p,
>  
> -	.leaf_max_ents = xfs_dir3_max_leaf_ents,
> -
>  	.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,
> diff --git a/fs/xfs/libxfs/xfs_dir2.c b/fs/xfs/libxfs/xfs_dir2.c
> index 94badb28fd1a..9f88b9885747 100644
> --- a/fs/xfs/libxfs/xfs_dir2.c
> +++ b/fs/xfs/libxfs/xfs_dir2.c
> @@ -129,6 +129,8 @@ xfs_da_mount(
>  		dageo->node_hdr_size = sizeof(struct xfs_da_node_hdr);
>  		dageo->leaf_hdr_size = sizeof(struct xfs_dir2_leaf_hdr);
>  	}
> +	dageo->leaf_max_ents = (dageo->blksize - dageo->leaf_hdr_size) /
> +			sizeof(struct xfs_dir2_leaf_entry);
>  
>  	/*
>  	 * Now we've set up the block conversion variables, we can calculate the
> diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h
> index 544adee5dd12..ee18fc56a6a1 100644
> --- a/fs/xfs/libxfs/xfs_dir2.h
> +++ b/fs/xfs/libxfs/xfs_dir2.h
> @@ -72,8 +72,6 @@ struct xfs_dir_ops {
>  	struct xfs_dir2_data_unused *
>  		(*data_unused_p)(struct xfs_dir2_data_hdr *hdr);
>  
> -	int	(*leaf_max_ents)(struct xfs_da_geometry *geo);
> -
>  	int	free_hdr_size;
>  	void	(*free_hdr_to_disk)(struct xfs_dir2_free *to,
>  				    struct xfs_dir3_icfree_hdr *from);
> diff --git a/fs/xfs/libxfs/xfs_dir2_leaf.c b/fs/xfs/libxfs/xfs_dir2_leaf.c
> index f72fd8182223..38d42fe1aa02 100644
> --- a/fs/xfs/libxfs/xfs_dir2_leaf.c
> +++ b/fs/xfs/libxfs/xfs_dir2_leaf.c
> @@ -167,7 +167,7 @@ xfs_dir3_leaf_check_int(
>  	 * Should factor in the size of the bests table as well.
>  	 * We can deduce a value for that from di_size.
>  	 */
> -	if (hdr->count > ops->leaf_max_ents(geo))
> +	if (hdr->count > geo->leaf_max_ents)
>  		return __this_address;
>  
>  	/* Leaves and bests don't overlap in leaf format. */
> diff --git a/fs/xfs/libxfs/xfs_dir2_node.c b/fs/xfs/libxfs/xfs_dir2_node.c
> index 76f31909376e..3b9ed6ac72b6 100644
> --- a/fs/xfs/libxfs/xfs_dir2_node.c
> +++ b/fs/xfs/libxfs/xfs_dir2_node.c
> @@ -455,7 +455,7 @@ xfs_dir2_leafn_add(
>  	 * a compact.
>  	 */
>  
> -	if (leafhdr.count == dp->d_ops->leaf_max_ents(args->geo)) {
> +	if (leafhdr.count == args->geo->leaf_max_ents) {
>  		if (!leafhdr.stale)
>  			return -ENOSPC;
>  		compact = leafhdr.stale > 1;
> diff --git a/fs/xfs/scrub/dir.c b/fs/xfs/scrub/dir.c
> index 27fdf8978467..e4e189d3c1c0 100644
> --- a/fs/xfs/scrub/dir.c
> +++ b/fs/xfs/scrub/dir.c
> @@ -487,7 +487,6 @@ xchk_directory_leaf1_bestfree(
>  	struct xfs_dir2_leaf		*leaf;
>  	struct xfs_buf			*dbp;
>  	struct xfs_buf			*bp;
> -	const struct xfs_dir_ops	*d_ops = sc->ip->d_ops;
>  	struct xfs_da_geometry		*geo = sc->mp->m_dir_geo;
>  	__be16				*bestp;
>  	__u16				best;
> @@ -527,7 +526,7 @@ xchk_directory_leaf1_bestfree(
>  	}
>  
>  	/* Is the leaf count even remotely sane? */
> -	if (leafhdr.count > d_ops->leaf_max_ents(geo)) {
> +	if (leafhdr.count > geo->leaf_max_ents) {
>  		xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk);
>  		goto out;
>  	}
> -- 
> 2.20.1
> 

^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH 12/34] xfs: devirtualize ->free_hdr_from_disk
  2019-11-01 22:06 ` [PATCH 12/34] xfs: devirtualize ->free_hdr_from_disk Christoph Hellwig
@ 2019-11-04 20:08   ` Darrick J. Wong
  0 siblings, 0 replies; 81+ messages in thread
From: Darrick J. Wong @ 2019-11-04 20:08 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-xfs

On Fri, Nov 01, 2019 at 03:06:57PM -0700, Christoph Hellwig wrote:
> 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: Christoph Hellwig <hch@lst.de>

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

--D

> ---
>  fs/xfs/libxfs/xfs_da_format.c | 30 -----------------------
>  fs/xfs/libxfs/xfs_dir2.h      |  2 --
>  fs/xfs/libxfs/xfs_dir2_leaf.c | 14 +++--------
>  fs/xfs/libxfs/xfs_dir2_node.c | 46 +++++++++++++++++++++++++++--------
>  fs/xfs/libxfs/xfs_dir2_priv.h |  5 ++--
>  fs/xfs/scrub/dir.c            |  2 +-
>  6 files changed, 43 insertions(+), 56 deletions(-)
> 
> diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c
> index fe9e20698719..d0e541d9d335 100644
> --- a/fs/xfs/libxfs/xfs_da_format.c
> +++ b/fs/xfs/libxfs/xfs_da_format.c
> @@ -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,
> diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h
> index ee18fc56a6a1..c3e6a6fb7e37 100644
> --- a/fs/xfs/libxfs/xfs_dir2.h
> +++ b/fs/xfs/libxfs/xfs_dir2.h
> @@ -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,
> diff --git a/fs/xfs/libxfs/xfs_dir2_leaf.c b/fs/xfs/libxfs/xfs_dir2_leaf.c
> index 38d42fe1aa02..4b697dd85eab 100644
> --- a/fs/xfs/libxfs/xfs_dir2_leaf.c
> +++ b/fs/xfs/libxfs/xfs_dir2_leaf.c
> @@ -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
> @@ -1756,7 +1748,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);
>  
> diff --git a/fs/xfs/libxfs/xfs_dir2_node.c b/fs/xfs/libxfs/xfs_dir2_node.c
> index 3b9ed6ac72b6..9e22710bb772 100644
> --- a/fs/xfs/libxfs/xfs_dir2_node.c
> +++ b/fs/xfs/libxfs/xfs_dir2_node.c
> @@ -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) >
> @@ -509,7 +533,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);
> @@ -1117,7 +1141,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) {
>  		/*
> @@ -1286,7 +1310,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)));
> @@ -1680,7 +1705,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,
> @@ -1689,7 +1714,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. */
> @@ -1758,7 +1783,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);
> @@ -1807,7 +1833,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--) {
> @@ -2260,7 +2286,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.
> diff --git a/fs/xfs/libxfs/xfs_dir2_priv.h b/fs/xfs/libxfs/xfs_dir2_priv.h
> index 07cea5751783..ef4a2b402e25 100644
> --- a/fs/xfs/libxfs/xfs_dir2_priv.h
> +++ b/fs/xfs/libxfs/xfs_dir2_priv.h
> @@ -104,10 +104,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,
> diff --git a/fs/xfs/scrub/dir.c b/fs/xfs/scrub/dir.c
> index e4e189d3c1c0..6b8d9a774ddf 100644
> --- a/fs/xfs/scrub/dir.c
> +++ b/fs/xfs/scrub/dir.c
> @@ -601,7 +601,7 @@ xchk_directory_free_bestfree(
>  	}
>  
>  	/* Check all the entries. */
> -	sc->ip->d_ops->free_hdr_from_disk(&freehdr, bp->b_addr);
> +	xfs_dir2_free_hdr_from_disk(sc->ip->i_mount, &freehdr, bp->b_addr);
>  	bestp = sc->ip->d_ops->free_bests_p(bp->b_addr);
>  	for (i = 0; i < freehdr.nvalid; i++, bestp++) {
>  		best = be16_to_cpu(*bestp);
> -- 
> 2.20.1
> 

^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH 13/34] xfs: devirtualize ->free_hdr_to_disk
  2019-11-01 22:06 ` [PATCH 13/34] xfs: devirtualize ->free_hdr_to_disk Christoph Hellwig
@ 2019-11-04 20:08   ` Darrick J. Wong
  0 siblings, 0 replies; 81+ messages in thread
From: Darrick J. Wong @ 2019-11-04 20:08 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-xfs

On Fri, Nov 01, 2019 at 03:06:58PM -0700, Christoph Hellwig wrote:
> Replace the ->free_hdr_to_disk dir ops method with a directly called
> xfs_dir2_free_hdr_to_disk helper that takes care of the differences
> between the v4 and v5 on-disk format.
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>

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

--D

> ---
>  fs/xfs/libxfs/xfs_da_format.c | 31 -------------------------------
>  fs/xfs/libxfs/xfs_dir2.h      |  2 --
>  fs/xfs/libxfs/xfs_dir2_node.c | 33 +++++++++++++++++++++++++++++----
>  3 files changed, 29 insertions(+), 37 deletions(-)
> 
> diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c
> index d0e541d9d335..b943d9443d55 100644
> --- a/fs/xfs/libxfs/xfs_da_format.c
> +++ b/fs/xfs/libxfs/xfs_da_format.c
> @@ -468,34 +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_to_disk(
> -	struct xfs_dir2_free		*to,
> -	struct xfs_dir3_icfree_hdr	*from)
> -{
> -	ASSERT(from->magic == XFS_DIR2_FREE_MAGIC);
> -
> -	to->hdr.magic = cpu_to_be32(from->magic);
> -	to->hdr.firstdb = cpu_to_be32(from->firstdb);
> -	to->hdr.nvalid = cpu_to_be32(from->nvalid);
> -	to->hdr.nused = cpu_to_be32(from->nused);
> -}
> -
> -static void
> -xfs_dir3_free_hdr_to_disk(
> -	struct xfs_dir2_free		*to,
> -	struct xfs_dir3_icfree_hdr	*from)
> -{
> -	struct xfs_dir3_free_hdr *hdr3 = (struct xfs_dir3_free_hdr *)to;
> -
> -	ASSERT(from->magic == XFS_DIR3_FREE_MAGIC);
> -
> -	hdr3->hdr.magic = cpu_to_be32(from->magic);
> -	hdr3->firstdb = cpu_to_be32(from->firstdb);
> -	hdr3->nvalid = cpu_to_be32(from->nvalid);
> -	hdr3->nused = cpu_to_be32(from->nused);
> -}
> -
>  static const struct xfs_dir_ops xfs_dir2_ops = {
>  	.sf_entsize = xfs_dir2_sf_entsize,
>  	.sf_nextentry = xfs_dir2_sf_nextentry,
> @@ -527,7 +499,6 @@ static const struct xfs_dir_ops xfs_dir2_ops = {
>  	.data_unused_p = xfs_dir2_data_unused_p,
>  
>  	.free_hdr_size = sizeof(struct xfs_dir2_free_hdr),
> -	.free_hdr_to_disk = xfs_dir2_free_hdr_to_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,
> @@ -565,7 +536,6 @@ static const struct xfs_dir_ops xfs_dir2_ftype_ops = {
>  	.data_unused_p = xfs_dir2_data_unused_p,
>  
>  	.free_hdr_size = sizeof(struct xfs_dir2_free_hdr),
> -	.free_hdr_to_disk = xfs_dir2_free_hdr_to_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,
> @@ -603,7 +573,6 @@ static const struct xfs_dir_ops xfs_dir3_ops = {
>  	.data_unused_p = xfs_dir3_data_unused_p,
>  
>  	.free_hdr_size = sizeof(struct xfs_dir3_free_hdr),
> -	.free_hdr_to_disk = xfs_dir3_free_hdr_to_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,
> diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h
> index c3e6a6fb7e37..613a78281d03 100644
> --- a/fs/xfs/libxfs/xfs_dir2.h
> +++ b/fs/xfs/libxfs/xfs_dir2.h
> @@ -73,8 +73,6 @@ struct xfs_dir_ops {
>  		(*data_unused_p)(struct xfs_dir2_data_hdr *hdr);
>  
>  	int	free_hdr_size;
> -	void	(*free_hdr_to_disk)(struct xfs_dir2_free *to,
> -				    struct xfs_dir3_icfree_hdr *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,
> diff --git a/fs/xfs/libxfs/xfs_dir2_node.c b/fs/xfs/libxfs/xfs_dir2_node.c
> index 9e22710bb772..26032eba1e32 100644
> --- a/fs/xfs/libxfs/xfs_dir2_node.c
> +++ b/fs/xfs/libxfs/xfs_dir2_node.c
> @@ -244,6 +244,31 @@ xfs_dir2_free_hdr_from_disk(
>  	}
>  }
>  
> +static void
> +xfs_dir2_free_hdr_to_disk(
> +	struct xfs_mount		*mp,
> +	struct xfs_dir2_free		*to,
> +	struct xfs_dir3_icfree_hdr	*from)
> +{
> +	if (xfs_sb_version_hascrc(&mp->m_sb)) {
> +		struct xfs_dir3_free	*to3 = (struct xfs_dir3_free *)to;
> +
> +		ASSERT(from->magic == XFS_DIR3_FREE_MAGIC);
> +
> +		to3->hdr.hdr.magic = cpu_to_be32(from->magic);
> +		to3->hdr.firstdb = cpu_to_be32(from->firstdb);
> +		to3->hdr.nvalid = cpu_to_be32(from->nvalid);
> +		to3->hdr.nused = cpu_to_be32(from->nused);
> +	} else {
> +		ASSERT(from->magic == XFS_DIR2_FREE_MAGIC);
> +
> +		to->hdr.magic = cpu_to_be32(from->magic);
> +		to->hdr.firstdb = cpu_to_be32(from->firstdb);
> +		to->hdr.nvalid = cpu_to_be32(from->nvalid);
> +		to->hdr.nused = cpu_to_be32(from->nused);
> +	}
> +}
> +
>  int
>  xfs_dir2_free_read(
>  	struct xfs_trans	*tp,
> @@ -302,7 +327,7 @@ xfs_dir3_free_get_buf(
>  		uuid_copy(&hdr3->hdr.uuid, &mp->m_sb.sb_meta_uuid);
>  	} else
>  		hdr.magic = XFS_DIR2_FREE_MAGIC;
> -	dp->d_ops->free_hdr_to_disk(bp->b_addr, &hdr);
> +	xfs_dir2_free_hdr_to_disk(mp, bp->b_addr, &hdr);
>  	*bpp = bp;
>  	return 0;
>  }
> @@ -418,7 +443,7 @@ xfs_dir2_leaf_to_node(
>  	freehdr.nused = n;
>  	freehdr.nvalid = be32_to_cpu(ltp->bestcount);
>  
> -	dp->d_ops->free_hdr_to_disk(fbp->b_addr, &freehdr);
> +	xfs_dir2_free_hdr_to_disk(dp->i_mount, fbp->b_addr, &freehdr);
>  	xfs_dir2_free_log_bests(args, fbp, 0, freehdr.nvalid - 1);
>  	xfs_dir2_free_log_header(args, fbp);
>  
> @@ -1176,7 +1201,7 @@ xfs_dir3_data_block_free(
>  		logfree = 1;
>  	}
>  
> -	dp->d_ops->free_hdr_to_disk(free, &freehdr);
> +	xfs_dir2_free_hdr_to_disk(dp->i_mount, free, &freehdr);
>  	xfs_dir2_free_log_header(args, fbp);
>  
>  	/*
> @@ -1733,7 +1758,7 @@ xfs_dir2_node_add_datablk(
>  	 */
>  	if (bests[*findex] == cpu_to_be16(NULLDATAOFF)) {
>  		freehdr.nused++;
> -		dp->d_ops->free_hdr_to_disk(fbp->b_addr, &freehdr);
> +		xfs_dir2_free_hdr_to_disk(mp, fbp->b_addr, &freehdr);
>  		xfs_dir2_free_log_header(args, fbp);
>  	}
>  
> -- 
> 2.20.1
> 

^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH 15/34] xfs: add a bests pointer to struct xfs_dir3_icfree_hdr
  2019-11-01 22:07 ` [PATCH 15/34] xfs: add a bests pointer to struct xfs_dir3_icfree_hdr Christoph Hellwig
@ 2019-11-04 20:21   ` Darrick J. Wong
  2019-11-05  1:44     ` Christoph Hellwig
  0 siblings, 1 reply; 81+ messages in thread
From: Darrick J. Wong @ 2019-11-04 20:21 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-xfs

On Fri, Nov 01, 2019 at 03:07:00PM -0700, Christoph Hellwig wrote:
> All but two callers of the ->free_bests_p dir operation already have a
> struct xfs_dir3_icfree_hdr from a previous call to
> xfs_dir2_free_hdr_from_disk at hand.  Add a pointer to the bests to
> struct xfs_dir3_icfree_hdr to clean up this pattern.  To optimize this
> pattern, pass the struct xfs_dir3_icfree_hdr to xfs_dir2_free_log_bests
> instead of recalculating the pointer there.
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
>  fs/xfs/libxfs/xfs_da_format.c | 15 ------
>  fs/xfs/libxfs/xfs_dir2.h      |  1 -
>  fs/xfs/libxfs/xfs_dir2_leaf.c |  6 +--
>  fs/xfs/libxfs/xfs_dir2_node.c | 97 ++++++++++++++---------------------
>  fs/xfs/libxfs/xfs_dir2_priv.h |  1 +
>  fs/xfs/scrub/dir.c            |  6 +--
>  6 files changed, 43 insertions(+), 83 deletions(-)
> 
> diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c
> index b943d9443d55..7263b6d6a135 100644
> --- a/fs/xfs/libxfs/xfs_da_format.c
> +++ b/fs/xfs/libxfs/xfs_da_format.c
> @@ -411,12 +411,6 @@ xfs_dir2_free_max_bests(struct xfs_da_geometry *geo)
>  		sizeof(xfs_dir2_data_off_t);
>  }
>  
> -static __be16 *
> -xfs_dir2_free_bests_p(struct xfs_dir2_free *free)
> -{
> -	return (__be16 *)((char *)free + sizeof(struct xfs_dir2_free_hdr));
> -}
> -
>  /*
>   * Convert data space db to the corresponding free db.
>   */
> @@ -443,12 +437,6 @@ xfs_dir3_free_max_bests(struct xfs_da_geometry *geo)
>  		sizeof(xfs_dir2_data_off_t);
>  }
>  
> -static __be16 *
> -xfs_dir3_free_bests_p(struct xfs_dir2_free *free)
> -{
> -	return (__be16 *)((char *)free + sizeof(struct xfs_dir3_free_hdr));
> -}
> -
>  /*
>   * Convert data space db to the corresponding free db.
>   */
> @@ -500,7 +488,6 @@ static const struct xfs_dir_ops xfs_dir2_ops = {
>  
>  	.free_hdr_size = sizeof(struct xfs_dir2_free_hdr),
>  	.free_max_bests = xfs_dir2_free_max_bests,
> -	.free_bests_p = xfs_dir2_free_bests_p,
>  	.db_to_fdb = xfs_dir2_db_to_fdb,
>  	.db_to_fdindex = xfs_dir2_db_to_fdindex,
>  };
> @@ -537,7 +524,6 @@ static const struct xfs_dir_ops xfs_dir2_ftype_ops = {
>  
>  	.free_hdr_size = sizeof(struct xfs_dir2_free_hdr),
>  	.free_max_bests = xfs_dir2_free_max_bests,
> -	.free_bests_p = xfs_dir2_free_bests_p,
>  	.db_to_fdb = xfs_dir2_db_to_fdb,
>  	.db_to_fdindex = xfs_dir2_db_to_fdindex,
>  };
> @@ -574,7 +560,6 @@ static const struct xfs_dir_ops xfs_dir3_ops = {
>  
>  	.free_hdr_size = sizeof(struct xfs_dir3_free_hdr),
>  	.free_max_bests = xfs_dir3_free_max_bests,
> -	.free_bests_p = xfs_dir3_free_bests_p,
>  	.db_to_fdb = xfs_dir3_db_to_fdb,
>  	.db_to_fdindex = xfs_dir3_db_to_fdindex,
>  };
> diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h
> index 613a78281d03..402f00326b64 100644
> --- a/fs/xfs/libxfs/xfs_dir2.h
> +++ b/fs/xfs/libxfs/xfs_dir2.h
> @@ -74,7 +74,6 @@ struct xfs_dir_ops {
>  
>  	int	free_hdr_size;
>  	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,
>  				   xfs_dir2_db_t db);
>  	int	(*db_to_fdindex)(struct xfs_da_geometry *geo,
> diff --git a/fs/xfs/libxfs/xfs_dir2_leaf.c b/fs/xfs/libxfs/xfs_dir2_leaf.c
> index 4b697dd85eab..3770107c0695 100644
> --- a/fs/xfs/libxfs/xfs_dir2_leaf.c
> +++ b/fs/xfs/libxfs/xfs_dir2_leaf.c
> @@ -1678,7 +1678,6 @@ xfs_dir2_node_to_leaf(
>  	int			error;		/* error return code */
>  	struct xfs_buf		*fbp;		/* buffer for freespace block */
>  	xfs_fileoff_t		fo;		/* freespace file offset */
> -	xfs_dir2_free_t		*free;		/* freespace structure */
>  	struct xfs_buf		*lbp;		/* buffer for leaf block */
>  	xfs_dir2_leaf_tail_t	*ltp;		/* tail of leaf structure */
>  	xfs_dir2_leaf_t		*leaf;		/* leaf structure */
> @@ -1747,8 +1746,7 @@ xfs_dir2_node_to_leaf(
>  	error = xfs_dir2_free_read(tp, dp,  args->geo->freeblk, &fbp);
>  	if (error)
>  		return error;
> -	free = fbp->b_addr;
> -	xfs_dir2_free_hdr_from_disk(mp, &freehdr, free);
> +	xfs_dir2_free_hdr_from_disk(mp, &freehdr, fbp->b_addr);
>  
>  	ASSERT(!freehdr.firstdb);
>  
> @@ -1782,7 +1780,7 @@ xfs_dir2_node_to_leaf(
>  	/*
>  	 * Set up the leaf bests table.
>  	 */
> -	memcpy(xfs_dir2_leaf_bests_p(ltp), dp->d_ops->free_bests_p(free),
> +	memcpy(xfs_dir2_leaf_bests_p(ltp), freehdr.bests,
>  		freehdr.nvalid * sizeof(xfs_dir2_data_off_t));
>  
>  	xfs_dir2_leaf_hdr_to_disk(mp, leaf, &leafhdr);
> diff --git a/fs/xfs/libxfs/xfs_dir2_node.c b/fs/xfs/libxfs/xfs_dir2_node.c
> index d400243c9556..eff7cfeb19b9 100644
> --- a/fs/xfs/libxfs/xfs_dir2_node.c
> +++ b/fs/xfs/libxfs/xfs_dir2_node.c
> @@ -233,6 +233,7 @@ xfs_dir2_free_hdr_from_disk(
>  		to->firstdb = be32_to_cpu(from3->hdr.firstdb);
>  		to->nvalid = be32_to_cpu(from3->hdr.nvalid);
>  		to->nused = be32_to_cpu(from3->hdr.nused);
> +		to->bests = (void *)from3 + sizeof(struct xfs_dir3_free_hdr);

Urgh, isn't void pointer arithmetic technically illegal according to C?

In any case, shouldn't this cast through struct xfs_dir3_free instead of
open-coding details of the disk format that we've already captured?  The
same question also applies to the other patches that add pointers to
ondisk leaf and intnode pointers into the incore header struct.

--D

>  
>  		ASSERT(to->magic == XFS_DIR3_FREE_MAGIC);
>  	} else {
> @@ -240,6 +241,8 @@ xfs_dir2_free_hdr_from_disk(
>  		to->firstdb = be32_to_cpu(from->hdr.firstdb);
>  		to->nvalid = be32_to_cpu(from->hdr.nvalid);
>  		to->nused = be32_to_cpu(from->hdr.nused);
> +		to->bests = (void *)from + sizeof(struct xfs_dir2_free_hdr);
> +
>  		ASSERT(to->magic == XFS_DIR2_FREE_MAGIC);
>  	}
>  }
> @@ -338,21 +341,19 @@ xfs_dir3_free_get_buf(
>  STATIC void
>  xfs_dir2_free_log_bests(
>  	struct xfs_da_args	*args,
> +	struct xfs_dir3_icfree_hdr *hdr,
>  	struct xfs_buf		*bp,
>  	int			first,		/* first entry to log */
>  	int			last)		/* last entry to log */
>  {
> -	xfs_dir2_free_t		*free;		/* freespace structure */
> -	__be16			*bests;
> +	struct xfs_dir2_free	*free = bp->b_addr;
>  
> -	free = bp->b_addr;
> -	bests = args->dp->d_ops->free_bests_p(free);
>  	ASSERT(free->hdr.magic == cpu_to_be32(XFS_DIR2_FREE_MAGIC) ||
>  	       free->hdr.magic == cpu_to_be32(XFS_DIR3_FREE_MAGIC));
>  	xfs_trans_log_buf(args->trans, bp,
> -		(uint)((char *)&bests[first] - (char *)free),
> -		(uint)((char *)&bests[last] - (char *)free +
> -		       sizeof(bests[0]) - 1));
> +			  (char *)&hdr->bests[first] - (char *)free,
> +			  (char *)&hdr->bests[last] - (char *)free +
> +			   sizeof(hdr->bests[0]) - 1);
>  }
>  
>  /*
> @@ -388,14 +389,12 @@ xfs_dir2_leaf_to_node(
>  	int			error;		/* error return value */
>  	struct xfs_buf		*fbp;		/* freespace buffer */
>  	xfs_dir2_db_t		fdb;		/* freespace block number */
> -	xfs_dir2_free_t		*free;		/* freespace structure */
>  	__be16			*from;		/* pointer to freespace entry */
>  	int			i;		/* leaf freespace index */
>  	xfs_dir2_leaf_t		*leaf;		/* leaf structure */
>  	xfs_dir2_leaf_tail_t	*ltp;		/* leaf tail structure */
>  	int			n;		/* count of live freespc ents */
>  	xfs_dir2_data_off_t	off;		/* freespace entry value */
> -	__be16			*to;		/* pointer to freespace entry */
>  	xfs_trans_t		*tp;		/* transaction pointer */
>  	struct xfs_dir3_icfree_hdr freehdr;
>  
> @@ -417,8 +416,7 @@ xfs_dir2_leaf_to_node(
>  	if (error)
>  		return error;
>  
> -	free = fbp->b_addr;
> -	xfs_dir2_free_hdr_from_disk(dp->i_mount, &freehdr, free);
> +	xfs_dir2_free_hdr_from_disk(dp->i_mount, &freehdr, fbp->b_addr);
>  	leaf = lbp->b_addr;
>  	ltp = xfs_dir2_leaf_tail_p(args->geo, leaf);
>  	if (be32_to_cpu(ltp->bestcount) >
> @@ -430,11 +428,11 @@ xfs_dir2_leaf_to_node(
>  	 * Count active entries.
>  	 */
>  	from = xfs_dir2_leaf_bests_p(ltp);
> -	to = dp->d_ops->free_bests_p(free);
> -	for (i = n = 0; i < be32_to_cpu(ltp->bestcount); i++, from++, to++) {
> -		if ((off = be16_to_cpu(*from)) != NULLDATAOFF)
> +	for (i = n = 0; i < be32_to_cpu(ltp->bestcount); i++, from++) {
> +		off = be16_to_cpu(*from);
> +		if (off != NULLDATAOFF)
>  			n++;
> -		*to = cpu_to_be16(off);
> +		freehdr.bests[i] = cpu_to_be16(off);
>  	}
>  
>  	/*
> @@ -444,7 +442,7 @@ xfs_dir2_leaf_to_node(
>  	freehdr.nvalid = be32_to_cpu(ltp->bestcount);
>  
>  	xfs_dir2_free_hdr_to_disk(dp->i_mount, fbp->b_addr, &freehdr);
> -	xfs_dir2_free_log_bests(args, fbp, 0, freehdr.nvalid - 1);
> +	xfs_dir2_free_log_bests(args, &freehdr, fbp, 0, freehdr.nvalid - 1);
>  	xfs_dir2_free_log_header(args, fbp);
>  
>  	/*
> @@ -673,7 +671,7 @@ xfs_dir2_leafn_lookup_for_addname(
>  		 * in hand, take a look at it.
>  		 */
>  		if (newdb != curdb) {
> -			__be16 *bests;
> +			struct xfs_dir3_icfree_hdr freehdr;
>  
>  			curdb = newdb;
>  			/*
> @@ -708,8 +706,9 @@ xfs_dir2_leafn_lookup_for_addname(
>  			/*
>  			 * If it has room, return it.
>  			 */
> -			bests = dp->d_ops->free_bests_p(free);
> -			if (unlikely(bests[fi] == cpu_to_be16(NULLDATAOFF))) {
> +			xfs_dir2_free_hdr_from_disk(mp, &freehdr, free);
> +			if (unlikely(freehdr.bests[fi] ==
> +				     cpu_to_be16(NULLDATAOFF))) {
>  				XFS_ERROR_REPORT("xfs_dir2_leafn_lookup_int",
>  							XFS_ERRLEVEL_LOW, mp);
>  				if (curfdb != newfdb)
> @@ -717,7 +716,7 @@ xfs_dir2_leafn_lookup_for_addname(
>  				return -EFSCORRUPTED;
>  			}
>  			curfdb = newfdb;
> -			if (be16_to_cpu(bests[fi]) >= length)
> +			if (be16_to_cpu(freehdr.bests[fi]) >= length)
>  				goto out;
>  		}
>  	}
> @@ -1162,19 +1161,17 @@ xfs_dir3_data_block_free(
>  	int			longest)
>  {
>  	int			logfree = 0;
> -	__be16			*bests;
>  	struct xfs_dir3_icfree_hdr freehdr;
>  	struct xfs_inode	*dp = args->dp;
>  
>  	xfs_dir2_free_hdr_from_disk(dp->i_mount, &freehdr, free);
> -	bests = dp->d_ops->free_bests_p(free);
>  	if (hdr) {
>  		/*
>  		 * Data block is not empty, just set the free entry to the new
>  		 * value.
>  		 */
> -		bests[findex] = cpu_to_be16(longest);
> -		xfs_dir2_free_log_bests(args, fbp, findex, findex);
> +		freehdr.bests[findex] = cpu_to_be16(longest);
> +		xfs_dir2_free_log_bests(args, &freehdr, fbp, findex, findex);
>  		return 0;
>  	}
>  
> @@ -1190,14 +1187,14 @@ xfs_dir3_data_block_free(
>  		int	i;		/* free entry index */
>  
>  		for (i = findex - 1; i >= 0; i--) {
> -			if (bests[i] != cpu_to_be16(NULLDATAOFF))
> +			if (freehdr.bests[i] != cpu_to_be16(NULLDATAOFF))
>  				break;
>  		}
>  		freehdr.nvalid = i + 1;
>  		logfree = 0;
>  	} else {
>  		/* Not the last entry, just punch it out.  */
> -		bests[findex] = cpu_to_be16(NULLDATAOFF);
> +		freehdr.bests[findex] = cpu_to_be16(NULLDATAOFF);
>  		logfree = 1;
>  	}
>  
> @@ -1226,7 +1223,7 @@ xfs_dir3_data_block_free(
>  
>  	/* Log the free entry that changed, unless we got rid of it.  */
>  	if (logfree)
> -		xfs_dir2_free_log_bests(args, fbp, findex, findex);
> +		xfs_dir2_free_log_bests(args, &freehdr, fbp, findex, findex);
>  	return 0;
>  }
>  
> @@ -1667,11 +1664,9 @@ xfs_dir2_node_add_datablk(
>  	struct xfs_trans	*tp = args->trans;
>  	struct xfs_mount	*mp = dp->i_mount;
>  	struct xfs_dir2_data_free *bf;
> -	struct xfs_dir2_free	*free = NULL;
>  	xfs_dir2_db_t		fbno;
>  	struct xfs_buf		*fbp;
>  	struct xfs_buf		*dbp;
> -	__be16			*bests = NULL;
>  	int			error;
>  
>  	/* Not allowed to allocate, return failure. */
> @@ -1727,18 +1722,14 @@ xfs_dir2_node_add_datablk(
>  		error = xfs_dir3_free_get_buf(args, fbno, &fbp);
>  		if (error)
>  			return error;
> -		free = fbp->b_addr;
> -		bests = dp->d_ops->free_bests_p(free);
> -		xfs_dir2_free_hdr_from_disk(mp, hdr, free);
> +		xfs_dir2_free_hdr_from_disk(mp, hdr, fbp->b_addr);
>  
>  		/* Remember the first slot as our empty slot. */
>  		hdr->firstdb = (fbno - xfs_dir2_byte_to_db(args->geo,
>  							XFS_DIR2_FREE_OFFSET)) *
>  				dp->d_ops->free_max_bests(args->geo);
>  	} else {
> -		free = fbp->b_addr;
> -		bests = dp->d_ops->free_bests_p(free);
> -		xfs_dir2_free_hdr_from_disk(mp, hdr, free);
> +		xfs_dir2_free_hdr_from_disk(mp, hdr, fbp->b_addr);
>  	}
>  
>  	/* Set the freespace block index from the data block number. */
> @@ -1748,14 +1739,14 @@ xfs_dir2_node_add_datablk(
>  	if (*findex >= hdr->nvalid) {
>  		ASSERT(*findex < dp->d_ops->free_max_bests(args->geo));
>  		hdr->nvalid = *findex + 1;
> -		bests[*findex] = cpu_to_be16(NULLDATAOFF);
> +		hdr->bests[*findex] = cpu_to_be16(NULLDATAOFF);
>  	}
>  
>  	/*
>  	 * If this entry was for an empty data block (this should always be
>  	 * true) then update the header.
>  	 */
> -	if (bests[*findex] == cpu_to_be16(NULLDATAOFF)) {
> +	if (hdr->bests[*findex] == cpu_to_be16(NULLDATAOFF)) {
>  		hdr->nused++;
>  		xfs_dir2_free_hdr_to_disk(mp, fbp->b_addr, hdr);
>  		xfs_dir2_free_log_header(args, fbp);
> @@ -1763,7 +1754,7 @@ xfs_dir2_node_add_datablk(
>  
>  	/* Update the freespace value for the new block in the table. */
>  	bf = dp->d_ops->data_bestfree_p(dbp->b_addr);
> -	bests[*findex] = bf[0].length;
> +	hdr->bests[*findex] = bf[0].length;
>  
>  	*dbpp = dbp;
>  	*fbpp = fbp;
> @@ -1780,7 +1771,6 @@ xfs_dir2_node_find_freeblk(
>  	int			*findexp,
>  	int			length)
>  {
> -	struct xfs_dir2_free	*free = NULL;
>  	struct xfs_inode	*dp = args->dp;
>  	struct xfs_trans	*tp = args->trans;
>  	struct xfs_buf		*fbp = NULL;
> @@ -1790,7 +1780,6 @@ xfs_dir2_node_find_freeblk(
>  	xfs_dir2_db_t		dbno = -1;
>  	xfs_dir2_db_t		fbno;
>  	xfs_fileoff_t		fo;
> -	__be16			*bests = NULL;
>  	int			findex = 0;
>  	int			error;
>  
> @@ -1801,16 +1790,13 @@ xfs_dir2_node_find_freeblk(
>  	 */
>  	if (fblk) {
>  		fbp = fblk->bp;
> -		free = fbp->b_addr;
>  		findex = fblk->index;
> +		xfs_dir2_free_hdr_from_disk(dp->i_mount, hdr, fbp->b_addr);
>  		if (findex >= 0) {
>  			/* caller already found the freespace for us. */
> -			bests = dp->d_ops->free_bests_p(free);
> -			xfs_dir2_free_hdr_from_disk(dp->i_mount, hdr, free);
> -
>  			ASSERT(findex < hdr->nvalid);
> -			ASSERT(be16_to_cpu(bests[findex]) != NULLDATAOFF);
> -			ASSERT(be16_to_cpu(bests[findex]) >= length);
> +			ASSERT(be16_to_cpu(hdr->bests[findex]) != NULLDATAOFF);
> +			ASSERT(be16_to_cpu(hdr->bests[findex]) >= length);
>  			dbno = hdr->firstdb + findex;
>  			goto found_block;
>  		}
> @@ -1853,14 +1839,12 @@ xfs_dir2_node_find_freeblk(
>  		if (!fbp)
>  			continue;
>  
> -		free = fbp->b_addr;
> -		bests = dp->d_ops->free_bests_p(free);
> -		xfs_dir2_free_hdr_from_disk(dp->i_mount, hdr, free);
> +		xfs_dir2_free_hdr_from_disk(dp->i_mount, hdr, fbp->b_addr);
>  
>  		/* Scan the free entry array for a large enough free space. */
>  		for (findex = hdr->nvalid - 1; findex >= 0; findex--) {
> -			if (be16_to_cpu(bests[findex]) != NULLDATAOFF &&
> -			    be16_to_cpu(bests[findex]) >= length) {
> +			if (be16_to_cpu(hdr->bests[findex]) != NULLDATAOFF &&
> +			    be16_to_cpu(hdr->bests[findex]) >= length) {
>  				dbno = hdr->firstdb + findex;
>  				goto found_block;
>  			}
> @@ -1877,7 +1861,6 @@ xfs_dir2_node_find_freeblk(
>  	return 0;
>  }
>  
> -
>  /*
>   * Add the data entry for a node-format directory name addition.
>   * The leaf entry is added in xfs_dir2_leafn_add.
> @@ -1892,7 +1875,6 @@ xfs_dir2_node_addname_int(
>  	struct xfs_dir2_data_entry *dep;	/* data entry pointer */
>  	struct xfs_dir2_data_hdr *hdr;		/* data block header */
>  	struct xfs_dir2_data_free *bf;
> -	struct xfs_dir2_free	*free = NULL;	/* freespace block structure */
>  	struct xfs_trans	*tp = args->trans;
>  	struct xfs_inode	*dp = args->dp;
>  	struct xfs_dir3_icfree_hdr freehdr;
> @@ -1907,7 +1889,6 @@ xfs_dir2_node_addname_int(
>  	int			needlog = 0;	/* need to log data header */
>  	int			needscan = 0;	/* need to rescan data frees */
>  	__be16			*tagp;		/* data entry tag pointer */
> -	__be16			*bests;
>  
>  	length = dp->d_ops->data_entsize(args->namelen);
>  	error = xfs_dir2_node_find_freeblk(args, fblk, &dbno, &fbp, &freehdr,
> @@ -1978,16 +1959,14 @@ xfs_dir2_node_addname_int(
>  		xfs_dir2_data_log_header(args, dbp);
>  
>  	/* If the freespace block entry is now wrong, update it. */
> -	free = fbp->b_addr;
> -	bests = dp->d_ops->free_bests_p(free);
> -	if (bests[findex] != bf[0].length) {
> -		bests[findex] = bf[0].length;
> +	if (freehdr.bests[findex] != bf[0].length) {
> +		freehdr.bests[findex] = bf[0].length;
>  		logfree = 1;
>  	}
>  
>  	/* Log the freespace entry if needed. */
>  	if (logfree)
> -		xfs_dir2_free_log_bests(args, fbp, findex, findex);
> +		xfs_dir2_free_log_bests(args, &freehdr, fbp, findex, findex);
>  
>  	/* Return the data block and offset in args. */
>  	args->blkno = (xfs_dablk_t)dbno;
> diff --git a/fs/xfs/libxfs/xfs_dir2_priv.h b/fs/xfs/libxfs/xfs_dir2_priv.h
> index ef4a2b402e25..b73cf38c6969 100644
> --- a/fs/xfs/libxfs/xfs_dir2_priv.h
> +++ b/fs/xfs/libxfs/xfs_dir2_priv.h
> @@ -26,6 +26,7 @@ struct xfs_dir3_icfree_hdr {
>  	uint32_t		firstdb;
>  	uint32_t		nvalid;
>  	uint32_t		nused;
> +	__be16			*bests;
>  };
>  
>  /* xfs_dir2.c */
> diff --git a/fs/xfs/scrub/dir.c b/fs/xfs/scrub/dir.c
> index 6b8d9a774ddf..dfaa0fca617e 100644
> --- a/fs/xfs/scrub/dir.c
> +++ b/fs/xfs/scrub/dir.c
> @@ -581,7 +581,6 @@ xchk_directory_free_bestfree(
>  	struct xfs_dir3_icfree_hdr	freehdr;
>  	struct xfs_buf			*dbp;
>  	struct xfs_buf			*bp;
> -	__be16				*bestp;
>  	__u16				best;
>  	unsigned int			stale = 0;
>  	int				i;
> @@ -602,9 +601,8 @@ xchk_directory_free_bestfree(
>  
>  	/* Check all the entries. */
>  	xfs_dir2_free_hdr_from_disk(sc->ip->i_mount, &freehdr, bp->b_addr);
> -	bestp = sc->ip->d_ops->free_bests_p(bp->b_addr);
> -	for (i = 0; i < freehdr.nvalid; i++, bestp++) {
> -		best = be16_to_cpu(*bestp);
> +	for (i = 0; i < freehdr.nvalid; i++) {
> +		best = be16_to_cpu(freehdr.bests[i]);
>  		if (best == NULLDATAOFF) {
>  			stale++;
>  			continue;
> -- 
> 2.20.1
> 

^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH 16/34] xfs: move the dir2 free header size to struct xfs_da_geometry
  2019-11-01 22:07 ` [PATCH 16/34] xfs: move the dir2 free header size to struct xfs_da_geometry Christoph Hellwig
@ 2019-11-04 20:22   ` Darrick J. Wong
  0 siblings, 0 replies; 81+ messages in thread
From: Darrick J. Wong @ 2019-11-04 20:22 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-xfs

On Fri, Nov 01, 2019 at 03:07:01PM -0700, Christoph Hellwig wrote:
> Move the free header size towards our structure for dir/attr geometry
> parameters.
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
>  fs/xfs/libxfs/xfs_da_btree.h  | 1 +
>  fs/xfs/libxfs/xfs_da_format.c | 3 ---
>  fs/xfs/libxfs/xfs_dir2.c      | 2 ++
>  fs/xfs/libxfs/xfs_dir2.h      | 1 -
>  fs/xfs/libxfs/xfs_dir2_node.c | 2 +-
>  5 files changed, 4 insertions(+), 5 deletions(-)
> 
> diff --git a/fs/xfs/libxfs/xfs_da_btree.h b/fs/xfs/libxfs/xfs_da_btree.h
> index c8b137685ca7..3d0b1e97bf43 100644
> --- a/fs/xfs/libxfs/xfs_da_btree.h
> +++ b/fs/xfs/libxfs/xfs_da_btree.h
> @@ -29,6 +29,7 @@ struct xfs_da_geometry {
>  	int		leaf_hdr_size;	/* dir2 leaf header size */
>  	unsigned int	leaf_max_ents;	/* # of entries in dir2 leaf */
>  	xfs_dablk_t	leafblk;	/* blockno of leaf data v2 */
> +	int		free_hdr_size;	/* dir2 free header size */

Shouldn't this be unsigned?  Even if the original code wasn't this way?

Looks fine otherwise,

--D

>  	xfs_dablk_t	freeblk;	/* blockno of free data v2 */
>  };
>  
> diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c
> index 7263b6d6a135..1fc8982c830f 100644
> --- a/fs/xfs/libxfs/xfs_da_format.c
> +++ b/fs/xfs/libxfs/xfs_da_format.c
> @@ -486,7 +486,6 @@ static const struct xfs_dir_ops xfs_dir2_ops = {
>  	.data_entry_p = xfs_dir2_data_entry_p,
>  	.data_unused_p = xfs_dir2_data_unused_p,
>  
> -	.free_hdr_size = sizeof(struct xfs_dir2_free_hdr),
>  	.free_max_bests = xfs_dir2_free_max_bests,
>  	.db_to_fdb = xfs_dir2_db_to_fdb,
>  	.db_to_fdindex = xfs_dir2_db_to_fdindex,
> @@ -522,7 +521,6 @@ static const struct xfs_dir_ops xfs_dir2_ftype_ops = {
>  	.data_entry_p = xfs_dir2_data_entry_p,
>  	.data_unused_p = xfs_dir2_data_unused_p,
>  
> -	.free_hdr_size = sizeof(struct xfs_dir2_free_hdr),
>  	.free_max_bests = xfs_dir2_free_max_bests,
>  	.db_to_fdb = xfs_dir2_db_to_fdb,
>  	.db_to_fdindex = xfs_dir2_db_to_fdindex,
> @@ -558,7 +556,6 @@ static const struct xfs_dir_ops xfs_dir3_ops = {
>  	.data_entry_p = xfs_dir3_data_entry_p,
>  	.data_unused_p = xfs_dir3_data_unused_p,
>  
> -	.free_hdr_size = sizeof(struct xfs_dir3_free_hdr),
>  	.free_max_bests = xfs_dir3_free_max_bests,
>  	.db_to_fdb = xfs_dir3_db_to_fdb,
>  	.db_to_fdindex = xfs_dir3_db_to_fdindex,
> diff --git a/fs/xfs/libxfs/xfs_dir2.c b/fs/xfs/libxfs/xfs_dir2.c
> index 9f88b9885747..13ac228bfc86 100644
> --- a/fs/xfs/libxfs/xfs_dir2.c
> +++ b/fs/xfs/libxfs/xfs_dir2.c
> @@ -125,9 +125,11 @@ xfs_da_mount(
>  	if (xfs_sb_version_hascrc(&mp->m_sb)) {
>  		dageo->node_hdr_size = sizeof(struct xfs_da3_node_hdr);
>  		dageo->leaf_hdr_size = sizeof(struct xfs_dir3_leaf_hdr);
> +		dageo->free_hdr_size = sizeof(struct xfs_dir3_free_hdr);
>  	} else {
>  		dageo->node_hdr_size = sizeof(struct xfs_da_node_hdr);
>  		dageo->leaf_hdr_size = sizeof(struct xfs_dir2_leaf_hdr);
> +		dageo->free_hdr_size = sizeof(struct xfs_dir2_free_hdr);
>  	}
>  	dageo->leaf_max_ents = (dageo->blksize - dageo->leaf_hdr_size) /
>  			sizeof(struct xfs_dir2_leaf_entry);
> diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h
> index 402f00326b64..d87cd71e3cf1 100644
> --- a/fs/xfs/libxfs/xfs_dir2.h
> +++ b/fs/xfs/libxfs/xfs_dir2.h
> @@ -72,7 +72,6 @@ struct xfs_dir_ops {
>  	struct xfs_dir2_data_unused *
>  		(*data_unused_p)(struct xfs_dir2_data_hdr *hdr);
>  
> -	int	free_hdr_size;
>  	int	(*free_max_bests)(struct xfs_da_geometry *geo);
>  	xfs_dir2_db_t (*db_to_fdb)(struct xfs_da_geometry *geo,
>  				   xfs_dir2_db_t db);
> diff --git a/fs/xfs/libxfs/xfs_dir2_node.c b/fs/xfs/libxfs/xfs_dir2_node.c
> index eff7cfeb19b9..7047d1e066f9 100644
> --- a/fs/xfs/libxfs/xfs_dir2_node.c
> +++ b/fs/xfs/libxfs/xfs_dir2_node.c
> @@ -372,7 +372,7 @@ xfs_dir2_free_log_header(
>  	       free->hdr.magic == cpu_to_be32(XFS_DIR3_FREE_MAGIC));
>  #endif
>  	xfs_trans_log_buf(args->trans, bp, 0,
> -			  args->dp->d_ops->free_hdr_size - 1);
> +			  args->geo->free_hdr_size - 1);
>  }
>  
>  /*
> -- 
> 2.20.1
> 

^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH 17/34] xfs: move the max dir2 free bests count to struct xfs_da_geometry
  2019-11-01 22:07 ` [PATCH 17/34] xfs: move the max dir2 free bests count " Christoph Hellwig
@ 2019-11-04 20:23   ` Darrick J. Wong
  0 siblings, 0 replies; 81+ messages in thread
From: Darrick J. Wong @ 2019-11-04 20:23 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-xfs

On Fri, Nov 01, 2019 at 03:07:02PM -0700, Christoph Hellwig wrote:
> Move the max free bests count towards our structure for dir/attr
> geometry parameters.
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>

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

--D

> ---
>  fs/xfs/libxfs/xfs_da_btree.h  |  1 +
>  fs/xfs/libxfs/xfs_da_format.c | 29 ++++-------------------------
>  fs/xfs/libxfs/xfs_dir2.c      |  2 ++
>  fs/xfs/libxfs/xfs_dir2.h      |  1 -
>  fs/xfs/libxfs/xfs_dir2_node.c | 12 +++++-------
>  5 files changed, 12 insertions(+), 33 deletions(-)
> 
> diff --git a/fs/xfs/libxfs/xfs_da_btree.h b/fs/xfs/libxfs/xfs_da_btree.h
> index 3d0b1e97bf43..e3f4329ab882 100644
> --- a/fs/xfs/libxfs/xfs_da_btree.h
> +++ b/fs/xfs/libxfs/xfs_da_btree.h
> @@ -30,6 +30,7 @@ struct xfs_da_geometry {
>  	unsigned int	leaf_max_ents;	/* # of entries in dir2 leaf */
>  	xfs_dablk_t	leafblk;	/* blockno of leaf data v2 */
>  	int		free_hdr_size;	/* dir2 free header size */
> +	unsigned int	free_max_bests;	/* # of bests entries in dir2 free */
>  	xfs_dablk_t	freeblk;	/* blockno of free data v2 */
>  };
>  
> diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c
> index 1fc8982c830f..d2d3144c1598 100644
> --- a/fs/xfs/libxfs/xfs_da_format.c
> +++ b/fs/xfs/libxfs/xfs_da_format.c
> @@ -400,17 +400,6 @@ xfs_dir3_data_unused_p(struct xfs_dir2_data_hdr *hdr)
>  		((char *)hdr + sizeof(struct xfs_dir3_data_hdr));
>  }
>  
> -
> -/*
> - * Directory free space block operations
> - */
> -static int
> -xfs_dir2_free_max_bests(struct xfs_da_geometry *geo)
> -{
> -	return (geo->blksize - sizeof(struct xfs_dir2_free_hdr)) /
> -		sizeof(xfs_dir2_data_off_t);
> -}
> -
>  /*
>   * Convert data space db to the corresponding free db.
>   */
> @@ -418,7 +407,7 @@ static xfs_dir2_db_t
>  xfs_dir2_db_to_fdb(struct xfs_da_geometry *geo, xfs_dir2_db_t db)
>  {
>  	return xfs_dir2_byte_to_db(geo, XFS_DIR2_FREE_OFFSET) +
> -			(db / xfs_dir2_free_max_bests(geo));
> +			(db / geo->free_max_bests);
>  }
>  
>  /*
> @@ -427,14 +416,7 @@ xfs_dir2_db_to_fdb(struct xfs_da_geometry *geo, xfs_dir2_db_t db)
>  static int
>  xfs_dir2_db_to_fdindex(struct xfs_da_geometry *geo, xfs_dir2_db_t db)
>  {
> -	return db % xfs_dir2_free_max_bests(geo);
> -}
> -
> -static int
> -xfs_dir3_free_max_bests(struct xfs_da_geometry *geo)
> -{
> -	return (geo->blksize - sizeof(struct xfs_dir3_free_hdr)) /
> -		sizeof(xfs_dir2_data_off_t);
> +	return db % geo->free_max_bests;
>  }
>  
>  /*
> @@ -444,7 +426,7 @@ static xfs_dir2_db_t
>  xfs_dir3_db_to_fdb(struct xfs_da_geometry *geo, xfs_dir2_db_t db)
>  {
>  	return xfs_dir2_byte_to_db(geo, XFS_DIR2_FREE_OFFSET) +
> -			(db / xfs_dir3_free_max_bests(geo));
> +			(db / geo->free_max_bests);
>  }
>  
>  /*
> @@ -453,7 +435,7 @@ xfs_dir3_db_to_fdb(struct xfs_da_geometry *geo, xfs_dir2_db_t db)
>  static int
>  xfs_dir3_db_to_fdindex(struct xfs_da_geometry *geo, xfs_dir2_db_t db)
>  {
> -	return db % xfs_dir3_free_max_bests(geo);
> +	return db % geo->free_max_bests;
>  }
>  
>  static const struct xfs_dir_ops xfs_dir2_ops = {
> @@ -486,7 +468,6 @@ static const struct xfs_dir_ops xfs_dir2_ops = {
>  	.data_entry_p = xfs_dir2_data_entry_p,
>  	.data_unused_p = xfs_dir2_data_unused_p,
>  
> -	.free_max_bests = xfs_dir2_free_max_bests,
>  	.db_to_fdb = xfs_dir2_db_to_fdb,
>  	.db_to_fdindex = xfs_dir2_db_to_fdindex,
>  };
> @@ -521,7 +502,6 @@ static const struct xfs_dir_ops xfs_dir2_ftype_ops = {
>  	.data_entry_p = xfs_dir2_data_entry_p,
>  	.data_unused_p = xfs_dir2_data_unused_p,
>  
> -	.free_max_bests = xfs_dir2_free_max_bests,
>  	.db_to_fdb = xfs_dir2_db_to_fdb,
>  	.db_to_fdindex = xfs_dir2_db_to_fdindex,
>  };
> @@ -556,7 +536,6 @@ static const struct xfs_dir_ops xfs_dir3_ops = {
>  	.data_entry_p = xfs_dir3_data_entry_p,
>  	.data_unused_p = xfs_dir3_data_unused_p,
>  
> -	.free_max_bests = xfs_dir3_free_max_bests,
>  	.db_to_fdb = xfs_dir3_db_to_fdb,
>  	.db_to_fdindex = xfs_dir3_db_to_fdindex,
>  };
> diff --git a/fs/xfs/libxfs/xfs_dir2.c b/fs/xfs/libxfs/xfs_dir2.c
> index 13ac228bfc86..6c46893af17e 100644
> --- a/fs/xfs/libxfs/xfs_dir2.c
> +++ b/fs/xfs/libxfs/xfs_dir2.c
> @@ -133,6 +133,8 @@ xfs_da_mount(
>  	}
>  	dageo->leaf_max_ents = (dageo->blksize - dageo->leaf_hdr_size) /
>  			sizeof(struct xfs_dir2_leaf_entry);
> +	dageo->free_max_bests = (dageo->blksize - dageo->free_hdr_size) /
> +			sizeof(xfs_dir2_data_off_t);
>  
>  	/*
>  	 * Now we've set up the block conversion variables, we can calculate the
> diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h
> index d87cd71e3cf1..e3c1385d1522 100644
> --- a/fs/xfs/libxfs/xfs_dir2.h
> +++ b/fs/xfs/libxfs/xfs_dir2.h
> @@ -72,7 +72,6 @@ struct xfs_dir_ops {
>  	struct xfs_dir2_data_unused *
>  		(*data_unused_p)(struct xfs_dir2_data_hdr *hdr);
>  
> -	int	(*free_max_bests)(struct xfs_da_geometry *geo);
>  	xfs_dir2_db_t (*db_to_fdb)(struct xfs_da_geometry *geo,
>  				   xfs_dir2_db_t db);
>  	int	(*db_to_fdindex)(struct xfs_da_geometry *geo,
> diff --git a/fs/xfs/libxfs/xfs_dir2_node.c b/fs/xfs/libxfs/xfs_dir2_node.c
> index 7047d1e066f9..0fcd7351038e 100644
> --- a/fs/xfs/libxfs/xfs_dir2_node.c
> +++ b/fs/xfs/libxfs/xfs_dir2_node.c
> @@ -160,10 +160,9 @@ xfs_dir3_free_header_check(
>  	struct xfs_buf		*bp)
>  {
>  	struct xfs_mount	*mp = dp->i_mount;
> +	int			maxbests = mp->m_dir_geo->free_max_bests;
>  	unsigned int		firstdb;
> -	int			maxbests;
>  
> -	maxbests = dp->d_ops->free_max_bests(mp->m_dir_geo);
>  	firstdb = (xfs_dir2_da_to_db(mp->m_dir_geo, fbno) -
>  		   xfs_dir2_byte_to_db(mp->m_dir_geo, XFS_DIR2_FREE_OFFSET)) *
>  			maxbests;
> @@ -558,8 +557,7 @@ xfs_dir2_free_hdr_check(
>  
>  	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);
> +	ASSERT((hdr.firstdb % dp->i_mount->m_dir_geo->free_max_bests) == 0);
>  	ASSERT(hdr.firstdb <= db);
>  	ASSERT(db < hdr.firstdb + hdr.nvalid);
>  }
> @@ -1334,7 +1332,7 @@ xfs_dir2_leafn_remove(
>  		struct xfs_dir3_icfree_hdr freehdr;
>  
>  		xfs_dir2_free_hdr_from_disk(dp->i_mount, &freehdr, free);
> -		ASSERT(freehdr.firstdb == dp->d_ops->free_max_bests(args->geo) *
> +		ASSERT(freehdr.firstdb == args->geo->free_max_bests *
>  			(fdb - xfs_dir2_byte_to_db(args->geo,
>  						   XFS_DIR2_FREE_OFFSET)));
>  	}
> @@ -1727,7 +1725,7 @@ xfs_dir2_node_add_datablk(
>  		/* Remember the first slot as our empty slot. */
>  		hdr->firstdb = (fbno - xfs_dir2_byte_to_db(args->geo,
>  							XFS_DIR2_FREE_OFFSET)) *
> -				dp->d_ops->free_max_bests(args->geo);
> +				args->geo->free_max_bests;
>  	} else {
>  		xfs_dir2_free_hdr_from_disk(mp, hdr, fbp->b_addr);
>  	}
> @@ -1737,7 +1735,7 @@ xfs_dir2_node_add_datablk(
>  
>  	/* Extend the freespace table if the new data block is off the end. */
>  	if (*findex >= hdr->nvalid) {
> -		ASSERT(*findex < dp->d_ops->free_max_bests(args->geo));
> +		ASSERT(*findex < args->geo->free_max_bests);
>  		hdr->nvalid = *findex + 1;
>  		hdr->bests[*findex] = cpu_to_be16(NULLDATAOFF);
>  	}
> -- 
> 2.20.1
> 

^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH 14/34] xfs: make the xfs_dir3_icfree_hdr available to xfs_dir2_node_addname_int
  2019-11-01 22:06 ` [PATCH 14/34] xfs: make the xfs_dir3_icfree_hdr available to xfs_dir2_node_addname_int Christoph Hellwig
@ 2019-11-04 20:25   ` Darrick J. Wong
  2019-11-05  1:52     ` Christoph Hellwig
  0 siblings, 1 reply; 81+ messages in thread
From: Darrick J. Wong @ 2019-11-04 20:25 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-xfs

On Fri, Nov 01, 2019 at 03:06:59PM -0700, Christoph Hellwig wrote:
> Return the xfs_dir3_icfree_hdr used by the helpers called from
> xfs_dir2_node_addname_int to the main function to prepare for the
> next round of changes.

How does this help?  Is this purely to reduce stack usage?  Or will we
use this later to skip some xfs_dir2_free_hdr_from_disk calls?

--D

> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
>  fs/xfs/libxfs/xfs_dir2_node.c | 42 +++++++++++++++++------------------
>  1 file changed, 20 insertions(+), 22 deletions(-)
> 
> diff --git a/fs/xfs/libxfs/xfs_dir2_node.c b/fs/xfs/libxfs/xfs_dir2_node.c
> index 26032eba1e32..d400243c9556 100644
> --- a/fs/xfs/libxfs/xfs_dir2_node.c
> +++ b/fs/xfs/libxfs/xfs_dir2_node.c
> @@ -1660,14 +1660,13 @@ xfs_dir2_node_add_datablk(
>  	xfs_dir2_db_t		*dbno,
>  	struct xfs_buf		**dbpp,
>  	struct xfs_buf		**fbpp,
> +	struct xfs_dir3_icfree_hdr *hdr,
>  	int			*findex)
>  {
>  	struct xfs_inode	*dp = args->dp;
>  	struct xfs_trans	*tp = args->trans;
>  	struct xfs_mount	*mp = dp->i_mount;
> -	struct xfs_dir3_icfree_hdr freehdr;
>  	struct xfs_dir2_data_free *bf;
> -	struct xfs_dir2_data_hdr *hdr;
>  	struct xfs_dir2_free	*free = NULL;
>  	xfs_dir2_db_t		fbno;
>  	struct xfs_buf		*fbp;
> @@ -1730,25 +1729,25 @@ xfs_dir2_node_add_datablk(
>  			return error;
>  		free = fbp->b_addr;
>  		bests = dp->d_ops->free_bests_p(free);
> -		xfs_dir2_free_hdr_from_disk(mp, &freehdr, free);
> +		xfs_dir2_free_hdr_from_disk(mp, hdr, free);
>  
>  		/* Remember the first slot as our empty slot. */
> -		freehdr.firstdb = (fbno - xfs_dir2_byte_to_db(args->geo,
> +		hdr->firstdb = (fbno - xfs_dir2_byte_to_db(args->geo,
>  							XFS_DIR2_FREE_OFFSET)) *
>  				dp->d_ops->free_max_bests(args->geo);
>  	} else {
>  		free = fbp->b_addr;
>  		bests = dp->d_ops->free_bests_p(free);
> -		xfs_dir2_free_hdr_from_disk(mp, &freehdr, free);
> +		xfs_dir2_free_hdr_from_disk(mp, hdr, free);
>  	}
>  
>  	/* Set the freespace block index from the data block number. */
>  	*findex = dp->d_ops->db_to_fdindex(args->geo, *dbno);
>  
>  	/* Extend the freespace table if the new data block is off the end. */
> -	if (*findex >= freehdr.nvalid) {
> +	if (*findex >= hdr->nvalid) {
>  		ASSERT(*findex < dp->d_ops->free_max_bests(args->geo));
> -		freehdr.nvalid = *findex + 1;
> +		hdr->nvalid = *findex + 1;
>  		bests[*findex] = cpu_to_be16(NULLDATAOFF);
>  	}
>  
> @@ -1757,14 +1756,13 @@ xfs_dir2_node_add_datablk(
>  	 * true) then update the header.
>  	 */
>  	if (bests[*findex] == cpu_to_be16(NULLDATAOFF)) {
> -		freehdr.nused++;
> -		xfs_dir2_free_hdr_to_disk(mp, fbp->b_addr, &freehdr);
> +		hdr->nused++;
> +		xfs_dir2_free_hdr_to_disk(mp, fbp->b_addr, hdr);
>  		xfs_dir2_free_log_header(args, fbp);
>  	}
>  
>  	/* Update the freespace value for the new block in the table. */
> -	hdr = dbp->b_addr;
> -	bf = dp->d_ops->data_bestfree_p(hdr);
> +	bf = dp->d_ops->data_bestfree_p(dbp->b_addr);
>  	bests[*findex] = bf[0].length;
>  
>  	*dbpp = dbp;
> @@ -1778,10 +1776,10 @@ xfs_dir2_node_find_freeblk(
>  	struct xfs_da_state_blk	*fblk,
>  	xfs_dir2_db_t		*dbnop,
>  	struct xfs_buf		**fbpp,
> +	struct xfs_dir3_icfree_hdr *hdr,
>  	int			*findexp,
>  	int			length)
>  {
> -	struct xfs_dir3_icfree_hdr freehdr;
>  	struct xfs_dir2_free	*free = NULL;
>  	struct xfs_inode	*dp = args->dp;
>  	struct xfs_trans	*tp = args->trans;
> @@ -1808,13 +1806,12 @@ xfs_dir2_node_find_freeblk(
>  		if (findex >= 0) {
>  			/* caller already found the freespace for us. */
>  			bests = dp->d_ops->free_bests_p(free);
> -			xfs_dir2_free_hdr_from_disk(dp->i_mount, &freehdr,
> -						    free);
> +			xfs_dir2_free_hdr_from_disk(dp->i_mount, hdr, free);
>  
> -			ASSERT(findex < freehdr.nvalid);
> +			ASSERT(findex < hdr->nvalid);
>  			ASSERT(be16_to_cpu(bests[findex]) != NULLDATAOFF);
>  			ASSERT(be16_to_cpu(bests[findex]) >= length);
> -			dbno = freehdr.firstdb + findex;
> +			dbno = hdr->firstdb + findex;
>  			goto found_block;
>  		}
>  
> @@ -1858,13 +1855,13 @@ xfs_dir2_node_find_freeblk(
>  
>  		free = fbp->b_addr;
>  		bests = dp->d_ops->free_bests_p(free);
> -		xfs_dir2_free_hdr_from_disk(dp->i_mount, &freehdr, free);
> +		xfs_dir2_free_hdr_from_disk(dp->i_mount, hdr, free);
>  
>  		/* Scan the free entry array for a large enough free space. */
> -		for (findex = freehdr.nvalid - 1; findex >= 0; findex--) {
> +		for (findex = hdr->nvalid - 1; findex >= 0; findex--) {
>  			if (be16_to_cpu(bests[findex]) != NULLDATAOFF &&
>  			    be16_to_cpu(bests[findex]) >= length) {
> -				dbno = freehdr.firstdb + findex;
> +				dbno = hdr->firstdb + findex;
>  				goto found_block;
>  			}
>  		}
> @@ -1898,6 +1895,7 @@ xfs_dir2_node_addname_int(
>  	struct xfs_dir2_free	*free = NULL;	/* freespace block structure */
>  	struct xfs_trans	*tp = args->trans;
>  	struct xfs_inode	*dp = args->dp;
> +	struct xfs_dir3_icfree_hdr freehdr;
>  	struct xfs_buf		*dbp;		/* data block buffer */
>  	struct xfs_buf		*fbp;		/* freespace buffer */
>  	xfs_dir2_data_aoff_t	aoff;
> @@ -1912,8 +1910,8 @@ xfs_dir2_node_addname_int(
>  	__be16			*bests;
>  
>  	length = dp->d_ops->data_entsize(args->namelen);
> -	error = xfs_dir2_node_find_freeblk(args, fblk, &dbno, &fbp, &findex,
> -					   length);
> +	error = xfs_dir2_node_find_freeblk(args, fblk, &dbno, &fbp, &freehdr,
> +					   &findex, length);
>  	if (error)
>  		return error;
>  
> @@ -1935,7 +1933,7 @@ xfs_dir2_node_addname_int(
>  		/* we're going to have to log the free block index later */
>  		logfree = 1;
>  		error = xfs_dir2_node_add_datablk(args, fblk, &dbno, &dbp, &fbp,
> -						  &findex);
> +						  &freehdr, &findex);
>  	} else {
>  		/* Read the data block in. */
>  		error = xfs_dir3_data_read(tp, dp,
> -- 
> 2.20.1
> 

^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH 18/34] xfs: devirtualize ->db_to_fdb and ->db_to_fdindex
  2019-11-01 22:07 ` [PATCH 18/34] xfs: devirtualize ->db_to_fdb and ->db_to_fdindex Christoph Hellwig
@ 2019-11-04 20:26   ` Darrick J. Wong
  0 siblings, 0 replies; 81+ messages in thread
From: Darrick J. Wong @ 2019-11-04 20:26 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-xfs

On Fri, Nov 01, 2019 at 03:07:03PM -0700, Christoph Hellwig wrote:
> Now that the max bests value is in struct xfs_da_geometry both instances
> of ->db_to_fdb and ->db_to_fdindex are identical.  Replace them with
> local xfs_dir2_db_to_fdb and xfs_dir2_db_to_fdindex functions in
> xfs_dir2_node.c.
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>

Seems pretty straightforward,
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>

--D

> ---
>  fs/xfs/libxfs/xfs_da_format.c | 47 -----------------------------------
>  fs/xfs/libxfs/xfs_dir2.h      |  5 ----
>  fs/xfs/libxfs/xfs_dir2_node.c | 35 ++++++++++++++++++++------
>  3 files changed, 27 insertions(+), 60 deletions(-)
> 
> diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c
> index d2d3144c1598..2b708b9fae1a 100644
> --- a/fs/xfs/libxfs/xfs_da_format.c
> +++ b/fs/xfs/libxfs/xfs_da_format.c
> @@ -400,44 +400,6 @@ xfs_dir3_data_unused_p(struct xfs_dir2_data_hdr *hdr)
>  		((char *)hdr + sizeof(struct xfs_dir3_data_hdr));
>  }
>  
> -/*
> - * Convert data space db to the corresponding free db.
> - */
> -static xfs_dir2_db_t
> -xfs_dir2_db_to_fdb(struct xfs_da_geometry *geo, xfs_dir2_db_t db)
> -{
> -	return xfs_dir2_byte_to_db(geo, XFS_DIR2_FREE_OFFSET) +
> -			(db / geo->free_max_bests);
> -}
> -
> -/*
> - * Convert data space db to the corresponding index in a free db.
> - */
> -static int
> -xfs_dir2_db_to_fdindex(struct xfs_da_geometry *geo, xfs_dir2_db_t db)
> -{
> -	return db % geo->free_max_bests;
> -}
> -
> -/*
> - * Convert data space db to the corresponding free db.
> - */
> -static xfs_dir2_db_t
> -xfs_dir3_db_to_fdb(struct xfs_da_geometry *geo, xfs_dir2_db_t db)
> -{
> -	return xfs_dir2_byte_to_db(geo, XFS_DIR2_FREE_OFFSET) +
> -			(db / geo->free_max_bests);
> -}
> -
> -/*
> - * Convert data space db to the corresponding index in a free db.
> - */
> -static int
> -xfs_dir3_db_to_fdindex(struct xfs_da_geometry *geo, xfs_dir2_db_t db)
> -{
> -	return db % geo->free_max_bests;
> -}
> -
>  static const struct xfs_dir_ops xfs_dir2_ops = {
>  	.sf_entsize = xfs_dir2_sf_entsize,
>  	.sf_nextentry = xfs_dir2_sf_nextentry,
> @@ -467,9 +429,6 @@ static const struct xfs_dir_ops xfs_dir2_ops = {
>  	.data_first_entry_p = xfs_dir2_data_first_entry_p,
>  	.data_entry_p = xfs_dir2_data_entry_p,
>  	.data_unused_p = xfs_dir2_data_unused_p,
> -
> -	.db_to_fdb = xfs_dir2_db_to_fdb,
> -	.db_to_fdindex = xfs_dir2_db_to_fdindex,
>  };
>  
>  static const struct xfs_dir_ops xfs_dir2_ftype_ops = {
> @@ -501,9 +460,6 @@ static const struct xfs_dir_ops xfs_dir2_ftype_ops = {
>  	.data_first_entry_p = xfs_dir2_ftype_data_first_entry_p,
>  	.data_entry_p = xfs_dir2_data_entry_p,
>  	.data_unused_p = xfs_dir2_data_unused_p,
> -
> -	.db_to_fdb = xfs_dir2_db_to_fdb,
> -	.db_to_fdindex = xfs_dir2_db_to_fdindex,
>  };
>  
>  static const struct xfs_dir_ops xfs_dir3_ops = {
> @@ -535,9 +491,6 @@ static const struct xfs_dir_ops xfs_dir3_ops = {
>  	.data_first_entry_p = xfs_dir3_data_first_entry_p,
>  	.data_entry_p = xfs_dir3_data_entry_p,
>  	.data_unused_p = xfs_dir3_data_unused_p,
> -
> -	.db_to_fdb = xfs_dir3_db_to_fdb,
> -	.db_to_fdindex = xfs_dir3_db_to_fdindex,
>  };
>  
>  /*
> diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h
> index e3c1385d1522..e302679d8c80 100644
> --- a/fs/xfs/libxfs/xfs_dir2.h
> +++ b/fs/xfs/libxfs/xfs_dir2.h
> @@ -71,11 +71,6 @@ struct xfs_dir_ops {
>  		(*data_entry_p)(struct xfs_dir2_data_hdr *hdr);
>  	struct xfs_dir2_data_unused *
>  		(*data_unused_p)(struct xfs_dir2_data_hdr *hdr);
> -
> -	xfs_dir2_db_t (*db_to_fdb)(struct xfs_da_geometry *geo,
> -				   xfs_dir2_db_t db);
> -	int	(*db_to_fdindex)(struct xfs_da_geometry *geo,
> -				 xfs_dir2_db_t db);
>  };
>  
>  extern const struct xfs_dir_ops *
> diff --git a/fs/xfs/libxfs/xfs_dir2_node.c b/fs/xfs/libxfs/xfs_dir2_node.c
> index 0fcd7351038e..ceb5936b58dd 100644
> --- a/fs/xfs/libxfs/xfs_dir2_node.c
> +++ b/fs/xfs/libxfs/xfs_dir2_node.c
> @@ -33,6 +33,25 @@ static int xfs_dir2_leafn_remove(xfs_da_args_t *args, struct xfs_buf *bp,
>  				 int index, xfs_da_state_blk_t *dblk,
>  				 int *rval);
>  
> +/*
> + * Convert data space db to the corresponding free db.
> + */
> +static xfs_dir2_db_t
> +xfs_dir2_db_to_fdb(struct xfs_da_geometry *geo, xfs_dir2_db_t db)
> +{
> +	return xfs_dir2_byte_to_db(geo, XFS_DIR2_FREE_OFFSET) +
> +			(db / geo->free_max_bests);
> +}
> +
> +/*
> + * Convert data space db to the corresponding index in a free db.
> + */
> +static int
> +xfs_dir2_db_to_fdindex(struct xfs_da_geometry *geo, xfs_dir2_db_t db)
> +{
> +	return db % geo->free_max_bests;
> +}
> +
>  /*
>   * Check internal consistency of a leafn block.
>   */
> @@ -676,7 +695,7 @@ xfs_dir2_leafn_lookup_for_addname(
>  			 * Convert the data block to the free block
>  			 * holding its freespace information.
>  			 */
> -			newfdb = dp->d_ops->db_to_fdb(args->geo, newdb);
> +			newfdb = xfs_dir2_db_to_fdb(args->geo, newdb);
>  			/*
>  			 * If it's not the one we have in hand, read it in.
>  			 */
> @@ -700,7 +719,7 @@ xfs_dir2_leafn_lookup_for_addname(
>  			/*
>  			 * Get the index for our entry.
>  			 */
> -			fi = dp->d_ops->db_to_fdindex(args->geo, curdb);
> +			fi = xfs_dir2_db_to_fdindex(args->geo, curdb);
>  			/*
>  			 * If it has room, return it.
>  			 */
> @@ -1320,7 +1339,7 @@ xfs_dir2_leafn_remove(
>  		 * Convert the data block number to a free block,
>  		 * read in the free block.
>  		 */
> -		fdb = dp->d_ops->db_to_fdb(args->geo, db);
> +		fdb = xfs_dir2_db_to_fdb(args->geo, db);
>  		error = xfs_dir2_free_read(tp, dp,
>  					   xfs_dir2_db_to_da(args->geo, fdb),
>  					   &fbp);
> @@ -1340,7 +1359,7 @@ xfs_dir2_leafn_remove(
>  		/*
>  		 * Calculate which entry we need to fix.
>  		 */
> -		findex = dp->d_ops->db_to_fdindex(args->geo, db);
> +		findex = xfs_dir2_db_to_fdindex(args->geo, db);
>  		longest = be16_to_cpu(bf[0].length);
>  		/*
>  		 * If the data block is now empty we can get rid of it
> @@ -1683,7 +1702,7 @@ xfs_dir2_node_add_datablk(
>  	 * Get the freespace block corresponding to the data block
>  	 * that was just allocated.
>  	 */
> -	fbno = dp->d_ops->db_to_fdb(args->geo, *dbno);
> +	fbno = xfs_dir2_db_to_fdb(args->geo, *dbno);
>  	error = xfs_dir2_free_try_read(tp, dp,
>  			       xfs_dir2_db_to_da(args->geo, fbno), &fbp);
>  	if (error)
> @@ -1698,11 +1717,11 @@ xfs_dir2_node_add_datablk(
>  		if (error)
>  			return error;
>  
> -		if (dp->d_ops->db_to_fdb(args->geo, *dbno) != fbno) {
> +		if (xfs_dir2_db_to_fdb(args->geo, *dbno) != fbno) {
>  			xfs_alert(mp,
>  "%s: dir ino %llu needed freesp block %lld for data block %lld, got %lld",
>  				__func__, (unsigned long long)dp->i_ino,
> -				(long long)dp->d_ops->db_to_fdb(args->geo, *dbno),
> +				(long long)xfs_dir2_db_to_fdb(args->geo, *dbno),
>  				(long long)*dbno, (long long)fbno);
>  			if (fblk) {
>  				xfs_alert(mp,
> @@ -1731,7 +1750,7 @@ xfs_dir2_node_add_datablk(
>  	}
>  
>  	/* Set the freespace block index from the data block number. */
> -	*findex = dp->d_ops->db_to_fdindex(args->geo, *dbno);
> +	*findex = xfs_dir2_db_to_fdindex(args->geo, *dbno);
>  
>  	/* Extend the freespace table if the new data block is off the end. */
>  	if (*findex >= hdr->nvalid) {
> -- 
> 2.20.1
> 

^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH 19/34] xfs: devirtualize ->sf_get_parent_ino and ->sf_put_parent_ino
  2019-11-01 22:07 ` [PATCH 19/34] xfs: devirtualize ->sf_get_parent_ino and ->sf_put_parent_ino Christoph Hellwig
@ 2019-11-04 20:26   ` Darrick J. Wong
  0 siblings, 0 replies; 81+ messages in thread
From: Darrick J. Wong @ 2019-11-04 20:26 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-xfs

On Fri, Nov 01, 2019 at 03:07:04PM -0700, Christoph Hellwig wrote:
> The parent inode handling is the same for all directory format variants,
> just use direct calls instead of going through a pointless indirect
> call.
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>

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

--D

> ---
>  fs/xfs/libxfs/xfs_da_format.c  | 10 ++--------
>  fs/xfs/libxfs/xfs_dir2.h       |  3 ---
>  fs/xfs/libxfs/xfs_dir2_block.c |  2 +-
>  fs/xfs/libxfs/xfs_dir2_priv.h  |  2 ++
>  fs/xfs/libxfs/xfs_dir2_sf.c    | 20 ++++++++++----------
>  fs/xfs/xfs_dir2_readdir.c      |  2 +-
>  6 files changed, 16 insertions(+), 23 deletions(-)
> 
> diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c
> index 2b708b9fae1a..7858469c09e4 100644
> --- a/fs/xfs/libxfs/xfs_da_format.c
> +++ b/fs/xfs/libxfs/xfs_da_format.c
> @@ -132,14 +132,14 @@ xfs_dir2_sf_put_ino(
>  		put_unaligned_be32(ino, to);
>  }
>  
> -static xfs_ino_t
> +xfs_ino_t
>  xfs_dir2_sf_get_parent_ino(
>  	struct xfs_dir2_sf_hdr	*hdr)
>  {
>  	return xfs_dir2_sf_get_ino(hdr, hdr->parent);
>  }
>  
> -static void
> +void
>  xfs_dir2_sf_put_parent_ino(
>  	struct xfs_dir2_sf_hdr	*hdr,
>  	xfs_ino_t		ino)
> @@ -407,8 +407,6 @@ static const struct xfs_dir_ops xfs_dir2_ops = {
>  	.sf_put_ftype = xfs_dir2_sfe_put_ftype,
>  	.sf_get_ino = xfs_dir2_sfe_get_ino,
>  	.sf_put_ino = xfs_dir2_sfe_put_ino,
> -	.sf_get_parent_ino = xfs_dir2_sf_get_parent_ino,
> -	.sf_put_parent_ino = xfs_dir2_sf_put_parent_ino,
>  
>  	.data_entsize = xfs_dir2_data_entsize,
>  	.data_get_ftype = xfs_dir2_data_get_ftype,
> @@ -438,8 +436,6 @@ static const struct xfs_dir_ops xfs_dir2_ftype_ops = {
>  	.sf_put_ftype = xfs_dir3_sfe_put_ftype,
>  	.sf_get_ino = xfs_dir3_sfe_get_ino,
>  	.sf_put_ino = xfs_dir3_sfe_put_ino,
> -	.sf_get_parent_ino = xfs_dir2_sf_get_parent_ino,
> -	.sf_put_parent_ino = xfs_dir2_sf_put_parent_ino,
>  
>  	.data_entsize = xfs_dir3_data_entsize,
>  	.data_get_ftype = xfs_dir3_data_get_ftype,
> @@ -469,8 +465,6 @@ static const struct xfs_dir_ops xfs_dir3_ops = {
>  	.sf_put_ftype = xfs_dir3_sfe_put_ftype,
>  	.sf_get_ino = xfs_dir3_sfe_get_ino,
>  	.sf_put_ino = xfs_dir3_sfe_put_ino,
> -	.sf_get_parent_ino = xfs_dir2_sf_get_parent_ino,
> -	.sf_put_parent_ino = xfs_dir2_sf_put_parent_ino,
>  
>  	.data_entsize = xfs_dir3_data_entsize,
>  	.data_get_ftype = xfs_dir3_data_get_ftype,
> diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h
> index e302679d8c80..d3a0b8daab5f 100644
> --- a/fs/xfs/libxfs/xfs_dir2.h
> +++ b/fs/xfs/libxfs/xfs_dir2.h
> @@ -44,9 +44,6 @@ struct xfs_dir_ops {
>  	void	(*sf_put_ino)(struct xfs_dir2_sf_hdr *hdr,
>  			      struct xfs_dir2_sf_entry *sfep,
>  			      xfs_ino_t ino);
> -	xfs_ino_t (*sf_get_parent_ino)(struct xfs_dir2_sf_hdr *hdr);
> -	void	(*sf_put_parent_ino)(struct xfs_dir2_sf_hdr *hdr,
> -				     xfs_ino_t ino);
>  
>  	int	(*data_entsize)(int len);
>  	uint8_t (*data_get_ftype)(struct xfs_dir2_data_entry *dep);
> diff --git a/fs/xfs/libxfs/xfs_dir2_block.c b/fs/xfs/libxfs/xfs_dir2_block.c
> index 38886b9c7b48..2ee9fdd182e1 100644
> --- a/fs/xfs/libxfs/xfs_dir2_block.c
> +++ b/fs/xfs/libxfs/xfs_dir2_block.c
> @@ -1163,7 +1163,7 @@ xfs_dir2_sf_to_block(
>  	 * Create entry for ..
>  	 */
>  	dep = dp->d_ops->data_dotdot_entry_p(hdr);
> -	dep->inumber = cpu_to_be64(dp->d_ops->sf_get_parent_ino(sfp));
> +	dep->inumber = cpu_to_be64(xfs_dir2_sf_get_parent_ino(sfp));
>  	dep->namelen = 2;
>  	dep->name[0] = dep->name[1] = '.';
>  	dp->d_ops->data_put_ftype(dep, XFS_DIR3_FT_DIR);
> diff --git a/fs/xfs/libxfs/xfs_dir2_priv.h b/fs/xfs/libxfs/xfs_dir2_priv.h
> index b73cf38c6969..d5104fdb8543 100644
> --- a/fs/xfs/libxfs/xfs_dir2_priv.h
> +++ b/fs/xfs/libxfs/xfs_dir2_priv.h
> @@ -135,6 +135,8 @@ extern int xfs_dir2_free_read(struct xfs_trans *tp, struct xfs_inode *dp,
>  		xfs_dablk_t fbno, struct xfs_buf **bpp);
>  
>  /* xfs_dir2_sf.c */
> +xfs_ino_t xfs_dir2_sf_get_parent_ino(struct xfs_dir2_sf_hdr *hdr);
> +void xfs_dir2_sf_put_parent_ino(struct xfs_dir2_sf_hdr *hdr, xfs_ino_t ino);
>  extern int xfs_dir2_block_sfsize(struct xfs_inode *dp,
>  		struct xfs_dir2_data_hdr *block, struct xfs_dir2_sf_hdr *sfhp);
>  extern int xfs_dir2_block_to_sf(struct xfs_da_args *args, struct xfs_buf *bp,
> diff --git a/fs/xfs/libxfs/xfs_dir2_sf.c b/fs/xfs/libxfs/xfs_dir2_sf.c
> index ae16ca7c422a..1d7c26d0157c 100644
> --- a/fs/xfs/libxfs/xfs_dir2_sf.c
> +++ b/fs/xfs/libxfs/xfs_dir2_sf.c
> @@ -125,7 +125,7 @@ xfs_dir2_block_sfsize(
>  	 */
>  	sfhp->count = count;
>  	sfhp->i8count = i8count;
> -	dp->d_ops->sf_put_parent_ino(sfhp, parent);
> +	xfs_dir2_sf_put_parent_ino(sfhp, parent);
>  	return size;
>  }
>  
> @@ -204,7 +204,7 @@ xfs_dir2_block_to_sf(
>  		else if (dep->namelen == 2 &&
>  			 dep->name[0] == '.' && dep->name[1] == '.')
>  			ASSERT(be64_to_cpu(dep->inumber) ==
> -			       dp->d_ops->sf_get_parent_ino(sfp));
> +			       xfs_dir2_sf_get_parent_ino(sfp));
>  		/*
>  		 * Normal entry, copy it into shortform.
>  		 */
> @@ -590,7 +590,7 @@ xfs_dir2_sf_check(
>  
>  	sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data;
>  	offset = dp->d_ops->data_first_offset;
> -	ino = dp->d_ops->sf_get_parent_ino(sfp);
> +	ino = xfs_dir2_sf_get_parent_ino(sfp);
>  	i8count = ino > XFS_DIR2_MAX_SHORT_INUM;
>  
>  	for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp);
> @@ -653,7 +653,7 @@ xfs_dir2_sf_verify(
>  	endp = (char *)sfp + size;
>  
>  	/* Check .. entry */
> -	ino = dops->sf_get_parent_ino(sfp);
> +	ino = xfs_dir2_sf_get_parent_ino(sfp);
>  	i8count = ino > XFS_DIR2_MAX_SHORT_INUM;
>  	error = xfs_dir_ino_validate(mp, ino);
>  	if (error)
> @@ -763,7 +763,7 @@ xfs_dir2_sf_create(
>  	/*
>  	 * Now can put in the inode number, since i8count is set.
>  	 */
> -	dp->d_ops->sf_put_parent_ino(sfp, pino);
> +	xfs_dir2_sf_put_parent_ino(sfp, pino);
>  	sfp->count = 0;
>  	dp->i_d.di_size = size;
>  	xfs_dir2_sf_check(args);
> @@ -818,7 +818,7 @@ xfs_dir2_sf_lookup(
>  	 */
>  	if (args->namelen == 2 &&
>  	    args->name[0] == '.' && args->name[1] == '.') {
> -		args->inumber = dp->d_ops->sf_get_parent_ino(sfp);
> +		args->inumber = xfs_dir2_sf_get_parent_ino(sfp);
>  		args->cmpresult = XFS_CMP_EXACT;
>  		args->filetype = XFS_DIR3_FT_DIR;
>  		return -EEXIST;
> @@ -1008,9 +1008,9 @@ xfs_dir2_sf_replace(
>  	 */
>  	if (args->namelen == 2 &&
>  	    args->name[0] == '.' && args->name[1] == '.') {
> -		ino = dp->d_ops->sf_get_parent_ino(sfp);
> +		ino = xfs_dir2_sf_get_parent_ino(sfp);
>  		ASSERT(args->inumber != ino);
> -		dp->d_ops->sf_put_parent_ino(sfp, args->inumber);
> +		xfs_dir2_sf_put_parent_ino(sfp, args->inumber);
>  	}
>  	/*
>  	 * Normal entry, look for the name.
> @@ -1116,7 +1116,7 @@ xfs_dir2_sf_toino4(
>  	 */
>  	sfp->count = oldsfp->count;
>  	sfp->i8count = 0;
> -	dp->d_ops->sf_put_parent_ino(sfp, dp->d_ops->sf_get_parent_ino(oldsfp));
> +	xfs_dir2_sf_put_parent_ino(sfp, xfs_dir2_sf_get_parent_ino(oldsfp));
>  	/*
>  	 * Copy the entries field by field.
>  	 */
> @@ -1189,7 +1189,7 @@ xfs_dir2_sf_toino8(
>  	 */
>  	sfp->count = oldsfp->count;
>  	sfp->i8count = 1;
> -	dp->d_ops->sf_put_parent_ino(sfp, dp->d_ops->sf_get_parent_ino(oldsfp));
> +	xfs_dir2_sf_put_parent_ino(sfp, xfs_dir2_sf_get_parent_ino(oldsfp));
>  	/*
>  	 * Copy the entries field by field.
>  	 */
> diff --git a/fs/xfs/xfs_dir2_readdir.c b/fs/xfs/xfs_dir2_readdir.c
> index a0bec0931f3b..6f94d2a45174 100644
> --- a/fs/xfs/xfs_dir2_readdir.c
> +++ b/fs/xfs/xfs_dir2_readdir.c
> @@ -92,7 +92,7 @@ xfs_dir2_sf_getdents(
>  	 * Put .. entry unless we're starting past it.
>  	 */
>  	if (ctx->pos <= dotdot_offset) {
> -		ino = dp->d_ops->sf_get_parent_ino(sfp);
> +		ino = xfs_dir2_sf_get_parent_ino(sfp);
>  		ctx->pos = dotdot_offset & 0x7fffffff;
>  		if (!dir_emit(ctx, "..", 2, ino, DT_DIR))
>  			return 0;
> -- 
> 2.20.1
> 

^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH 20/34] xfs: devirtualize ->sf_entsize and ->sf_nextentry
  2019-11-01 22:07 ` [PATCH 20/34] xfs: devirtualize ->sf_entsize and ->sf_nextentry Christoph Hellwig
@ 2019-11-04 20:28   ` Darrick J. Wong
  0 siblings, 0 replies; 81+ messages in thread
From: Darrick J. Wong @ 2019-11-04 20:28 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-xfs

On Fri, Nov 01, 2019 at 03:07:05PM -0700, Christoph Hellwig wrote:
> Just check for file-type enabled directories directly.
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>

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

--D

> ---
>  fs/xfs/libxfs/xfs_da_format.c  | 48 -----------------
>  fs/xfs/libxfs/xfs_dir2.h       |  4 --
>  fs/xfs/libxfs/xfs_dir2_block.c |  2 +-
>  fs/xfs/libxfs/xfs_dir2_priv.h  |  2 +
>  fs/xfs/libxfs/xfs_dir2_sf.c    | 99 ++++++++++++++++++++--------------
>  fs/xfs/xfs_dir2_readdir.c      |  7 +--
>  6 files changed, 66 insertions(+), 96 deletions(-)
> 
> diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c
> index 7858469c09e4..f80495a38a76 100644
> --- a/fs/xfs/libxfs/xfs_da_format.c
> +++ b/fs/xfs/libxfs/xfs_da_format.c
> @@ -15,48 +15,6 @@
>  #include "xfs_dir2.h"
>  #include "xfs_dir2_priv.h"
>  
> -/*
> - * Shortform directory ops
> - */
> -static int
> -xfs_dir2_sf_entsize(
> -	struct xfs_dir2_sf_hdr	*hdr,
> -	int			len)
> -{
> -	int count = sizeof(struct xfs_dir2_sf_entry);	/* namelen + offset */
> -
> -	count += len;					/* name */
> -	count += hdr->i8count ? XFS_INO64_SIZE : XFS_INO32_SIZE; /* ino # */
> -	return count;
> -}
> -
> -static int
> -xfs_dir3_sf_entsize(
> -	struct xfs_dir2_sf_hdr	*hdr,
> -	int			len)
> -{
> -	return xfs_dir2_sf_entsize(hdr, len) + sizeof(uint8_t);
> -}
> -
> -static struct xfs_dir2_sf_entry *
> -xfs_dir2_sf_nextentry(
> -	struct xfs_dir2_sf_hdr	*hdr,
> -	struct xfs_dir2_sf_entry *sfep)
> -{
> -	return (struct xfs_dir2_sf_entry *)
> -		((char *)sfep + xfs_dir2_sf_entsize(hdr, sfep->namelen));
> -}
> -
> -static struct xfs_dir2_sf_entry *
> -xfs_dir3_sf_nextentry(
> -	struct xfs_dir2_sf_hdr	*hdr,
> -	struct xfs_dir2_sf_entry *sfep)
> -{
> -	return (struct xfs_dir2_sf_entry *)
> -		((char *)sfep + xfs_dir3_sf_entsize(hdr, sfep->namelen));
> -}
> -
> -
>  /*
>   * For filetype enabled shortform directories, the file type field is stored at
>   * the end of the name.  Because it's only a single byte, endian conversion is
> @@ -401,8 +359,6 @@ xfs_dir3_data_unused_p(struct xfs_dir2_data_hdr *hdr)
>  }
>  
>  static const struct xfs_dir_ops xfs_dir2_ops = {
> -	.sf_entsize = xfs_dir2_sf_entsize,
> -	.sf_nextentry = xfs_dir2_sf_nextentry,
>  	.sf_get_ftype = xfs_dir2_sfe_get_ftype,
>  	.sf_put_ftype = xfs_dir2_sfe_put_ftype,
>  	.sf_get_ino = xfs_dir2_sfe_get_ino,
> @@ -430,8 +386,6 @@ static const struct xfs_dir_ops xfs_dir2_ops = {
>  };
>  
>  static const struct xfs_dir_ops xfs_dir2_ftype_ops = {
> -	.sf_entsize = xfs_dir3_sf_entsize,
> -	.sf_nextentry = xfs_dir3_sf_nextentry,
>  	.sf_get_ftype = xfs_dir3_sfe_get_ftype,
>  	.sf_put_ftype = xfs_dir3_sfe_put_ftype,
>  	.sf_get_ino = xfs_dir3_sfe_get_ino,
> @@ -459,8 +413,6 @@ static const struct xfs_dir_ops xfs_dir2_ftype_ops = {
>  };
>  
>  static const struct xfs_dir_ops xfs_dir3_ops = {
> -	.sf_entsize = xfs_dir3_sf_entsize,
> -	.sf_nextentry = xfs_dir3_sf_nextentry,
>  	.sf_get_ftype = xfs_dir3_sfe_get_ftype,
>  	.sf_put_ftype = xfs_dir3_sfe_put_ftype,
>  	.sf_get_ino = xfs_dir3_sfe_get_ino,
> diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h
> index d3a0b8daab5f..c99f0ad6607a 100644
> --- a/fs/xfs/libxfs/xfs_dir2.h
> +++ b/fs/xfs/libxfs/xfs_dir2.h
> @@ -32,10 +32,6 @@ extern unsigned char xfs_mode_to_ftype(int mode);
>   * directory operations vector for encode/decode routines
>   */
>  struct xfs_dir_ops {
> -	int	(*sf_entsize)(struct xfs_dir2_sf_hdr *hdr, int len);
> -	struct xfs_dir2_sf_entry *
> -		(*sf_nextentry)(struct xfs_dir2_sf_hdr *hdr,
> -				struct xfs_dir2_sf_entry *sfep);
>  	uint8_t (*sf_get_ftype)(struct xfs_dir2_sf_entry *sfep);
>  	void	(*sf_put_ftype)(struct xfs_dir2_sf_entry *sfep,
>  				uint8_t ftype);
> diff --git a/fs/xfs/libxfs/xfs_dir2_block.c b/fs/xfs/libxfs/xfs_dir2_block.c
> index 2ee9fdd182e1..88b3d1884c74 100644
> --- a/fs/xfs/libxfs/xfs_dir2_block.c
> +++ b/fs/xfs/libxfs/xfs_dir2_block.c
> @@ -1231,7 +1231,7 @@ xfs_dir2_sf_to_block(
>  		if (++i == sfp->count)
>  			sfep = NULL;
>  		else
> -			sfep = dp->d_ops->sf_nextentry(sfp, sfep);
> +			sfep = xfs_dir2_sf_nextentry(mp, sfp, sfep);
>  	}
>  	/* Done with the temporary buffer */
>  	kmem_free(sfp);
> diff --git a/fs/xfs/libxfs/xfs_dir2_priv.h b/fs/xfs/libxfs/xfs_dir2_priv.h
> index d5104fdb8543..a96b9ba7909b 100644
> --- a/fs/xfs/libxfs/xfs_dir2_priv.h
> +++ b/fs/xfs/libxfs/xfs_dir2_priv.h
> @@ -137,6 +137,8 @@ extern int xfs_dir2_free_read(struct xfs_trans *tp, struct xfs_inode *dp,
>  /* xfs_dir2_sf.c */
>  xfs_ino_t xfs_dir2_sf_get_parent_ino(struct xfs_dir2_sf_hdr *hdr);
>  void xfs_dir2_sf_put_parent_ino(struct xfs_dir2_sf_hdr *hdr, xfs_ino_t ino);
> +struct xfs_dir2_sf_entry *xfs_dir2_sf_nextentry(struct xfs_mount *mp,
> +		struct xfs_dir2_sf_hdr *hdr, struct xfs_dir2_sf_entry *sfep);
>  extern int xfs_dir2_block_sfsize(struct xfs_inode *dp,
>  		struct xfs_dir2_data_hdr *block, struct xfs_dir2_sf_hdr *sfhp);
>  extern int xfs_dir2_block_to_sf(struct xfs_da_args *args, struct xfs_buf *bp,
> diff --git a/fs/xfs/libxfs/xfs_dir2_sf.c b/fs/xfs/libxfs/xfs_dir2_sf.c
> index 1d7c26d0157c..f3a4f0ddfc1a 100644
> --- a/fs/xfs/libxfs/xfs_dir2_sf.c
> +++ b/fs/xfs/libxfs/xfs_dir2_sf.c
> @@ -37,6 +37,32 @@ static void xfs_dir2_sf_check(xfs_da_args_t *args);
>  static void xfs_dir2_sf_toino4(xfs_da_args_t *args);
>  static void xfs_dir2_sf_toino8(xfs_da_args_t *args);
>  
> +static int
> +xfs_dir2_sf_entsize(
> +	struct xfs_mount	*mp,
> +	struct xfs_dir2_sf_hdr	*hdr,
> +	int			len)
> +{
> +	int			count = len;
> +
> +	count += sizeof(struct xfs_dir2_sf_entry);	/* namelen + offset */
> +	count += hdr->i8count ? XFS_INO64_SIZE : XFS_INO32_SIZE; /* ino # */
> +
> +	if (xfs_sb_version_hasftype(&mp->m_sb))
> +		count += sizeof(uint8_t);
> +	return count;
> +}
> +
> +struct xfs_dir2_sf_entry *
> +xfs_dir2_sf_nextentry(
> +	struct xfs_mount	*mp,
> +	struct xfs_dir2_sf_hdr	*hdr,
> +	struct xfs_dir2_sf_entry *sfep)
> +{
> +	return (struct xfs_dir2_sf_entry *)
> +		((char *)sfep + xfs_dir2_sf_entsize(mp, hdr, sfep->namelen));
> +}
> +
>  /*
>   * Given a block directory (dp/block), calculate its size as a shortform (sf)
>   * directory and a header for the sf directory, if it will fit it the
> @@ -219,7 +245,7 @@ xfs_dir2_block_to_sf(
>  			dp->d_ops->sf_put_ftype(sfep,
>  					dp->d_ops->data_get_ftype(dep));
>  
> -			sfep = dp->d_ops->sf_nextentry(sfp, sfep);
> +			sfep = xfs_dir2_sf_nextentry(mp, sfp, sfep);
>  		}
>  		ptr += dp->d_ops->data_entsize(dep->namelen);
>  	}
> @@ -291,7 +317,7 @@ xfs_dir2_sf_addname(
>  	/*
>  	 * Compute entry (and change in) size.
>  	 */
> -	incr_isize = dp->d_ops->sf_entsize(sfp, args->namelen);
> +	incr_isize = xfs_dir2_sf_entsize(dp->i_mount, sfp, args->namelen);
>  	objchange = 0;
>  
>  	/*
> @@ -364,18 +390,17 @@ xfs_dir2_sf_addname_easy(
>  	xfs_dir2_data_aoff_t	offset,		/* offset to use for new ent */
>  	int			new_isize)	/* new directory size */
>  {
> +	struct xfs_inode	*dp = args->dp;
> +	struct xfs_mount	*mp = dp->i_mount;
>  	int			byteoff;	/* byte offset in sf dir */
> -	xfs_inode_t		*dp;		/* incore directory inode */
>  	xfs_dir2_sf_hdr_t	*sfp;		/* shortform structure */
>  
> -	dp = args->dp;
> -
>  	sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data;
>  	byteoff = (int)((char *)sfep - (char *)sfp);
>  	/*
>  	 * Grow the in-inode space.
>  	 */
> -	xfs_idata_realloc(dp, dp->d_ops->sf_entsize(sfp, args->namelen),
> +	xfs_idata_realloc(dp, xfs_dir2_sf_entsize(mp, sfp, args->namelen),
>  			  XFS_DATA_FORK);
>  	/*
>  	 * Need to set up again due to realloc of the inode data.
> @@ -416,9 +441,10 @@ xfs_dir2_sf_addname_hard(
>  	int			objchange,	/* changing inode number size */
>  	int			new_isize)	/* new directory size */
>  {
> +	struct xfs_inode	*dp = args->dp;
> +	struct xfs_mount	*mp = dp->i_mount;
>  	int			add_datasize;	/* data size need for new ent */
>  	char			*buf;		/* buffer for old */
> -	xfs_inode_t		*dp;		/* incore directory inode */
>  	int			eof;		/* reached end of old dir */
>  	int			nbytes;		/* temp for byte copies */
>  	xfs_dir2_data_aoff_t	new_offset;	/* next offset value */
> @@ -432,8 +458,6 @@ xfs_dir2_sf_addname_hard(
>  	/*
>  	 * Copy the old directory to the stack buffer.
>  	 */
> -	dp = args->dp;
> -
>  	sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data;
>  	old_isize = (int)dp->i_d.di_size;
>  	buf = kmem_alloc(old_isize, 0);
> @@ -450,7 +474,7 @@ xfs_dir2_sf_addname_hard(
>  	      eof = (char *)oldsfep == &buf[old_isize];
>  	     !eof;
>  	     offset = new_offset + dp->d_ops->data_entsize(oldsfep->namelen),
> -	      oldsfep = dp->d_ops->sf_nextentry(oldsfp, oldsfep),
> +	      oldsfep = xfs_dir2_sf_nextentry(mp, oldsfp, oldsfep),
>  	      eof = (char *)oldsfep == &buf[old_isize]) {
>  		new_offset = xfs_dir2_sf_get_offset(oldsfep);
>  		if (offset + add_datasize <= new_offset)
> @@ -488,7 +512,7 @@ xfs_dir2_sf_addname_hard(
>  	 * If there's more left to copy, do that.
>  	 */
>  	if (!eof) {
> -		sfep = dp->d_ops->sf_nextentry(sfp, sfep);
> +		sfep = xfs_dir2_sf_nextentry(mp, sfp, sfep);
>  		memcpy(sfep, oldsfep, old_isize - nbytes);
>  	}
>  	kmem_free(buf);
> @@ -510,7 +534,8 @@ xfs_dir2_sf_addname_pick(
>  	xfs_dir2_sf_entry_t	**sfepp,	/* out(1): new entry ptr */
>  	xfs_dir2_data_aoff_t	*offsetp)	/* out(1): new offset */
>  {
> -	xfs_inode_t		*dp;		/* incore directory inode */
> +	struct xfs_inode	*dp = args->dp;
> +	struct xfs_mount	*mp = dp->i_mount;
>  	int			holefit;	/* found hole it will fit in */
>  	int			i;		/* entry number */
>  	xfs_dir2_data_aoff_t	offset;		/* data block offset */
> @@ -519,8 +544,6 @@ xfs_dir2_sf_addname_pick(
>  	int			size;		/* entry's data size */
>  	int			used;		/* data bytes used */
>  
> -	dp = args->dp;
> -
>  	sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data;
>  	size = dp->d_ops->data_entsize(args->namelen);
>  	offset = dp->d_ops->data_first_offset;
> @@ -536,7 +559,7 @@ xfs_dir2_sf_addname_pick(
>  			holefit = offset + size <= xfs_dir2_sf_get_offset(sfep);
>  		offset = xfs_dir2_sf_get_offset(sfep) +
>  			 dp->d_ops->data_entsize(sfep->namelen);
> -		sfep = dp->d_ops->sf_nextentry(sfp, sfep);
> +		sfep = xfs_dir2_sf_nextentry(mp, sfp, sfep);
>  	}
>  	/*
>  	 * Calculate data bytes used excluding the new entry, if this
> @@ -595,7 +618,7 @@ xfs_dir2_sf_check(
>  
>  	for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp);
>  	     i < sfp->count;
> -	     i++, sfep = dp->d_ops->sf_nextentry(sfp, sfep)) {
> +	     i++, sfep = xfs_dir2_sf_nextentry(dp->i_mount, sfp, sfep)) {
>  		ASSERT(xfs_dir2_sf_get_offset(sfep) >= offset);
>  		ino = dp->d_ops->sf_get_ino(sfp, sfep);
>  		i8count += ino > XFS_DIR2_MAX_SHORT_INUM;
> @@ -680,7 +703,7 @@ xfs_dir2_sf_verify(
>  		 * within the data buffer.  The next entry starts after the
>  		 * name component, so nextentry is an acceptable test.
>  		 */
> -		next_sfep = dops->sf_nextentry(sfp, sfep);
> +		next_sfep = xfs_dir2_sf_nextentry(mp, sfp, sfep);
>  		if (endp < (char *)next_sfep)
>  			return __this_address;
>  
> @@ -779,7 +802,8 @@ int						/* error */
>  xfs_dir2_sf_lookup(
>  	xfs_da_args_t		*args)		/* operation arguments */
>  {
> -	xfs_inode_t		*dp;		/* incore directory inode */
> +	struct xfs_inode	*dp = args->dp;
> +	struct xfs_mount	*mp = dp->i_mount;
>  	int			i;		/* entry index */
>  	int			error;
>  	xfs_dir2_sf_entry_t	*sfep;		/* shortform directory entry */
> @@ -790,7 +814,6 @@ xfs_dir2_sf_lookup(
>  	trace_xfs_dir2_sf_lookup(args);
>  
>  	xfs_dir2_sf_check(args);
> -	dp = args->dp;
>  
>  	ASSERT(dp->i_df.if_flags & XFS_IFINLINE);
>  	/*
> @@ -828,7 +851,7 @@ xfs_dir2_sf_lookup(
>  	 */
>  	ci_sfep = NULL;
>  	for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp); i < sfp->count;
> -	     i++, sfep = dp->d_ops->sf_nextentry(sfp, sfep)) {
> +	     i++, sfep = xfs_dir2_sf_nextentry(mp, sfp, sfep)) {
>  		/*
>  		 * Compare name and if it's an exact match, return the inode
>  		 * number. If it's the first case-insensitive match, store the
> @@ -864,8 +887,9 @@ int						/* error */
>  xfs_dir2_sf_removename(
>  	xfs_da_args_t		*args)
>  {
> +	struct xfs_inode	*dp = args->dp;
> +	struct xfs_mount	*mp = dp->i_mount;
>  	int			byteoff;	/* offset of removed entry */
> -	xfs_inode_t		*dp;		/* incore directory inode */
>  	int			entsize;	/* this entry's size */
>  	int			i;		/* shortform entry index */
>  	int			newsize;	/* new inode size */
> @@ -875,8 +899,6 @@ xfs_dir2_sf_removename(
>  
>  	trace_xfs_dir2_sf_removename(args);
>  
> -	dp = args->dp;
> -
>  	ASSERT(dp->i_df.if_flags & XFS_IFINLINE);
>  	oldsize = (int)dp->i_d.di_size;
>  	/*
> @@ -895,7 +917,7 @@ xfs_dir2_sf_removename(
>  	 * Find the one we're deleting.
>  	 */
>  	for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp); i < sfp->count;
> -	     i++, sfep = dp->d_ops->sf_nextentry(sfp, sfep)) {
> +	     i++, sfep = xfs_dir2_sf_nextentry(mp, sfp, sfep)) {
>  		if (xfs_da_compname(args, sfep->name, sfep->namelen) ==
>  								XFS_CMP_EXACT) {
>  			ASSERT(dp->d_ops->sf_get_ino(sfp, sfep) ==
> @@ -912,7 +934,7 @@ xfs_dir2_sf_removename(
>  	 * Calculate sizes.
>  	 */
>  	byteoff = (int)((char *)sfep - (char *)sfp);
> -	entsize = dp->d_ops->sf_entsize(sfp, args->namelen);
> +	entsize = xfs_dir2_sf_entsize(mp, sfp, args->namelen);
>  	newsize = oldsize - entsize;
>  	/*
>  	 * Copy the part if any after the removed entry, sliding it down.
> @@ -951,7 +973,8 @@ int						/* error */
>  xfs_dir2_sf_replace(
>  	xfs_da_args_t		*args)		/* operation arguments */
>  {
> -	xfs_inode_t		*dp;		/* incore directory inode */
> +	struct xfs_inode	*dp = args->dp;
> +	struct xfs_mount	*mp = dp->i_mount;
>  	int			i;		/* entry index */
>  	xfs_ino_t		ino=0;		/* entry old inode number */
>  	int			i8elevated;	/* sf_toino8 set i8count=1 */
> @@ -960,14 +983,12 @@ xfs_dir2_sf_replace(
>  
>  	trace_xfs_dir2_sf_replace(args);
>  
> -	dp = args->dp;
> -
>  	ASSERT(dp->i_df.if_flags & XFS_IFINLINE);
>  	/*
>  	 * Bail out if the shortform directory is way too small.
>  	 */
>  	if (dp->i_d.di_size < offsetof(xfs_dir2_sf_hdr_t, parent)) {
> -		ASSERT(XFS_FORCED_SHUTDOWN(dp->i_mount));
> +		ASSERT(XFS_FORCED_SHUTDOWN(mp));
>  		return -EIO;
>  	}
>  	ASSERT(dp->i_df.if_bytes == dp->i_d.di_size);
> @@ -1017,7 +1038,7 @@ xfs_dir2_sf_replace(
>  	 */
>  	else {
>  		for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp); i < sfp->count;
> -		     i++, sfep = dp->d_ops->sf_nextentry(sfp, sfep)) {
> +		     i++, sfep = xfs_dir2_sf_nextentry(mp, sfp, sfep)) {
>  			if (xfs_da_compname(args, sfep->name, sfep->namelen) ==
>  								XFS_CMP_EXACT) {
>  				ino = dp->d_ops->sf_get_ino(sfp, sfep);
> @@ -1076,8 +1097,9 @@ static void
>  xfs_dir2_sf_toino4(
>  	xfs_da_args_t		*args)		/* operation arguments */
>  {
> +	struct xfs_inode	*dp = args->dp;
> +	struct xfs_mount	*mp = dp->i_mount;
>  	char			*buf;		/* old dir's buffer */
> -	xfs_inode_t		*dp;		/* incore directory inode */
>  	int			i;		/* entry index */
>  	int			newsize;	/* new inode size */
>  	xfs_dir2_sf_entry_t	*oldsfep;	/* old sf entry */
> @@ -1088,8 +1110,6 @@ xfs_dir2_sf_toino4(
>  
>  	trace_xfs_dir2_sf_toino4(args);
>  
> -	dp = args->dp;
> -
>  	/*
>  	 * Copy the old directory to the buffer.
>  	 * Then nuke it from the inode, and add the new buffer to the inode.
> @@ -1123,8 +1143,8 @@ xfs_dir2_sf_toino4(
>  	for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp),
>  		    oldsfep = xfs_dir2_sf_firstentry(oldsfp);
>  	     i < sfp->count;
> -	     i++, sfep = dp->d_ops->sf_nextentry(sfp, sfep),
> -		  oldsfep = dp->d_ops->sf_nextentry(oldsfp, oldsfep)) {
> +	     i++, sfep = xfs_dir2_sf_nextentry(mp, sfp, sfep),
> +		  oldsfep = xfs_dir2_sf_nextentry(mp, oldsfp, oldsfep)) {
>  		sfep->namelen = oldsfep->namelen;
>  		memcpy(sfep->offset, oldsfep->offset, sizeof(sfep->offset));
>  		memcpy(sfep->name, oldsfep->name, sfep->namelen);
> @@ -1149,8 +1169,9 @@ static void
>  xfs_dir2_sf_toino8(
>  	xfs_da_args_t		*args)		/* operation arguments */
>  {
> +	struct xfs_inode	*dp = args->dp;
> +	struct xfs_mount	*mp = dp->i_mount;
>  	char			*buf;		/* old dir's buffer */
> -	xfs_inode_t		*dp;		/* incore directory inode */
>  	int			i;		/* entry index */
>  	int			newsize;	/* new inode size */
>  	xfs_dir2_sf_entry_t	*oldsfep;	/* old sf entry */
> @@ -1161,8 +1182,6 @@ xfs_dir2_sf_toino8(
>  
>  	trace_xfs_dir2_sf_toino8(args);
>  
> -	dp = args->dp;
> -
>  	/*
>  	 * Copy the old directory to the buffer.
>  	 * Then nuke it from the inode, and add the new buffer to the inode.
> @@ -1196,8 +1215,8 @@ xfs_dir2_sf_toino8(
>  	for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp),
>  		    oldsfep = xfs_dir2_sf_firstentry(oldsfp);
>  	     i < sfp->count;
> -	     i++, sfep = dp->d_ops->sf_nextentry(sfp, sfep),
> -		  oldsfep = dp->d_ops->sf_nextentry(oldsfp, oldsfep)) {
> +	     i++, sfep = xfs_dir2_sf_nextentry(mp, sfp, sfep),
> +		  oldsfep = xfs_dir2_sf_nextentry(mp, oldsfp, oldsfep)) {
>  		sfep->namelen = oldsfep->namelen;
>  		memcpy(sfep->offset, oldsfep->offset, sizeof(sfep->offset));
>  		memcpy(sfep->name, oldsfep->name, sfep->namelen);
> diff --git a/fs/xfs/xfs_dir2_readdir.c b/fs/xfs/xfs_dir2_readdir.c
> index 6f94d2a45174..7d150e914d00 100644
> --- a/fs/xfs/xfs_dir2_readdir.c
> +++ b/fs/xfs/xfs_dir2_readdir.c
> @@ -48,6 +48,7 @@ xfs_dir2_sf_getdents(
>  {
>  	int			i;		/* shortform entry number */
>  	struct xfs_inode	*dp = args->dp;	/* incore directory inode */
> +	struct xfs_mount	*mp = dp->i_mount;
>  	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 */
> @@ -109,7 +110,7 @@ xfs_dir2_sf_getdents(
>  				xfs_dir2_sf_get_offset(sfep));
>  
>  		if (ctx->pos > off) {
> -			sfep = dp->d_ops->sf_nextentry(sfp, sfep);
> +			sfep = xfs_dir2_sf_nextentry(mp, sfp, sfep);
>  			continue;
>  		}
>  
> @@ -122,9 +123,9 @@ xfs_dir2_sf_getdents(
>  			return -EFSCORRUPTED;
>  		}
>  		if (!dir_emit(ctx, (char *)sfep->name, sfep->namelen, ino,
> -			    xfs_dir3_get_dtype(dp->i_mount, filetype)))
> +			    xfs_dir3_get_dtype(mp, filetype)))
>  			return 0;
> -		sfep = dp->d_ops->sf_nextentry(sfp, sfep);
> +		sfep = xfs_dir2_sf_nextentry(mp, sfp, sfep);
>  	}
>  
>  	ctx->pos = xfs_dir2_db_off_to_dataptr(geo, geo->datablk + 1, 0) &
> -- 
> 2.20.1
> 

^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH 21/34] xfs: devirtualize ->sf_get_ino and ->sf_put_ino
  2019-11-01 22:07 ` [PATCH 21/34] xfs: devirtualize ->sf_get_ino and ->sf_put_ino Christoph Hellwig
@ 2019-11-04 20:33   ` Darrick J. Wong
  2019-11-07  1:05     ` Darrick J. Wong
  0 siblings, 1 reply; 81+ messages in thread
From: Darrick J. Wong @ 2019-11-04 20:33 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-xfs

On Fri, Nov 01, 2019 at 03:07:06PM -0700, Christoph Hellwig wrote:
> Replace the ->sf_get_ino and ->sf_put_ino dir ops methods with directly
> called xfs_dir2_sf_get_ino nd xfs_dir2_sf_put_ino helpers that take care

                            ^^^ "and"

> of the difference between the directory format with and without the file
> type field.  Also move xfs_dir2_sf_get_parent_ino and
> xfs_dir2_sf_put_parent_ino to xfs_dir2_sf.c with the rest of the
> low-level short form entry handling.
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>

Looks ok, except...

<snip>

> diff --git a/fs/xfs/libxfs/xfs_dir2_sf.c b/fs/xfs/libxfs/xfs_dir2_sf.c
> index f3a4f0ddfc1a..c33d838b1a5c 100644
> --- a/fs/xfs/libxfs/xfs_dir2_sf.c
> +++ b/fs/xfs/libxfs/xfs_dir2_sf.c
> @@ -63,6 +63,69 @@ xfs_dir2_sf_nextentry(
>  		((char *)sfep + xfs_dir2_sf_entsize(mp, hdr, sfep->namelen));
>  }
>  
> +/*
> + * In short-form directory entries the inode numbers are stored at variable
> + * offset behind the entry name. If the entry stores a filetype value, then it
> + * sits between the name and the inode number.  The actual inode numbers can
> + * come in two formats as well, either 4 bytes or 8 bytes wide.
> + */
> +xfs_ino_t
> +xfs_dir2_sf_get_ino(
> +	struct xfs_mount		*mp,
> +	struct xfs_dir2_sf_hdr		*hdr,
> +	struct xfs_dir2_sf_entry	*sfep)
> +{
> +	uint8_t				*from = sfep->name + sfep->namelen;
> +
> +	if (xfs_sb_version_hasftype(&mp->m_sb))
> +		from++;
> +
> +	if (!hdr->i8count)
> +		return get_unaligned_be32(from);
> +	return get_unaligned_be64(from) & 0x00ffffffffffffffULL;

...maybe we ought to convert this to use XFS_MAXINUMBER instead of
encoding magic numbers?

> +}
> +
> +void
> +xfs_dir2_sf_put_ino(
> +	struct xfs_mount		*mp,
> +	struct xfs_dir2_sf_hdr		*hdr,
> +	struct xfs_dir2_sf_entry	*sfep,
> +	xfs_ino_t			ino)
> +{
> +	uint8_t				*to = sfep->name + sfep->namelen;
> +
> +	ASSERT((ino & 0xff00000000000000ULL) == 0);

Same here...

> +	if (xfs_sb_version_hasftype(&mp->m_sb))
> +		to++;
> +
> +	if (hdr->i8count)
> +		put_unaligned_be64(ino, to);
> +	else
> +		put_unaligned_be32(ino, to);
> +}
> +
> +xfs_ino_t
> +xfs_dir2_sf_get_parent_ino(
> +	struct xfs_dir2_sf_hdr	*hdr)
> +{
> +	if (!hdr->i8count)
> +		return get_unaligned_be32(hdr->parent);
> +	return get_unaligned_be64(hdr->parent) & 0x00ffffffffffffffULL;

And here...

> +}
> +
> +void
> +xfs_dir2_sf_put_parent_ino(
> +	struct xfs_dir2_sf_hdr		*hdr,
> +	xfs_ino_t			ino)
> +{
> +	ASSERT((ino & 0xff00000000000000ULL) == 0);

And here?

--D

> +	if (hdr->i8count)
> +		put_unaligned_be64(ino, hdr->parent);
> +	else
> +		put_unaligned_be32(ino, hdr->parent);
> +}
> +
>  /*
>   * Given a block directory (dp/block), calculate its size as a shortform (sf)
>   * directory and a header for the sf directory, if it will fit it the
> @@ -240,7 +303,7 @@ xfs_dir2_block_to_sf(
>  				(xfs_dir2_data_aoff_t)
>  				((char *)dep - (char *)hdr));
>  			memcpy(sfep->name, dep->name, dep->namelen);
> -			dp->d_ops->sf_put_ino(sfp, sfep,
> +			xfs_dir2_sf_put_ino(mp, sfp, sfep,
>  					      be64_to_cpu(dep->inumber));
>  			dp->d_ops->sf_put_ftype(sfep,
>  					dp->d_ops->data_get_ftype(dep));
> @@ -413,7 +476,7 @@ xfs_dir2_sf_addname_easy(
>  	sfep->namelen = args->namelen;
>  	xfs_dir2_sf_put_offset(sfep, offset);
>  	memcpy(sfep->name, args->name, sfep->namelen);
> -	dp->d_ops->sf_put_ino(sfp, sfep, args->inumber);
> +	xfs_dir2_sf_put_ino(mp, sfp, sfep, args->inumber);
>  	dp->d_ops->sf_put_ftype(sfep, args->filetype);
>  
>  	/*
> @@ -503,7 +566,7 @@ xfs_dir2_sf_addname_hard(
>  	sfep->namelen = args->namelen;
>  	xfs_dir2_sf_put_offset(sfep, offset);
>  	memcpy(sfep->name, args->name, sfep->namelen);
> -	dp->d_ops->sf_put_ino(sfp, sfep, args->inumber);
> +	xfs_dir2_sf_put_ino(mp, sfp, sfep, args->inumber);
>  	dp->d_ops->sf_put_ftype(sfep, args->filetype);
>  	sfp->count++;
>  	if (args->inumber > XFS_DIR2_MAX_SHORT_INUM && !objchange)
> @@ -620,7 +683,7 @@ xfs_dir2_sf_check(
>  	     i < sfp->count;
>  	     i++, sfep = xfs_dir2_sf_nextentry(dp->i_mount, sfp, sfep)) {
>  		ASSERT(xfs_dir2_sf_get_offset(sfep) >= offset);
> -		ino = dp->d_ops->sf_get_ino(sfp, sfep);
> +		ino = xfs_dir2_sf_get_ino(dp->i_mount, sfp, sfep);
>  		i8count += ino > XFS_DIR2_MAX_SHORT_INUM;
>  		offset =
>  			xfs_dir2_sf_get_offset(sfep) +
> @@ -712,7 +775,7 @@ xfs_dir2_sf_verify(
>  			return __this_address;
>  
>  		/* Check the inode number. */
> -		ino = dops->sf_get_ino(sfp, sfep);
> +		ino = xfs_dir2_sf_get_ino(mp, sfp, sfep);
>  		i8count += ino > XFS_DIR2_MAX_SHORT_INUM;
>  		error = xfs_dir_ino_validate(mp, ino);
>  		if (error)
> @@ -861,7 +924,7 @@ xfs_dir2_sf_lookup(
>  								sfep->namelen);
>  		if (cmp != XFS_CMP_DIFFERENT && cmp != args->cmpresult) {
>  			args->cmpresult = cmp;
> -			args->inumber = dp->d_ops->sf_get_ino(sfp, sfep);
> +			args->inumber = xfs_dir2_sf_get_ino(mp, sfp, sfep);
>  			args->filetype = dp->d_ops->sf_get_ftype(sfep);
>  			if (cmp == XFS_CMP_EXACT)
>  				return -EEXIST;
> @@ -920,7 +983,7 @@ xfs_dir2_sf_removename(
>  	     i++, sfep = xfs_dir2_sf_nextentry(mp, sfp, sfep)) {
>  		if (xfs_da_compname(args, sfep->name, sfep->namelen) ==
>  								XFS_CMP_EXACT) {
> -			ASSERT(dp->d_ops->sf_get_ino(sfp, sfep) ==
> +			ASSERT(xfs_dir2_sf_get_ino(mp, sfp, sfep) ==
>  			       args->inumber);
>  			break;
>  		}
> @@ -1041,9 +1104,10 @@ xfs_dir2_sf_replace(
>  		     i++, sfep = xfs_dir2_sf_nextentry(mp, sfp, sfep)) {
>  			if (xfs_da_compname(args, sfep->name, sfep->namelen) ==
>  								XFS_CMP_EXACT) {
> -				ino = dp->d_ops->sf_get_ino(sfp, sfep);
> +				ino = xfs_dir2_sf_get_ino(mp, sfp, sfep);
>  				ASSERT(args->inumber != ino);
> -				dp->d_ops->sf_put_ino(sfp, sfep, args->inumber);
> +				xfs_dir2_sf_put_ino(mp, sfp, sfep,
> +						args->inumber);
>  				dp->d_ops->sf_put_ftype(sfep, args->filetype);
>  				break;
>  			}
> @@ -1148,8 +1212,8 @@ xfs_dir2_sf_toino4(
>  		sfep->namelen = oldsfep->namelen;
>  		memcpy(sfep->offset, oldsfep->offset, sizeof(sfep->offset));
>  		memcpy(sfep->name, oldsfep->name, sfep->namelen);
> -		dp->d_ops->sf_put_ino(sfp, sfep,
> -				      dp->d_ops->sf_get_ino(oldsfp, oldsfep));
> +		xfs_dir2_sf_put_ino(mp, sfp, sfep,
> +				xfs_dir2_sf_get_ino(mp, oldsfp, oldsfep));
>  		dp->d_ops->sf_put_ftype(sfep, dp->d_ops->sf_get_ftype(oldsfep));
>  	}
>  	/*
> @@ -1220,8 +1284,8 @@ xfs_dir2_sf_toino8(
>  		sfep->namelen = oldsfep->namelen;
>  		memcpy(sfep->offset, oldsfep->offset, sizeof(sfep->offset));
>  		memcpy(sfep->name, oldsfep->name, sfep->namelen);
> -		dp->d_ops->sf_put_ino(sfp, sfep,
> -				      dp->d_ops->sf_get_ino(oldsfp, oldsfep));
> +		xfs_dir2_sf_put_ino(mp, sfp, sfep,
> +				xfs_dir2_sf_get_ino(mp, oldsfp, oldsfep));
>  		dp->d_ops->sf_put_ftype(sfep, dp->d_ops->sf_get_ftype(oldsfep));
>  	}
>  	/*
> diff --git a/fs/xfs/xfs_dir2_readdir.c b/fs/xfs/xfs_dir2_readdir.c
> index 7d150e914d00..9d318f091a73 100644
> --- a/fs/xfs/xfs_dir2_readdir.c
> +++ b/fs/xfs/xfs_dir2_readdir.c
> @@ -114,7 +114,7 @@ xfs_dir2_sf_getdents(
>  			continue;
>  		}
>  
> -		ino = dp->d_ops->sf_get_ino(sfp, sfep);
> +		ino = xfs_dir2_sf_get_ino(mp, sfp, sfep);
>  		filetype = dp->d_ops->sf_get_ftype(sfep);
>  		ctx->pos = off & 0x7fffffff;
>  		if (!xfs_dir2_namecheck(sfep->name, sfep->namelen)) {
> -- 
> 2.20.1
> 

^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH 22/34] xfs: devirtualize ->sf_get_ftype and ->sf_put_ftype
  2019-11-01 22:07 ` [PATCH 22/34] xfs: devirtualize ->sf_get_ftype and ->sf_put_ftype Christoph Hellwig
@ 2019-11-04 20:34   ` Darrick J. Wong
  0 siblings, 0 replies; 81+ messages in thread
From: Darrick J. Wong @ 2019-11-04 20:34 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-xfs

On Fri, Nov 01, 2019 at 03:07:07PM -0700, Christoph Hellwig wrote:
> Replace the ->sf_get_ftype and ->sf_put_ftype dir ops methods with
> directly called xfs_dir2_sf_get_ftype and xfs_dir2_sf_put_ftype helpers
> that takes care of the differences between the directory format with and
> without the file type field.
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>

Seems reasonable to me,
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>

--D

> ---
>  fs/xfs/libxfs/xfs_da_format.c  | 52 -----------------------------
>  fs/xfs/libxfs/xfs_dir2.h       |  4 ---
>  fs/xfs/libxfs/xfs_dir2_block.c |  2 +-
>  fs/xfs/libxfs/xfs_dir2_priv.h  |  2 ++
>  fs/xfs/libxfs/xfs_dir2_sf.c    | 60 ++++++++++++++++++++++++++--------
>  fs/xfs/xfs_dir2_readdir.c      |  2 +-
>  6 files changed, 50 insertions(+), 72 deletions(-)
> 
> diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c
> index f427f141d001..1c72b46344d6 100644
> --- a/fs/xfs/libxfs/xfs_da_format.c
> +++ b/fs/xfs/libxfs/xfs_da_format.c
> @@ -15,49 +15,6 @@
>  #include "xfs_dir2.h"
>  #include "xfs_dir2_priv.h"
>  
> -/*
> - * For filetype enabled shortform directories, the file type field is stored at
> - * the end of the name.  Because it's only a single byte, endian conversion is
> - * not necessary. For non-filetype enable directories, the type is always
> - * unknown and we never store the value.
> - */
> -static uint8_t
> -xfs_dir2_sfe_get_ftype(
> -	struct xfs_dir2_sf_entry *sfep)
> -{
> -	return XFS_DIR3_FT_UNKNOWN;
> -}
> -
> -static void
> -xfs_dir2_sfe_put_ftype(
> -	struct xfs_dir2_sf_entry *sfep,
> -	uint8_t			ftype)
> -{
> -	ASSERT(ftype < XFS_DIR3_FT_MAX);
> -}
> -
> -static uint8_t
> -xfs_dir3_sfe_get_ftype(
> -	struct xfs_dir2_sf_entry *sfep)
> -{
> -	uint8_t		ftype;
> -
> -	ftype = sfep->name[sfep->namelen];
> -	if (ftype >= XFS_DIR3_FT_MAX)
> -		return XFS_DIR3_FT_UNKNOWN;
> -	return ftype;
> -}
> -
> -static void
> -xfs_dir3_sfe_put_ftype(
> -	struct xfs_dir2_sf_entry *sfep,
> -	uint8_t			ftype)
> -{
> -	ASSERT(ftype < XFS_DIR3_FT_MAX);
> -
> -	sfep->name[sfep->namelen] = ftype;
> -}
> -
>  /*
>   * Directory data block operations
>   */
> @@ -271,9 +228,6 @@ xfs_dir3_data_unused_p(struct xfs_dir2_data_hdr *hdr)
>  }
>  
>  static const struct xfs_dir_ops xfs_dir2_ops = {
> -	.sf_get_ftype = xfs_dir2_sfe_get_ftype,
> -	.sf_put_ftype = xfs_dir2_sfe_put_ftype,
> -
>  	.data_entsize = xfs_dir2_data_entsize,
>  	.data_get_ftype = xfs_dir2_data_get_ftype,
>  	.data_put_ftype = xfs_dir2_data_put_ftype,
> @@ -296,9 +250,6 @@ static const struct xfs_dir_ops xfs_dir2_ops = {
>  };
>  
>  static const struct xfs_dir_ops xfs_dir2_ftype_ops = {
> -	.sf_get_ftype = xfs_dir3_sfe_get_ftype,
> -	.sf_put_ftype = xfs_dir3_sfe_put_ftype,
> -
>  	.data_entsize = xfs_dir3_data_entsize,
>  	.data_get_ftype = xfs_dir3_data_get_ftype,
>  	.data_put_ftype = xfs_dir3_data_put_ftype,
> @@ -321,9 +272,6 @@ static const struct xfs_dir_ops xfs_dir2_ftype_ops = {
>  };
>  
>  static const struct xfs_dir_ops xfs_dir3_ops = {
> -	.sf_get_ftype = xfs_dir3_sfe_get_ftype,
> -	.sf_put_ftype = xfs_dir3_sfe_put_ftype,
> -
>  	.data_entsize = xfs_dir3_data_entsize,
>  	.data_get_ftype = xfs_dir3_data_get_ftype,
>  	.data_put_ftype = xfs_dir3_data_put_ftype,
> diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h
> index 049d844d6a18..61cc9ae837d5 100644
> --- a/fs/xfs/libxfs/xfs_dir2.h
> +++ b/fs/xfs/libxfs/xfs_dir2.h
> @@ -32,10 +32,6 @@ extern unsigned char xfs_mode_to_ftype(int mode);
>   * directory operations vector for encode/decode routines
>   */
>  struct xfs_dir_ops {
> -	uint8_t (*sf_get_ftype)(struct xfs_dir2_sf_entry *sfep);
> -	void	(*sf_put_ftype)(struct xfs_dir2_sf_entry *sfep,
> -				uint8_t ftype);
> -
>  	int	(*data_entsize)(int len);
>  	uint8_t (*data_get_ftype)(struct xfs_dir2_data_entry *dep);
>  	void	(*data_put_ftype)(struct xfs_dir2_data_entry *dep,
> diff --git a/fs/xfs/libxfs/xfs_dir2_block.c b/fs/xfs/libxfs/xfs_dir2_block.c
> index 0f3024386a5c..5877272dc63e 100644
> --- a/fs/xfs/libxfs/xfs_dir2_block.c
> +++ b/fs/xfs/libxfs/xfs_dir2_block.c
> @@ -1216,7 +1216,7 @@ xfs_dir2_sf_to_block(
>  		dep = (xfs_dir2_data_entry_t *)((char *)hdr + newoffset);
>  		dep->inumber = cpu_to_be64(xfs_dir2_sf_get_ino(mp, sfp, sfep));
>  		dep->namelen = sfep->namelen;
> -		dp->d_ops->data_put_ftype(dep, dp->d_ops->sf_get_ftype(sfep));
> +		dp->d_ops->data_put_ftype(dep, xfs_dir2_sf_get_ftype(mp, sfep));
>  		memcpy(dep->name, sfep->name, dep->namelen);
>  		tagp = dp->d_ops->data_entry_tag_p(dep);
>  		*tagp = cpu_to_be16((char *)dep - (char *)hdr);
> diff --git a/fs/xfs/libxfs/xfs_dir2_priv.h b/fs/xfs/libxfs/xfs_dir2_priv.h
> index 57c0f7aee7a4..a92d9f0f83e0 100644
> --- a/fs/xfs/libxfs/xfs_dir2_priv.h
> +++ b/fs/xfs/libxfs/xfs_dir2_priv.h
> @@ -139,6 +139,8 @@ xfs_ino_t xfs_dir2_sf_get_ino(struct xfs_mount *mp, struct xfs_dir2_sf_hdr *hdr,
>  		struct xfs_dir2_sf_entry *sfep);
>  xfs_ino_t xfs_dir2_sf_get_parent_ino(struct xfs_dir2_sf_hdr *hdr);
>  void xfs_dir2_sf_put_parent_ino(struct xfs_dir2_sf_hdr *hdr, xfs_ino_t ino);
> +uint8_t xfs_dir2_sf_get_ftype(struct xfs_mount *mp,
> +		struct xfs_dir2_sf_entry *sfep);
>  struct xfs_dir2_sf_entry *xfs_dir2_sf_nextentry(struct xfs_mount *mp,
>  		struct xfs_dir2_sf_hdr *hdr, struct xfs_dir2_sf_entry *sfep);
>  extern int xfs_dir2_block_sfsize(struct xfs_inode *dp,
> diff --git a/fs/xfs/libxfs/xfs_dir2_sf.c b/fs/xfs/libxfs/xfs_dir2_sf.c
> index c33d838b1a5c..10199261c94c 100644
> --- a/fs/xfs/libxfs/xfs_dir2_sf.c
> +++ b/fs/xfs/libxfs/xfs_dir2_sf.c
> @@ -126,6 +126,37 @@ xfs_dir2_sf_put_parent_ino(
>  		put_unaligned_be32(ino, hdr->parent);
>  }
>  
> +/*
> + * The file type field is stored at the end of the name for filetype enabled
> + * shortform directories, or not at all otherwise.
> + */
> +uint8_t
> +xfs_dir2_sf_get_ftype(
> +	struct xfs_mount		*mp,
> +	struct xfs_dir2_sf_entry	*sfep)
> +{
> +	if (xfs_sb_version_hasftype(&mp->m_sb)) {
> +		uint8_t			ftype = sfep->name[sfep->namelen];
> +
> +		if (ftype < XFS_DIR3_FT_MAX)
> +			return ftype;
> +	}
> +
> +	return XFS_DIR3_FT_UNKNOWN;
> +}
> +
> +static void
> +xfs_dir2_sf_put_ftype(
> +	struct xfs_mount	*mp,
> +	struct xfs_dir2_sf_entry *sfep,
> +	uint8_t			ftype)
> +{
> +	ASSERT(ftype < XFS_DIR3_FT_MAX);
> +
> +	if (xfs_sb_version_hasftype(&mp->m_sb))
> +		sfep->name[sfep->namelen] = ftype;
> +}
> +
>  /*
>   * Given a block directory (dp/block), calculate its size as a shortform (sf)
>   * directory and a header for the sf directory, if it will fit it the
> @@ -305,7 +336,7 @@ xfs_dir2_block_to_sf(
>  			memcpy(sfep->name, dep->name, dep->namelen);
>  			xfs_dir2_sf_put_ino(mp, sfp, sfep,
>  					      be64_to_cpu(dep->inumber));
> -			dp->d_ops->sf_put_ftype(sfep,
> +			xfs_dir2_sf_put_ftype(mp, sfep,
>  					dp->d_ops->data_get_ftype(dep));
>  
>  			sfep = xfs_dir2_sf_nextentry(mp, sfp, sfep);
> @@ -477,7 +508,7 @@ xfs_dir2_sf_addname_easy(
>  	xfs_dir2_sf_put_offset(sfep, offset);
>  	memcpy(sfep->name, args->name, sfep->namelen);
>  	xfs_dir2_sf_put_ino(mp, sfp, sfep, args->inumber);
> -	dp->d_ops->sf_put_ftype(sfep, args->filetype);
> +	xfs_dir2_sf_put_ftype(mp, sfep, args->filetype);
>  
>  	/*
>  	 * Update the header and inode.
> @@ -567,7 +598,7 @@ xfs_dir2_sf_addname_hard(
>  	xfs_dir2_sf_put_offset(sfep, offset);
>  	memcpy(sfep->name, args->name, sfep->namelen);
>  	xfs_dir2_sf_put_ino(mp, sfp, sfep, args->inumber);
> -	dp->d_ops->sf_put_ftype(sfep, args->filetype);
> +	xfs_dir2_sf_put_ftype(mp, sfep, args->filetype);
>  	sfp->count++;
>  	if (args->inumber > XFS_DIR2_MAX_SHORT_INUM && !objchange)
>  		sfp->i8count++;
> @@ -664,7 +695,8 @@ static void
>  xfs_dir2_sf_check(
>  	xfs_da_args_t		*args)		/* operation arguments */
>  {
> -	xfs_inode_t		*dp;		/* incore directory inode */
> +	struct xfs_inode	*dp = args->dp;
> +	struct xfs_mount	*mp = dp->i_mount;
>  	int			i;		/* entry number */
>  	int			i8count;	/* number of big inode#s */
>  	xfs_ino_t		ino;		/* entry inode number */
> @@ -672,8 +704,6 @@ xfs_dir2_sf_check(
>  	xfs_dir2_sf_entry_t	*sfep;		/* shortform dir entry */
>  	xfs_dir2_sf_hdr_t	*sfp;		/* shortform structure */
>  
> -	dp = args->dp;
> -
>  	sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data;
>  	offset = dp->d_ops->data_first_offset;
>  	ino = xfs_dir2_sf_get_parent_ino(sfp);
> @@ -681,14 +711,14 @@ xfs_dir2_sf_check(
>  
>  	for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp);
>  	     i < sfp->count;
> -	     i++, sfep = xfs_dir2_sf_nextentry(dp->i_mount, sfp, sfep)) {
> +	     i++, sfep = xfs_dir2_sf_nextentry(mp, sfp, sfep)) {
>  		ASSERT(xfs_dir2_sf_get_offset(sfep) >= offset);
> -		ino = xfs_dir2_sf_get_ino(dp->i_mount, sfp, sfep);
> +		ino = xfs_dir2_sf_get_ino(mp, sfp, sfep);
>  		i8count += ino > XFS_DIR2_MAX_SHORT_INUM;
>  		offset =
>  			xfs_dir2_sf_get_offset(sfep) +
>  			dp->d_ops->data_entsize(sfep->namelen);
> -		ASSERT(dp->d_ops->sf_get_ftype(sfep) < XFS_DIR3_FT_MAX);
> +		ASSERT(xfs_dir2_sf_get_ftype(mp, sfep) < XFS_DIR3_FT_MAX);
>  	}
>  	ASSERT(i8count == sfp->i8count);
>  	ASSERT((char *)sfep - (char *)sfp == dp->i_d.di_size);
> @@ -782,7 +812,7 @@ xfs_dir2_sf_verify(
>  			return __this_address;
>  
>  		/* Check the file type. */
> -		filetype = dops->sf_get_ftype(sfep);
> +		filetype = xfs_dir2_sf_get_ftype(mp, sfep);
>  		if (filetype >= XFS_DIR3_FT_MAX)
>  			return __this_address;
>  
> @@ -925,7 +955,7 @@ xfs_dir2_sf_lookup(
>  		if (cmp != XFS_CMP_DIFFERENT && cmp != args->cmpresult) {
>  			args->cmpresult = cmp;
>  			args->inumber = xfs_dir2_sf_get_ino(mp, sfp, sfep);
> -			args->filetype = dp->d_ops->sf_get_ftype(sfep);
> +			args->filetype = xfs_dir2_sf_get_ftype(mp, sfep);
>  			if (cmp == XFS_CMP_EXACT)
>  				return -EEXIST;
>  			ci_sfep = sfep;
> @@ -1108,7 +1138,7 @@ xfs_dir2_sf_replace(
>  				ASSERT(args->inumber != ino);
>  				xfs_dir2_sf_put_ino(mp, sfp, sfep,
>  						args->inumber);
> -				dp->d_ops->sf_put_ftype(sfep, args->filetype);
> +				xfs_dir2_sf_put_ftype(mp, sfep, args->filetype);
>  				break;
>  			}
>  		}
> @@ -1214,7 +1244,8 @@ xfs_dir2_sf_toino4(
>  		memcpy(sfep->name, oldsfep->name, sfep->namelen);
>  		xfs_dir2_sf_put_ino(mp, sfp, sfep,
>  				xfs_dir2_sf_get_ino(mp, oldsfp, oldsfep));
> -		dp->d_ops->sf_put_ftype(sfep, dp->d_ops->sf_get_ftype(oldsfep));
> +		xfs_dir2_sf_put_ftype(mp, sfep,
> +				xfs_dir2_sf_get_ftype(mp, oldsfep));
>  	}
>  	/*
>  	 * Clean up the inode.
> @@ -1286,7 +1317,8 @@ xfs_dir2_sf_toino8(
>  		memcpy(sfep->name, oldsfep->name, sfep->namelen);
>  		xfs_dir2_sf_put_ino(mp, sfp, sfep,
>  				xfs_dir2_sf_get_ino(mp, oldsfp, oldsfep));
> -		dp->d_ops->sf_put_ftype(sfep, dp->d_ops->sf_get_ftype(oldsfep));
> +		xfs_dir2_sf_put_ftype(mp, sfep,
> +				xfs_dir2_sf_get_ftype(mp, oldsfep));
>  	}
>  	/*
>  	 * Clean up the inode.
> diff --git a/fs/xfs/xfs_dir2_readdir.c b/fs/xfs/xfs_dir2_readdir.c
> index 9d318f091a73..e18045465455 100644
> --- a/fs/xfs/xfs_dir2_readdir.c
> +++ b/fs/xfs/xfs_dir2_readdir.c
> @@ -115,7 +115,7 @@ xfs_dir2_sf_getdents(
>  		}
>  
>  		ino = xfs_dir2_sf_get_ino(mp, sfp, sfep);
> -		filetype = dp->d_ops->sf_get_ftype(sfep);
> +		filetype = xfs_dir2_sf_get_ftype(mp, sfep);
>  		ctx->pos = off & 0x7fffffff;
>  		if (!xfs_dir2_namecheck(sfep->name, sfep->namelen)) {
>  			XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW,
> -- 
> 2.20.1
> 

^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH 23/34] xfs: remove the ->data_dot_entry_p and ->data_dotdot_entry_p methods
  2019-11-01 22:07 ` [PATCH 23/34] xfs: remove the ->data_dot_entry_p and ->data_dotdot_entry_p methods Christoph Hellwig
@ 2019-11-04 20:37   ` Darrick J. Wong
  0 siblings, 0 replies; 81+ messages in thread
From: Darrick J. Wong @ 2019-11-04 20:37 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-xfs

On Fri, Nov 01, 2019 at 03:07:08PM -0700, Christoph Hellwig wrote:
> Replace the only user of the ->data_dot_entry_p and ->data_dotdot_entry_p
> dir ops methods with direct calculations using ->data_dot_offset and
> ->data_dotdot_offset.
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
>  fs/xfs/libxfs/xfs_da_format.c  | 52 ----------------------------------
>  fs/xfs/libxfs/xfs_dir2.h       |  4 ---
>  fs/xfs/libxfs/xfs_dir2_block.c |  4 +--
>  3 files changed, 2 insertions(+), 58 deletions(-)
> 
> diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c
> index 1c72b46344d6..84f8355072b4 100644
> --- a/fs/xfs/libxfs/xfs_da_format.c
> +++ b/fs/xfs/libxfs/xfs_da_format.c
> @@ -111,26 +111,6 @@ xfs_dir3_data_entry_tag_p(
>  		xfs_dir3_data_entsize(dep->namelen) - sizeof(__be16));
>  }
>  
> -/*
> - * location of . and .. in data space (always block 0)
> - */
> -static struct xfs_dir2_data_entry *
> -xfs_dir2_data_dot_entry_p(
> -	struct xfs_dir2_data_hdr *hdr)
> -{
> -	return (struct xfs_dir2_data_entry *)
> -		((char *)hdr + sizeof(struct xfs_dir2_data_hdr));
> -}
> -
> -static struct xfs_dir2_data_entry *
> -xfs_dir2_data_dotdot_entry_p(
> -	struct xfs_dir2_data_hdr *hdr)
> -{
> -	return (struct xfs_dir2_data_entry *)
> -		((char *)hdr + sizeof(struct xfs_dir2_data_hdr) +
> -				XFS_DIR2_DATA_ENTSIZE(1));
> -}
> -
>  static struct xfs_dir2_data_entry *
>  xfs_dir2_data_first_entry_p(
>  	struct xfs_dir2_data_hdr *hdr)
> @@ -141,15 +121,6 @@ xfs_dir2_data_first_entry_p(
>  				XFS_DIR2_DATA_ENTSIZE(2));
>  }
>  
> -static struct xfs_dir2_data_entry *
> -xfs_dir2_ftype_data_dotdot_entry_p(
> -	struct xfs_dir2_data_hdr *hdr)
> -{
> -	return (struct xfs_dir2_data_entry *)
> -		((char *)hdr + sizeof(struct xfs_dir2_data_hdr) +
> -				XFS_DIR3_DATA_ENTSIZE(1));
> -}
> -
>  static struct xfs_dir2_data_entry *
>  xfs_dir2_ftype_data_first_entry_p(
>  	struct xfs_dir2_data_hdr *hdr)
> @@ -160,23 +131,6 @@ xfs_dir2_ftype_data_first_entry_p(
>  				XFS_DIR3_DATA_ENTSIZE(2));
>  }
>  
> -static struct xfs_dir2_data_entry *
> -xfs_dir3_data_dot_entry_p(
> -	struct xfs_dir2_data_hdr *hdr)
> -{
> -	return (struct xfs_dir2_data_entry *)
> -		((char *)hdr + sizeof(struct xfs_dir3_data_hdr));
> -}
> -
> -static struct xfs_dir2_data_entry *
> -xfs_dir3_data_dotdot_entry_p(
> -	struct xfs_dir2_data_hdr *hdr)
> -{
> -	return (struct xfs_dir2_data_entry *)
> -		((char *)hdr + sizeof(struct xfs_dir3_data_hdr) +
> -				XFS_DIR3_DATA_ENTSIZE(1));
> -}
> -
>  static struct xfs_dir2_data_entry *
>  xfs_dir3_data_first_entry_p(
>  	struct xfs_dir2_data_hdr *hdr)
> @@ -242,8 +196,6 @@ static const struct xfs_dir_ops xfs_dir2_ops = {
>  				XFS_DIR2_DATA_ENTSIZE(2),
>  	.data_entry_offset = sizeof(struct xfs_dir2_data_hdr),
>  
> -	.data_dot_entry_p = xfs_dir2_data_dot_entry_p,
> -	.data_dotdot_entry_p = xfs_dir2_data_dotdot_entry_p,
>  	.data_first_entry_p = xfs_dir2_data_first_entry_p,
>  	.data_entry_p = xfs_dir2_data_entry_p,
>  	.data_unused_p = xfs_dir2_data_unused_p,
> @@ -264,8 +216,6 @@ static const struct xfs_dir_ops xfs_dir2_ftype_ops = {
>  				XFS_DIR3_DATA_ENTSIZE(2),
>  	.data_entry_offset = sizeof(struct xfs_dir2_data_hdr),
>  
> -	.data_dot_entry_p = xfs_dir2_data_dot_entry_p,
> -	.data_dotdot_entry_p = xfs_dir2_ftype_data_dotdot_entry_p,
>  	.data_first_entry_p = xfs_dir2_ftype_data_first_entry_p,
>  	.data_entry_p = xfs_dir2_data_entry_p,
>  	.data_unused_p = xfs_dir2_data_unused_p,
> @@ -286,8 +236,6 @@ static const struct xfs_dir_ops xfs_dir3_ops = {
>  				XFS_DIR3_DATA_ENTSIZE(2),
>  	.data_entry_offset = sizeof(struct xfs_dir3_data_hdr),
>  
> -	.data_dot_entry_p = xfs_dir3_data_dot_entry_p,
> -	.data_dotdot_entry_p = xfs_dir3_data_dotdot_entry_p,
>  	.data_first_entry_p = xfs_dir3_data_first_entry_p,
>  	.data_entry_p = xfs_dir3_data_entry_p,
>  	.data_unused_p = xfs_dir3_data_unused_p,
> diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h
> index 61cc9ae837d5..0198887a1c54 100644
> --- a/fs/xfs/libxfs/xfs_dir2.h
> +++ b/fs/xfs/libxfs/xfs_dir2.h
> @@ -45,10 +45,6 @@ struct xfs_dir_ops {
>  	xfs_dir2_data_aoff_t data_first_offset;
>  	size_t	data_entry_offset;
>  
> -	struct xfs_dir2_data_entry *
> -		(*data_dot_entry_p)(struct xfs_dir2_data_hdr *hdr);
> -	struct xfs_dir2_data_entry *
> -		(*data_dotdot_entry_p)(struct xfs_dir2_data_hdr *hdr);
>  	struct xfs_dir2_data_entry *
>  		(*data_first_entry_p)(struct xfs_dir2_data_hdr *hdr);
>  	struct xfs_dir2_data_entry *
> diff --git a/fs/xfs/libxfs/xfs_dir2_block.c b/fs/xfs/libxfs/xfs_dir2_block.c
> index 5877272dc63e..34e0cdf03950 100644
> --- a/fs/xfs/libxfs/xfs_dir2_block.c
> +++ b/fs/xfs/libxfs/xfs_dir2_block.c
> @@ -1148,7 +1148,7 @@ xfs_dir2_sf_to_block(
>  	/*
>  	 * Create entry for .
>  	 */
> -	dep = dp->d_ops->data_dot_entry_p(hdr);
> +	dep = (void *)hdr + dp->d_ops->data_dot_offset;

Same complaint about (void *) arithmetic as last time.

Also, why not leave a static inline helper function or two to
encapsulate the pointer arithmetic and ensure type checking?

--D

>  	dep->inumber = cpu_to_be64(dp->i_ino);
>  	dep->namelen = 1;
>  	dep->name[0] = '.';
> @@ -1162,7 +1162,7 @@ xfs_dir2_sf_to_block(
>  	/*
>  	 * Create entry for ..
>  	 */
> -	dep = dp->d_ops->data_dotdot_entry_p(hdr);
> +	dep = (void *)hdr + dp->d_ops->data_dotdot_offset;
>  	dep->inumber = cpu_to_be64(xfs_dir2_sf_get_parent_ino(sfp));
>  	dep->namelen = 2;
>  	dep->name[0] = dep->name[1] = '.';
> -- 
> 2.20.1
> 

^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH 24/34] xfs: remove the unused ->data_first_entry_p method
  2019-11-01 22:07 ` [PATCH 24/34] xfs: remove the unused ->data_first_entry_p method Christoph Hellwig
@ 2019-11-04 20:38   ` Darrick J. Wong
  0 siblings, 0 replies; 81+ messages in thread
From: Darrick J. Wong @ 2019-11-04 20:38 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-xfs

On Fri, Nov 01, 2019 at 03:07:09PM -0700, Christoph Hellwig wrote:
> Signed-off-by: Christoph Hellwig <hch@lst.de>

LOL.
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>

--D

> ---
>  fs/xfs/libxfs/xfs_da_format.c | 33 ---------------------------------
>  fs/xfs/libxfs/xfs_dir2.h      |  2 --
>  2 files changed, 35 deletions(-)
> 
> diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c
> index 84f8355072b4..35edf470efc8 100644
> --- a/fs/xfs/libxfs/xfs_da_format.c
> +++ b/fs/xfs/libxfs/xfs_da_format.c
> @@ -111,36 +111,6 @@ xfs_dir3_data_entry_tag_p(
>  		xfs_dir3_data_entsize(dep->namelen) - sizeof(__be16));
>  }
>  
> -static struct xfs_dir2_data_entry *
> -xfs_dir2_data_first_entry_p(
> -	struct xfs_dir2_data_hdr *hdr)
> -{
> -	return (struct xfs_dir2_data_entry *)
> -		((char *)hdr + sizeof(struct xfs_dir2_data_hdr) +
> -				XFS_DIR2_DATA_ENTSIZE(1) +
> -				XFS_DIR2_DATA_ENTSIZE(2));
> -}
> -
> -static struct xfs_dir2_data_entry *
> -xfs_dir2_ftype_data_first_entry_p(
> -	struct xfs_dir2_data_hdr *hdr)
> -{
> -	return (struct xfs_dir2_data_entry *)
> -		((char *)hdr + sizeof(struct xfs_dir2_data_hdr) +
> -				XFS_DIR3_DATA_ENTSIZE(1) +
> -				XFS_DIR3_DATA_ENTSIZE(2));
> -}
> -
> -static struct xfs_dir2_data_entry *
> -xfs_dir3_data_first_entry_p(
> -	struct xfs_dir2_data_hdr *hdr)
> -{
> -	return (struct xfs_dir2_data_entry *)
> -		((char *)hdr + sizeof(struct xfs_dir3_data_hdr) +
> -				XFS_DIR3_DATA_ENTSIZE(1) +
> -				XFS_DIR3_DATA_ENTSIZE(2));
> -}
> -
>  static struct xfs_dir2_data_free *
>  xfs_dir2_data_bestfree_p(struct xfs_dir2_data_hdr *hdr)
>  {
> @@ -196,7 +166,6 @@ static const struct xfs_dir_ops xfs_dir2_ops = {
>  				XFS_DIR2_DATA_ENTSIZE(2),
>  	.data_entry_offset = sizeof(struct xfs_dir2_data_hdr),
>  
> -	.data_first_entry_p = xfs_dir2_data_first_entry_p,
>  	.data_entry_p = xfs_dir2_data_entry_p,
>  	.data_unused_p = xfs_dir2_data_unused_p,
>  };
> @@ -216,7 +185,6 @@ static const struct xfs_dir_ops xfs_dir2_ftype_ops = {
>  				XFS_DIR3_DATA_ENTSIZE(2),
>  	.data_entry_offset = sizeof(struct xfs_dir2_data_hdr),
>  
> -	.data_first_entry_p = xfs_dir2_ftype_data_first_entry_p,
>  	.data_entry_p = xfs_dir2_data_entry_p,
>  	.data_unused_p = xfs_dir2_data_unused_p,
>  };
> @@ -236,7 +204,6 @@ static const struct xfs_dir_ops xfs_dir3_ops = {
>  				XFS_DIR3_DATA_ENTSIZE(2),
>  	.data_entry_offset = sizeof(struct xfs_dir3_data_hdr),
>  
> -	.data_first_entry_p = xfs_dir3_data_first_entry_p,
>  	.data_entry_p = xfs_dir3_data_entry_p,
>  	.data_unused_p = xfs_dir3_data_unused_p,
>  };
> diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h
> index 0198887a1c54..20417c42ca6f 100644
> --- a/fs/xfs/libxfs/xfs_dir2.h
> +++ b/fs/xfs/libxfs/xfs_dir2.h
> @@ -45,8 +45,6 @@ struct xfs_dir_ops {
>  	xfs_dir2_data_aoff_t data_first_offset;
>  	size_t	data_entry_offset;
>  
> -	struct xfs_dir2_data_entry *
> -		(*data_first_entry_p)(struct xfs_dir2_data_hdr *hdr);
>  	struct xfs_dir2_data_entry *
>  		(*data_entry_p)(struct xfs_dir2_data_hdr *hdr);
>  	struct xfs_dir2_data_unused *
> -- 
> 2.20.1
> 

^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH 25/34] xfs: remove the ->data_entry_entry_p method
  2019-11-01 22:07 ` [PATCH 25/34] xfs: remove the ->data_entry_entry_p method Christoph Hellwig
@ 2019-11-04 20:41   ` Darrick J. Wong
  0 siblings, 0 replies; 81+ messages in thread
From: Darrick J. Wong @ 2019-11-04 20:41 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-xfs

On Fri, Nov 01, 2019 at 03:07:10PM -0700, Christoph Hellwig wrote:
> Replace the users of the ->data_entry_entry_p dir ops method with a
> direct calculation using ->data_entry_offset.
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
>  fs/xfs/libxfs/xfs_da_format.c  | 37 ----------------------------------
>  fs/xfs/libxfs/xfs_dir2.h       |  5 -----
>  fs/xfs/libxfs/xfs_dir2_block.c |  2 +-
>  fs/xfs/libxfs/xfs_dir2_data.c  |  6 +++---
>  fs/xfs/libxfs/xfs_dir2_sf.c    |  2 +-
>  fs/xfs/scrub/dir.c             |  4 ++--
>  fs/xfs/xfs_dir2_readdir.c      |  4 ++--
>  7 files changed, 9 insertions(+), 51 deletions(-)
> 
> diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c
> index 35edf470efc8..47c56f6dd872 100644
> --- a/fs/xfs/libxfs/xfs_da_format.c
> +++ b/fs/xfs/libxfs/xfs_da_format.c
> @@ -123,34 +123,6 @@ xfs_dir3_data_bestfree_p(struct xfs_dir2_data_hdr *hdr)
>  	return ((struct xfs_dir3_data_hdr *)hdr)->best_free;
>  }
>  
> -static struct xfs_dir2_data_entry *
> -xfs_dir2_data_entry_p(struct xfs_dir2_data_hdr *hdr)
> -{
> -	return (struct xfs_dir2_data_entry *)
> -		((char *)hdr + sizeof(struct xfs_dir2_data_hdr));
> -}
> -
> -static struct xfs_dir2_data_unused *
> -xfs_dir2_data_unused_p(struct xfs_dir2_data_hdr *hdr)
> -{
> -	return (struct xfs_dir2_data_unused *)
> -		((char *)hdr + sizeof(struct xfs_dir2_data_hdr));
> -}
> -
> -static struct xfs_dir2_data_entry *
> -xfs_dir3_data_entry_p(struct xfs_dir2_data_hdr *hdr)
> -{
> -	return (struct xfs_dir2_data_entry *)
> -		((char *)hdr + sizeof(struct xfs_dir3_data_hdr));
> -}
> -
> -static struct xfs_dir2_data_unused *
> -xfs_dir3_data_unused_p(struct xfs_dir2_data_hdr *hdr)
> -{
> -	return (struct xfs_dir2_data_unused *)
> -		((char *)hdr + sizeof(struct xfs_dir3_data_hdr));
> -}
> -
>  static const struct xfs_dir_ops xfs_dir2_ops = {
>  	.data_entsize = xfs_dir2_data_entsize,
>  	.data_get_ftype = xfs_dir2_data_get_ftype,
> @@ -165,9 +137,6 @@ static const struct xfs_dir_ops xfs_dir2_ops = {
>  				XFS_DIR2_DATA_ENTSIZE(1) +
>  				XFS_DIR2_DATA_ENTSIZE(2),
>  	.data_entry_offset = sizeof(struct xfs_dir2_data_hdr),
> -
> -	.data_entry_p = xfs_dir2_data_entry_p,
> -	.data_unused_p = xfs_dir2_data_unused_p,
>  };
>  
>  static const struct xfs_dir_ops xfs_dir2_ftype_ops = {
> @@ -184,9 +153,6 @@ static const struct xfs_dir_ops xfs_dir2_ftype_ops = {
>  				XFS_DIR3_DATA_ENTSIZE(1) +
>  				XFS_DIR3_DATA_ENTSIZE(2),
>  	.data_entry_offset = sizeof(struct xfs_dir2_data_hdr),
> -
> -	.data_entry_p = xfs_dir2_data_entry_p,
> -	.data_unused_p = xfs_dir2_data_unused_p,
>  };
>  
>  static const struct xfs_dir_ops xfs_dir3_ops = {
> @@ -203,9 +169,6 @@ static const struct xfs_dir_ops xfs_dir3_ops = {
>  				XFS_DIR3_DATA_ENTSIZE(1) +
>  				XFS_DIR3_DATA_ENTSIZE(2),
>  	.data_entry_offset = sizeof(struct xfs_dir3_data_hdr),
> -
> -	.data_entry_p = xfs_dir3_data_entry_p,
> -	.data_unused_p = xfs_dir3_data_unused_p,
>  };
>  
>  /*
> diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h
> index 20417c42ca6f..e9de15e62630 100644
> --- a/fs/xfs/libxfs/xfs_dir2.h
> +++ b/fs/xfs/libxfs/xfs_dir2.h
> @@ -44,11 +44,6 @@ struct xfs_dir_ops {
>  	xfs_dir2_data_aoff_t data_dotdot_offset;
>  	xfs_dir2_data_aoff_t data_first_offset;
>  	size_t	data_entry_offset;
> -
> -	struct xfs_dir2_data_entry *
> -		(*data_entry_p)(struct xfs_dir2_data_hdr *hdr);
> -	struct xfs_dir2_data_unused *
> -		(*data_unused_p)(struct xfs_dir2_data_hdr *hdr);
>  };
>  
>  extern const struct xfs_dir_ops *
> diff --git a/fs/xfs/libxfs/xfs_dir2_block.c b/fs/xfs/libxfs/xfs_dir2_block.c
> index 34e0cdf03950..b32beb71b7b2 100644
> --- a/fs/xfs/libxfs/xfs_dir2_block.c
> +++ b/fs/xfs/libxfs/xfs_dir2_block.c
> @@ -1122,7 +1122,7 @@ xfs_dir2_sf_to_block(
>  	 * The whole thing is initialized to free by the init routine.
>  	 * Say we're using the leaf and tail area.
>  	 */
> -	dup = dp->d_ops->data_unused_p(hdr);
> +	dup = (void *)hdr + dp->d_ops->data_entry_offset;
>  	needlog = needscan = 0;
>  	error = xfs_dir2_data_use_free(args, bp, dup, args->geo->blksize - i,
>  			i, &needlog, &needscan);
> diff --git a/fs/xfs/libxfs/xfs_dir2_data.c b/fs/xfs/libxfs/xfs_dir2_data.c
> index 2c79be4c3153..edb3fe5c9174 100644
> --- a/fs/xfs/libxfs/xfs_dir2_data.c
> +++ b/fs/xfs/libxfs/xfs_dir2_data.c
> @@ -71,7 +71,7 @@ __xfs_dir3_data_check(
>  		return __this_address;
>  
>  	hdr = bp->b_addr;
> -	p = (char *)ops->data_entry_p(hdr);
> +	p = (char *)hdr + ops->data_entry_offset;
>  
>  	switch (hdr->magic) {
>  	case cpu_to_be32(XFS_DIR3_BLOCK_MAGIC):
> @@ -587,7 +587,7 @@ xfs_dir2_data_freescan_int(
>  	/*
>  	 * Set up pointers.
>  	 */
> -	p = (char *)ops->data_entry_p(hdr);
> +	p = (char *)hdr + ops->data_entry_offset;
>  	endp = xfs_dir3_data_endp(geo, hdr);
>  	/*
>  	 * Loop over the block's entries.
> @@ -685,7 +685,7 @@ xfs_dir3_data_init(
>  	/*
>  	 * Set up an unused entry for the block's body.
>  	 */
> -	dup = dp->d_ops->data_unused_p(hdr);
> +	dup = (void *)hdr + dp->d_ops->data_entry_offset;
>  	dup->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG);
>  
>  	t = args->geo->blksize - (uint)dp->d_ops->data_entry_offset;
> diff --git a/fs/xfs/libxfs/xfs_dir2_sf.c b/fs/xfs/libxfs/xfs_dir2_sf.c
> index 10199261c94c..b2c6c492b09d 100644
> --- a/fs/xfs/libxfs/xfs_dir2_sf.c
> +++ b/fs/xfs/libxfs/xfs_dir2_sf.c
> @@ -296,7 +296,7 @@ xfs_dir2_block_to_sf(
>  	/*
>  	 * Set up to loop over the block's entries.
>  	 */
> -	ptr = (char *)dp->d_ops->data_entry_p(hdr);
> +	ptr = (char *)hdr + dp->d_ops->data_entry_offset;
>  	endptr = xfs_dir3_data_endp(args->geo, hdr);
>  	sfep = xfs_dir2_sf_firstentry(sfp);
>  	/*
> diff --git a/fs/xfs/scrub/dir.c b/fs/xfs/scrub/dir.c
> index dfaa0fca617e..8d6ecfe09611 100644
> --- a/fs/xfs/scrub/dir.c
> +++ b/fs/xfs/scrub/dir.c
> @@ -241,7 +241,7 @@ xchk_dir_rec(
>  	dent = (struct xfs_dir2_data_entry *)(((char *)bp->b_addr) + off);
>  
>  	/* Make sure we got a real directory entry. */
> -	p = (char *)mp->m_dir_inode_ops->data_entry_p(bp->b_addr);
> +	p = bp->b_addr + mp->m_dir_inode_ops->data_entry_offset;
>  	endp = xfs_dir3_data_endp(mp->m_dir_geo, bp->b_addr);
>  	if (!endp) {
>  		xchk_fblock_set_corrupt(ds->sc, XFS_DATA_FORK, rec_bno);
> @@ -391,7 +391,7 @@ xchk_directory_data_bestfree(
>  	}
>  
>  	/* Make sure the bestfrees are actually the best free spaces. */
> -	ptr = (char *)d_ops->data_entry_p(bp->b_addr);
> +	ptr = bp->b_addr + d_ops->data_entry_offset;
>  	endptr = xfs_dir3_data_endp(mp->m_dir_geo, bp->b_addr);
>  
>  	/* Iterate the entries, stopping when we hit or go past the end. */
> diff --git a/fs/xfs/xfs_dir2_readdir.c b/fs/xfs/xfs_dir2_readdir.c
> index e18045465455..04f8c2451b93 100644
> --- a/fs/xfs/xfs_dir2_readdir.c
> +++ b/fs/xfs/xfs_dir2_readdir.c
> @@ -176,7 +176,7 @@ xfs_dir2_block_getdents(
>  	/*
>  	 * Set up values for the loop.
>  	 */
> -	ptr = (char *)dp->d_ops->data_entry_p(hdr);
> +	ptr = (char *)hdr + dp->d_ops->data_entry_offset;
>  	endptr = xfs_dir3_data_endp(geo, hdr);
>  
>  	/*
> @@ -410,7 +410,7 @@ xfs_dir2_leaf_getdents(
>  			/*
>  			 * Find our position in the block.
>  			 */
> -			ptr = (char *)dp->d_ops->data_entry_p(hdr);
> +			ptr = (char *)hdr + dp->d_ops->data_entry_offset;

/me thinks we're open-coding this calculation enough to warrant a static
inline helper...

--D

>  			byteoff = xfs_dir2_byte_to_off(geo, curoff);
>  			/*
>  			 * Skip past the header.
> -- 
> 2.20.1
> 

^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH 26/34] xfs: devirtualize ->data_entsize
  2019-11-01 22:07 ` [PATCH 26/34] xfs: devirtualize ->data_entsize Christoph Hellwig
@ 2019-11-04 20:45   ` Darrick J. Wong
  0 siblings, 0 replies; 81+ messages in thread
From: Darrick J. Wong @ 2019-11-04 20:45 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-xfs

On Fri, Nov 01, 2019 at 03:07:11PM -0700, Christoph Hellwig wrote:
> Replace the ->data_entsize dir ops method with a directly called
> xfs_dir2_data_entsize helper that takes care of the differences between
> the directory format with and without the file type field.
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
>  fs/xfs/libxfs/xfs_da_format.c  | 22 ++++++++--------------
>  fs/xfs/libxfs/xfs_dir2.h       |  3 +--
>  fs/xfs/libxfs/xfs_dir2_block.c |  5 +++--
>  fs/xfs/libxfs/xfs_dir2_data.c  | 13 ++++++-------
>  fs/xfs/libxfs/xfs_dir2_leaf.c  |  5 +++--
>  fs/xfs/libxfs/xfs_dir2_node.c  |  7 ++++---
>  fs/xfs/libxfs/xfs_dir2_priv.h  |  2 ++
>  fs/xfs/libxfs/xfs_dir2_sf.c    | 14 +++++++-------
>  fs/xfs/scrub/dir.c             |  4 ++--
>  fs/xfs/xfs_dir2_readdir.c      |  9 +++++----
>  10 files changed, 41 insertions(+), 43 deletions(-)
> 
> diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c
> index 47c56f6dd872..bbff0e7822b8 100644
> --- a/fs/xfs/libxfs/xfs_da_format.c
> +++ b/fs/xfs/libxfs/xfs_da_format.c
> @@ -41,18 +41,15 @@
>  		 sizeof(xfs_dir2_data_off_t) + sizeof(uint8_t)),	\
>  		XFS_DIR2_DATA_ALIGN)
>  
> -static int
> +int
>  xfs_dir2_data_entsize(
> +	struct xfs_mount	*mp,
>  	int			n)

@namelen, not just @n?

Oh, you do change that later.

Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>

--D

>  {
> -	return XFS_DIR2_DATA_ENTSIZE(n);
> -}
> -
> -static int
> -xfs_dir3_data_entsize(
> -	int			n)
> -{
> -	return XFS_DIR3_DATA_ENTSIZE(n);
> +	if (xfs_sb_version_hasftype(&mp->m_sb))
> +		return XFS_DIR3_DATA_ENTSIZE(n);
> +	else
> +		return XFS_DIR2_DATA_ENTSIZE(n);
>  }
>  
>  static uint8_t
> @@ -100,7 +97,7 @@ xfs_dir2_data_entry_tag_p(
>  	struct xfs_dir2_data_entry *dep)
>  {
>  	return (__be16 *)((char *)dep +
> -		xfs_dir2_data_entsize(dep->namelen) - sizeof(__be16));
> +		XFS_DIR2_DATA_ENTSIZE(dep->namelen) - sizeof(__be16));
>  }
>  
>  static __be16 *
> @@ -108,7 +105,7 @@ xfs_dir3_data_entry_tag_p(
>  	struct xfs_dir2_data_entry *dep)
>  {
>  	return (__be16 *)((char *)dep +
> -		xfs_dir3_data_entsize(dep->namelen) - sizeof(__be16));
> +		XFS_DIR3_DATA_ENTSIZE(dep->namelen) - sizeof(__be16));
>  }
>  
>  static struct xfs_dir2_data_free *
> @@ -124,7 +121,6 @@ xfs_dir3_data_bestfree_p(struct xfs_dir2_data_hdr *hdr)
>  }
>  
>  static const struct xfs_dir_ops xfs_dir2_ops = {
> -	.data_entsize = xfs_dir2_data_entsize,
>  	.data_get_ftype = xfs_dir2_data_get_ftype,
>  	.data_put_ftype = xfs_dir2_data_put_ftype,
>  	.data_entry_tag_p = xfs_dir2_data_entry_tag_p,
> @@ -140,7 +136,6 @@ static const struct xfs_dir_ops xfs_dir2_ops = {
>  };
>  
>  static const struct xfs_dir_ops xfs_dir2_ftype_ops = {
> -	.data_entsize = xfs_dir3_data_entsize,
>  	.data_get_ftype = xfs_dir3_data_get_ftype,
>  	.data_put_ftype = xfs_dir3_data_put_ftype,
>  	.data_entry_tag_p = xfs_dir3_data_entry_tag_p,
> @@ -156,7 +151,6 @@ static const struct xfs_dir_ops xfs_dir2_ftype_ops = {
>  };
>  
>  static const struct xfs_dir_ops xfs_dir3_ops = {
> -	.data_entsize = xfs_dir3_data_entsize,
>  	.data_get_ftype = xfs_dir3_data_get_ftype,
>  	.data_put_ftype = xfs_dir3_data_put_ftype,
>  	.data_entry_tag_p = xfs_dir3_data_entry_tag_p,
> diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h
> index e9de15e62630..3fb2c514437a 100644
> --- a/fs/xfs/libxfs/xfs_dir2.h
> +++ b/fs/xfs/libxfs/xfs_dir2.h
> @@ -32,7 +32,6 @@ extern unsigned char xfs_mode_to_ftype(int mode);
>   * directory operations vector for encode/decode routines
>   */
>  struct xfs_dir_ops {
> -	int	(*data_entsize)(int len);
>  	uint8_t (*data_get_ftype)(struct xfs_dir2_data_entry *dep);
>  	void	(*data_put_ftype)(struct xfs_dir2_data_entry *dep,
>  				uint8_t ftype);
> @@ -87,7 +86,7 @@ extern int xfs_dir2_isleaf(struct xfs_da_args *args, int *r);
>  extern int xfs_dir2_shrink_inode(struct xfs_da_args *args, xfs_dir2_db_t db,
>  				struct xfs_buf *bp);
>  
> -extern void xfs_dir2_data_freescan_int(struct xfs_da_geometry *geo,
> +extern void xfs_dir2_data_freescan_int(struct xfs_mount *mp,
>  		const struct xfs_dir_ops *ops,
>  		struct xfs_dir2_data_hdr *hdr, int *loghead);
>  extern void xfs_dir2_data_freescan(struct xfs_inode *dp,
> diff --git a/fs/xfs/libxfs/xfs_dir2_block.c b/fs/xfs/libxfs/xfs_dir2_block.c
> index b32beb71b7b2..709423199369 100644
> --- a/fs/xfs/libxfs/xfs_dir2_block.c
> +++ b/fs/xfs/libxfs/xfs_dir2_block.c
> @@ -355,7 +355,7 @@ xfs_dir2_block_addname(
>  	if (error)
>  		return error;
>  
> -	len = dp->d_ops->data_entsize(args->namelen);
> +	len = xfs_dir2_data_entsize(dp->i_mount, args->namelen);
>  
>  	/*
>  	 * Set up pointers to parts of the block.
> @@ -791,7 +791,8 @@ xfs_dir2_block_removename(
>  	needlog = needscan = 0;
>  	xfs_dir2_data_make_free(args, bp,
>  		(xfs_dir2_data_aoff_t)((char *)dep - (char *)hdr),
> -		dp->d_ops->data_entsize(dep->namelen), &needlog, &needscan);
> +		xfs_dir2_data_entsize(dp->i_mount, dep->namelen), &needlog,
> +		&needscan);
>  	/*
>  	 * Fix up the block tail.
>  	 */
> diff --git a/fs/xfs/libxfs/xfs_dir2_data.c b/fs/xfs/libxfs/xfs_dir2_data.c
> index edb3fe5c9174..7e3d35f0cdb5 100644
> --- a/fs/xfs/libxfs/xfs_dir2_data.c
> +++ b/fs/xfs/libxfs/xfs_dir2_data.c
> @@ -173,7 +173,7 @@ __xfs_dir3_data_check(
>  			return __this_address;
>  		if (xfs_dir_ino_validate(mp, be64_to_cpu(dep->inumber)))
>  			return __this_address;
> -		if (endp < p + ops->data_entsize(dep->namelen))
> +		if (endp < p + xfs_dir2_data_entsize(mp, dep->namelen))
>  			return __this_address;
>  		if (be16_to_cpu(*ops->data_entry_tag_p(dep)) !=
>  		    (char *)dep - (char *)hdr)
> @@ -198,7 +198,7 @@ __xfs_dir3_data_check(
>  			if (i >= be32_to_cpu(btp->count))
>  				return __this_address;
>  		}
> -		p += ops->data_entsize(dep->namelen);
> +		p += xfs_dir2_data_entsize(mp, dep->namelen);
>  	}
>  	/*
>  	 * Need to have seen all the entries and all the bestfree slots.
> @@ -562,7 +562,7 @@ xfs_dir2_data_freeremove(
>   */
>  void
>  xfs_dir2_data_freescan_int(
> -	struct xfs_da_geometry	*geo,
> +	struct xfs_mount	*mp,
>  	const struct xfs_dir_ops *ops,
>  	struct xfs_dir2_data_hdr *hdr,
>  	int			*loghead)
> @@ -588,7 +588,7 @@ xfs_dir2_data_freescan_int(
>  	 * Set up pointers.
>  	 */
>  	p = (char *)hdr + ops->data_entry_offset;
> -	endp = xfs_dir3_data_endp(geo, hdr);
> +	endp = xfs_dir3_data_endp(mp->m_dir_geo, hdr);
>  	/*
>  	 * Loop over the block's entries.
>  	 */
> @@ -610,7 +610,7 @@ xfs_dir2_data_freescan_int(
>  			dep = (xfs_dir2_data_entry_t *)p;
>  			ASSERT((char *)dep - (char *)hdr ==
>  			       be16_to_cpu(*ops->data_entry_tag_p(dep)));
> -			p += ops->data_entsize(dep->namelen);
> +			p += xfs_dir2_data_entsize(mp, dep->namelen);
>  		}
>  	}
>  }
> @@ -621,8 +621,7 @@ xfs_dir2_data_freescan(
>  	struct xfs_dir2_data_hdr *hdr,
>  	int			*loghead)
>  {
> -	return xfs_dir2_data_freescan_int(dp->i_mount->m_dir_geo, dp->d_ops,
> -			hdr, loghead);
> +	return xfs_dir2_data_freescan_int(dp->i_mount, dp->d_ops, hdr, loghead);
>  }
>  
>  /*
> diff --git a/fs/xfs/libxfs/xfs_dir2_leaf.c b/fs/xfs/libxfs/xfs_dir2_leaf.c
> index 3770107c0695..2f7eda3008a6 100644
> --- a/fs/xfs/libxfs/xfs_dir2_leaf.c
> +++ b/fs/xfs/libxfs/xfs_dir2_leaf.c
> @@ -660,7 +660,7 @@ xfs_dir2_leaf_addname(
>  	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);
> +	length = xfs_dir2_data_entsize(dp->i_mount, args->namelen);
>  
>  	/*
>  	 * See if there are any entries with the same hash value
> @@ -1395,7 +1395,8 @@ xfs_dir2_leaf_removename(
>  	 */
>  	xfs_dir2_data_make_free(args, dbp,
>  		(xfs_dir2_data_aoff_t)((char *)dep - (char *)hdr),
> -		dp->d_ops->data_entsize(dep->namelen), &needlog, &needscan);
> +		xfs_dir2_data_entsize(dp->i_mount, dep->namelen), &needlog,
> +		&needscan);
>  	/*
>  	 * We just mark the leaf entry stale by putting a null in it.
>  	 */
> diff --git a/fs/xfs/libxfs/xfs_dir2_node.c b/fs/xfs/libxfs/xfs_dir2_node.c
> index ceb5936b58dd..d08a11121dee 100644
> --- a/fs/xfs/libxfs/xfs_dir2_node.c
> +++ b/fs/xfs/libxfs/xfs_dir2_node.c
> @@ -662,7 +662,7 @@ xfs_dir2_leafn_lookup_for_addname(
>  		ASSERT(free->hdr.magic == cpu_to_be32(XFS_DIR2_FREE_MAGIC) ||
>  		       free->hdr.magic == cpu_to_be32(XFS_DIR3_FREE_MAGIC));
>  	}
> -	length = dp->d_ops->data_entsize(args->namelen);
> +	length = xfs_dir2_data_entsize(mp, args->namelen);
>  	/*
>  	 * Loop over leaf entries with the right hash value.
>  	 */
> @@ -1314,7 +1314,8 @@ xfs_dir2_leafn_remove(
>  	longest = be16_to_cpu(bf[0].length);
>  	needlog = needscan = 0;
>  	xfs_dir2_data_make_free(args, dbp, off,
> -		dp->d_ops->data_entsize(dep->namelen), &needlog, &needscan);
> +		xfs_dir2_data_entsize(dp->i_mount, dep->namelen), &needlog,
> +		&needscan);
>  	/*
>  	 * Rescan the data block freespaces for bestfree.
>  	 * Log the data block header if needed.
> @@ -1907,7 +1908,7 @@ xfs_dir2_node_addname_int(
>  	int			needscan = 0;	/* need to rescan data frees */
>  	__be16			*tagp;		/* data entry tag pointer */
>  
> -	length = dp->d_ops->data_entsize(args->namelen);
> +	length = xfs_dir2_data_entsize(dp->i_mount, args->namelen);
>  	error = xfs_dir2_node_find_freeblk(args, fblk, &dbno, &fbp, &freehdr,
>  					   &findex, length);
>  	if (error)
> diff --git a/fs/xfs/libxfs/xfs_dir2_priv.h b/fs/xfs/libxfs/xfs_dir2_priv.h
> index a92d9f0f83e0..585b7b42c204 100644
> --- a/fs/xfs/libxfs/xfs_dir2_priv.h
> +++ b/fs/xfs/libxfs/xfs_dir2_priv.h
> @@ -47,6 +47,8 @@ extern int xfs_dir2_leaf_to_block(struct xfs_da_args *args,
>  		struct xfs_buf *lbp, struct xfs_buf *dbp);
>  
>  /* xfs_dir2_data.c */
> +int xfs_dir2_data_entsize(struct xfs_mount *mp, int n);
> +
>  #ifdef DEBUG
>  extern void xfs_dir3_data_check(struct xfs_inode *dp, struct xfs_buf *bp);
>  #else
> diff --git a/fs/xfs/libxfs/xfs_dir2_sf.c b/fs/xfs/libxfs/xfs_dir2_sf.c
> index b2c6c492b09d..4885a0e920c5 100644
> --- a/fs/xfs/libxfs/xfs_dir2_sf.c
> +++ b/fs/xfs/libxfs/xfs_dir2_sf.c
> @@ -341,7 +341,7 @@ xfs_dir2_block_to_sf(
>  
>  			sfep = xfs_dir2_sf_nextentry(mp, sfp, sfep);
>  		}
> -		ptr += dp->d_ops->data_entsize(dep->namelen);
> +		ptr += xfs_dir2_data_entsize(mp, dep->namelen);
>  	}
>  	ASSERT((char *)sfep - (char *)sfp == size);
>  
> @@ -564,10 +564,10 @@ xfs_dir2_sf_addname_hard(
>  	 */
>  	for (offset = dp->d_ops->data_first_offset,
>  	      oldsfep = xfs_dir2_sf_firstentry(oldsfp),
> -	      add_datasize = dp->d_ops->data_entsize(args->namelen),
> +	      add_datasize = xfs_dir2_data_entsize(mp, args->namelen),
>  	      eof = (char *)oldsfep == &buf[old_isize];
>  	     !eof;
> -	     offset = new_offset + dp->d_ops->data_entsize(oldsfep->namelen),
> +	     offset = new_offset + xfs_dir2_data_entsize(mp, oldsfep->namelen),
>  	      oldsfep = xfs_dir2_sf_nextentry(mp, oldsfp, oldsfep),
>  	      eof = (char *)oldsfep == &buf[old_isize]) {
>  		new_offset = xfs_dir2_sf_get_offset(oldsfep);
> @@ -639,7 +639,7 @@ xfs_dir2_sf_addname_pick(
>  	int			used;		/* data bytes used */
>  
>  	sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data;
> -	size = dp->d_ops->data_entsize(args->namelen);
> +	size = xfs_dir2_data_entsize(mp, args->namelen);
>  	offset = dp->d_ops->data_first_offset;
>  	sfep = xfs_dir2_sf_firstentry(sfp);
>  	holefit = 0;
> @@ -652,7 +652,7 @@ xfs_dir2_sf_addname_pick(
>  		if (!holefit)
>  			holefit = offset + size <= xfs_dir2_sf_get_offset(sfep);
>  		offset = xfs_dir2_sf_get_offset(sfep) +
> -			 dp->d_ops->data_entsize(sfep->namelen);
> +			 xfs_dir2_data_entsize(mp, sfep->namelen);
>  		sfep = xfs_dir2_sf_nextentry(mp, sfp, sfep);
>  	}
>  	/*
> @@ -717,7 +717,7 @@ xfs_dir2_sf_check(
>  		i8count += ino > XFS_DIR2_MAX_SHORT_INUM;
>  		offset =
>  			xfs_dir2_sf_get_offset(sfep) +
> -			dp->d_ops->data_entsize(sfep->namelen);
> +			xfs_dir2_data_entsize(mp, sfep->namelen);
>  		ASSERT(xfs_dir2_sf_get_ftype(mp, sfep) < XFS_DIR3_FT_MAX);
>  	}
>  	ASSERT(i8count == sfp->i8count);
> @@ -817,7 +817,7 @@ xfs_dir2_sf_verify(
>  			return __this_address;
>  
>  		offset = xfs_dir2_sf_get_offset(sfep) +
> -				dops->data_entsize(sfep->namelen);
> +				xfs_dir2_data_entsize(mp, sfep->namelen);
>  
>  		sfep = next_sfep;
>  	}
> diff --git a/fs/xfs/scrub/dir.c b/fs/xfs/scrub/dir.c
> index 8d6ecfe09611..5ddd95f12b85 100644
> --- a/fs/xfs/scrub/dir.c
> +++ b/fs/xfs/scrub/dir.c
> @@ -259,7 +259,7 @@ xchk_dir_rec(
>  		dep = (struct xfs_dir2_data_entry *)p;
>  		if (dep == dent)
>  			break;
> -		p += mp->m_dir_inode_ops->data_entsize(dep->namelen);
> +		p += xfs_dir2_data_entsize(mp, dep->namelen);
>  	}
>  	if (p >= endp) {
>  		xchk_fblock_set_corrupt(ds->sc, XFS_DATA_FORK, rec_bno);
> @@ -402,7 +402,7 @@ xchk_directory_data_bestfree(
>  			struct xfs_dir2_data_entry	*dep;
>  
>  			dep = (struct xfs_dir2_data_entry *)ptr;
> -			newlen = d_ops->data_entsize(dep->namelen);
> +			newlen = xfs_dir2_data_entsize(mp, dep->namelen);
>  			if (newlen <= 0) {
>  				xchk_fblock_set_corrupt(sc, XFS_DATA_FORK,
>  						lblk);
> diff --git a/fs/xfs/xfs_dir2_readdir.c b/fs/xfs/xfs_dir2_readdir.c
> index 04f8c2451b93..4cc4102c85f0 100644
> --- a/fs/xfs/xfs_dir2_readdir.c
> +++ b/fs/xfs/xfs_dir2_readdir.c
> @@ -200,7 +200,7 @@ xfs_dir2_block_getdents(
>  		/*
>  		 * Bump pointer for the next iteration.
>  		 */
> -		ptr += dp->d_ops->data_entsize(dep->namelen);
> +		ptr += xfs_dir2_data_entsize(dp->i_mount, dep->namelen);
>  		/*
>  		 * The entry is before the desired starting point, skip it.
>  		 */
> @@ -355,6 +355,7 @@ xfs_dir2_leaf_getdents(
>  	size_t			bufsize)
>  {
>  	struct xfs_inode	*dp = args->dp;
> +	struct xfs_mount	*mp = dp->i_mount;
>  	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 */
> @@ -432,8 +433,8 @@ xfs_dir2_leaf_getdents(
>  						continue;
>  					}
>  					dep = (xfs_dir2_data_entry_t *)ptr;
> -					length =
> -					   dp->d_ops->data_entsize(dep->namelen);
> +					length = xfs_dir2_data_entsize(mp,
> +							dep->namelen);
>  					ptr += length;
>  				}
>  				/*
> @@ -464,7 +465,7 @@ xfs_dir2_leaf_getdents(
>  		}
>  
>  		dep = (xfs_dir2_data_entry_t *)ptr;
> -		length = dp->d_ops->data_entsize(dep->namelen);
> +		length = xfs_dir2_data_entsize(mp, dep->namelen);
>  		filetype = dp->d_ops->data_get_ftype(dep);
>  
>  		ctx->pos = xfs_dir2_byte_to_dataptr(curoff) & 0x7fffffff;
> -- 
> 2.20.1
> 

^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH 27/34] xfs: devirtualize ->data_entry_tag_p
  2019-11-01 22:07 ` [PATCH 27/34] xfs: devirtualize ->data_entry_tag_p Christoph Hellwig
@ 2019-11-04 20:45   ` Darrick J. Wong
  0 siblings, 0 replies; 81+ messages in thread
From: Darrick J. Wong @ 2019-11-04 20:45 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-xfs

On Fri, Nov 01, 2019 at 03:07:12PM -0700, Christoph Hellwig wrote:
> Replace the ->data_entry_tag_p dir ops method with a directly called
> xfs_dir2_data_entry_tag_p helper that takes care of the differences
> between the directory format with and without the file type field.
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>

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

--D

> ---
>  fs/xfs/libxfs/xfs_da_format.c  | 22 ----------------------
>  fs/xfs/libxfs/xfs_dir2.h       |  1 -
>  fs/xfs/libxfs/xfs_dir2_block.c |  8 ++++----
>  fs/xfs/libxfs/xfs_dir2_data.c  | 21 ++++++++++++++++++---
>  fs/xfs/libxfs/xfs_dir2_leaf.c  |  2 +-
>  fs/xfs/libxfs/xfs_dir2_node.c  |  2 +-
>  fs/xfs/libxfs/xfs_dir2_priv.h  |  2 ++
>  fs/xfs/scrub/dir.c             |  2 +-
>  8 files changed, 27 insertions(+), 33 deletions(-)
> 
> diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c
> index bbff0e7822b8..9c247223326f 100644
> --- a/fs/xfs/libxfs/xfs_da_format.c
> +++ b/fs/xfs/libxfs/xfs_da_format.c
> @@ -89,25 +89,6 @@ xfs_dir3_data_put_ftype(
>  	dep->name[dep->namelen] = type;
>  }
>  
> -/*
> - * Pointer to an entry's tag word.
> - */
> -static __be16 *
> -xfs_dir2_data_entry_tag_p(
> -	struct xfs_dir2_data_entry *dep)
> -{
> -	return (__be16 *)((char *)dep +
> -		XFS_DIR2_DATA_ENTSIZE(dep->namelen) - sizeof(__be16));
> -}
> -
> -static __be16 *
> -xfs_dir3_data_entry_tag_p(
> -	struct xfs_dir2_data_entry *dep)
> -{
> -	return (__be16 *)((char *)dep +
> -		XFS_DIR3_DATA_ENTSIZE(dep->namelen) - sizeof(__be16));
> -}
> -
>  static struct xfs_dir2_data_free *
>  xfs_dir2_data_bestfree_p(struct xfs_dir2_data_hdr *hdr)
>  {
> @@ -123,7 +104,6 @@ xfs_dir3_data_bestfree_p(struct xfs_dir2_data_hdr *hdr)
>  static const struct xfs_dir_ops xfs_dir2_ops = {
>  	.data_get_ftype = xfs_dir2_data_get_ftype,
>  	.data_put_ftype = xfs_dir2_data_put_ftype,
> -	.data_entry_tag_p = xfs_dir2_data_entry_tag_p,
>  	.data_bestfree_p = xfs_dir2_data_bestfree_p,
>  
>  	.data_dot_offset = sizeof(struct xfs_dir2_data_hdr),
> @@ -138,7 +118,6 @@ static const struct xfs_dir_ops xfs_dir2_ops = {
>  static const struct xfs_dir_ops xfs_dir2_ftype_ops = {
>  	.data_get_ftype = xfs_dir3_data_get_ftype,
>  	.data_put_ftype = xfs_dir3_data_put_ftype,
> -	.data_entry_tag_p = xfs_dir3_data_entry_tag_p,
>  	.data_bestfree_p = xfs_dir2_data_bestfree_p,
>  
>  	.data_dot_offset = sizeof(struct xfs_dir2_data_hdr),
> @@ -153,7 +132,6 @@ static const struct xfs_dir_ops xfs_dir2_ftype_ops = {
>  static const struct xfs_dir_ops xfs_dir3_ops = {
>  	.data_get_ftype = xfs_dir3_data_get_ftype,
>  	.data_put_ftype = xfs_dir3_data_put_ftype,
> -	.data_entry_tag_p = xfs_dir3_data_entry_tag_p,
>  	.data_bestfree_p = xfs_dir3_data_bestfree_p,
>  
>  	.data_dot_offset = sizeof(struct xfs_dir3_data_hdr),
> diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h
> index 3fb2c514437a..8397e35d6b82 100644
> --- a/fs/xfs/libxfs/xfs_dir2.h
> +++ b/fs/xfs/libxfs/xfs_dir2.h
> @@ -35,7 +35,6 @@ struct xfs_dir_ops {
>  	uint8_t (*data_get_ftype)(struct xfs_dir2_data_entry *dep);
>  	void	(*data_put_ftype)(struct xfs_dir2_data_entry *dep,
>  				uint8_t ftype);
> -	__be16 * (*data_entry_tag_p)(struct xfs_dir2_data_entry *dep);
>  	struct xfs_dir2_data_free *
>  		(*data_bestfree_p)(struct xfs_dir2_data_hdr *hdr);
>  
> diff --git a/fs/xfs/libxfs/xfs_dir2_block.c b/fs/xfs/libxfs/xfs_dir2_block.c
> index 709423199369..4230ea945bc4 100644
> --- a/fs/xfs/libxfs/xfs_dir2_block.c
> +++ b/fs/xfs/libxfs/xfs_dir2_block.c
> @@ -542,7 +542,7 @@ xfs_dir2_block_addname(
>  	dep->namelen = args->namelen;
>  	memcpy(dep->name, args->name, args->namelen);
>  	dp->d_ops->data_put_ftype(dep, args->filetype);
> -	tagp = dp->d_ops->data_entry_tag_p(dep);
> +	tagp = xfs_dir2_data_entry_tag_p(dp->i_mount, dep);
>  	*tagp = cpu_to_be16((char *)dep - (char *)hdr);
>  	/*
>  	 * Clean up the bestfree array and log the header, tail, and entry.
> @@ -1154,7 +1154,7 @@ xfs_dir2_sf_to_block(
>  	dep->namelen = 1;
>  	dep->name[0] = '.';
>  	dp->d_ops->data_put_ftype(dep, XFS_DIR3_FT_DIR);
> -	tagp = dp->d_ops->data_entry_tag_p(dep);
> +	tagp = xfs_dir2_data_entry_tag_p(mp, dep);
>  	*tagp = cpu_to_be16((char *)dep - (char *)hdr);
>  	xfs_dir2_data_log_entry(args, bp, dep);
>  	blp[0].hashval = cpu_to_be32(xfs_dir_hash_dot);
> @@ -1168,7 +1168,7 @@ xfs_dir2_sf_to_block(
>  	dep->namelen = 2;
>  	dep->name[0] = dep->name[1] = '.';
>  	dp->d_ops->data_put_ftype(dep, XFS_DIR3_FT_DIR);
> -	tagp = dp->d_ops->data_entry_tag_p(dep);
> +	tagp = xfs_dir2_data_entry_tag_p(mp, dep);
>  	*tagp = cpu_to_be16((char *)dep - (char *)hdr);
>  	xfs_dir2_data_log_entry(args, bp, dep);
>  	blp[1].hashval = cpu_to_be32(xfs_dir_hash_dotdot);
> @@ -1219,7 +1219,7 @@ xfs_dir2_sf_to_block(
>  		dep->namelen = sfep->namelen;
>  		dp->d_ops->data_put_ftype(dep, xfs_dir2_sf_get_ftype(mp, sfep));
>  		memcpy(dep->name, sfep->name, dep->namelen);
> -		tagp = dp->d_ops->data_entry_tag_p(dep);
> +		tagp = xfs_dir2_data_entry_tag_p(mp, dep);
>  		*tagp = cpu_to_be16((char *)dep - (char *)hdr);
>  		xfs_dir2_data_log_entry(args, bp, dep);
>  		name.name = sfep->name;
> diff --git a/fs/xfs/libxfs/xfs_dir2_data.c b/fs/xfs/libxfs/xfs_dir2_data.c
> index 7e3d35f0cdb5..750e95997d8c 100644
> --- a/fs/xfs/libxfs/xfs_dir2_data.c
> +++ b/fs/xfs/libxfs/xfs_dir2_data.c
> @@ -17,12 +17,25 @@
>  #include "xfs_trans.h"
>  #include "xfs_buf_item.h"
>  #include "xfs_log.h"
> +#include "xfs_dir2_priv.h"
>  
>  static xfs_failaddr_t xfs_dir2_data_freefind_verify(
>  		struct xfs_dir2_data_hdr *hdr, struct xfs_dir2_data_free *bf,
>  		struct xfs_dir2_data_unused *dup,
>  		struct xfs_dir2_data_free **bf_ent);
>  
> +/*
> + * Pointer to an entry's tag word.
> + */
> +__be16 *
> +xfs_dir2_data_entry_tag_p(
> +	struct xfs_mount		*mp,
> +	struct xfs_dir2_data_entry	*dep)
> +{
> +	return (__be16 *)((char *)dep +
> +		xfs_dir2_data_entsize(mp, dep->namelen) - sizeof(__be16));
> +}
> +
>  /*
>   * Check the consistency of the data block.
>   * The input can also be a block-format directory.
> @@ -175,7 +188,7 @@ __xfs_dir3_data_check(
>  			return __this_address;
>  		if (endp < p + xfs_dir2_data_entsize(mp, dep->namelen))
>  			return __this_address;
> -		if (be16_to_cpu(*ops->data_entry_tag_p(dep)) !=
> +		if (be16_to_cpu(*xfs_dir2_data_entry_tag_p(mp, dep)) !=
>  		    (char *)dep - (char *)hdr)
>  			return __this_address;
>  		if (ops->data_get_ftype(dep) >= XFS_DIR3_FT_MAX)
> @@ -609,7 +622,8 @@ xfs_dir2_data_freescan_int(
>  		else {
>  			dep = (xfs_dir2_data_entry_t *)p;
>  			ASSERT((char *)dep - (char *)hdr ==
> -			       be16_to_cpu(*ops->data_entry_tag_p(dep)));
> +			       be16_to_cpu(*xfs_dir2_data_entry_tag_p(mp,
> +					   dep)));
>  			p += xfs_dir2_data_entsize(mp, dep->namelen);
>  		}
>  	}
> @@ -709,6 +723,7 @@ xfs_dir2_data_log_entry(
>  	struct xfs_buf		*bp,
>  	xfs_dir2_data_entry_t	*dep)		/* data entry pointer */
>  {
> +	struct xfs_mount	*mp = bp->b_mount;
>  	struct xfs_dir2_data_hdr *hdr = bp->b_addr;
>  
>  	ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) ||
> @@ -717,7 +732,7 @@ xfs_dir2_data_log_entry(
>  	       hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC));
>  
>  	xfs_trans_log_buf(args->trans, bp, (uint)((char *)dep - (char *)hdr),
> -		(uint)((char *)(args->dp->d_ops->data_entry_tag_p(dep) + 1) -
> +		(uint)((char *)(xfs_dir2_data_entry_tag_p(mp, dep) + 1) -
>  		       (char *)hdr - 1));
>  }
>  
> diff --git a/fs/xfs/libxfs/xfs_dir2_leaf.c b/fs/xfs/libxfs/xfs_dir2_leaf.c
> index 2f7eda3008a6..3a65b7c8aa83 100644
> --- a/fs/xfs/libxfs/xfs_dir2_leaf.c
> +++ b/fs/xfs/libxfs/xfs_dir2_leaf.c
> @@ -866,7 +866,7 @@ xfs_dir2_leaf_addname(
>  	dep->namelen = args->namelen;
>  	memcpy(dep->name, args->name, dep->namelen);
>  	dp->d_ops->data_put_ftype(dep, args->filetype);
> -	tagp = dp->d_ops->data_entry_tag_p(dep);
> +	tagp = xfs_dir2_data_entry_tag_p(dp->i_mount, dep);
>  	*tagp = cpu_to_be16((char *)dep - (char *)hdr);
>  	/*
>  	 * Need to scan fix up the bestfree table.
> diff --git a/fs/xfs/libxfs/xfs_dir2_node.c b/fs/xfs/libxfs/xfs_dir2_node.c
> index d08a11121dee..7534e35d8aa2 100644
> --- a/fs/xfs/libxfs/xfs_dir2_node.c
> +++ b/fs/xfs/libxfs/xfs_dir2_node.c
> @@ -1966,7 +1966,7 @@ xfs_dir2_node_addname_int(
>  	dep->namelen = args->namelen;
>  	memcpy(dep->name, args->name, dep->namelen);
>  	dp->d_ops->data_put_ftype(dep, args->filetype);
> -	tagp = dp->d_ops->data_entry_tag_p(dep);
> +	tagp = xfs_dir2_data_entry_tag_p(dp->i_mount, dep);
>  	*tagp = cpu_to_be16((char *)dep - (char *)hdr);
>  	xfs_dir2_data_log_entry(args, dbp, dep);
>  
> diff --git a/fs/xfs/libxfs/xfs_dir2_priv.h b/fs/xfs/libxfs/xfs_dir2_priv.h
> index 585b7b42c204..750344407f27 100644
> --- a/fs/xfs/libxfs/xfs_dir2_priv.h
> +++ b/fs/xfs/libxfs/xfs_dir2_priv.h
> @@ -48,6 +48,8 @@ extern int xfs_dir2_leaf_to_block(struct xfs_da_args *args,
>  
>  /* xfs_dir2_data.c */
>  int xfs_dir2_data_entsize(struct xfs_mount *mp, int n);
> +__be16 *xfs_dir2_data_entry_tag_p(struct xfs_mount *mp,
> +		struct xfs_dir2_data_entry *dep);
>  
>  #ifdef DEBUG
>  extern void xfs_dir3_data_check(struct xfs_inode *dp, struct xfs_buf *bp);
> diff --git a/fs/xfs/scrub/dir.c b/fs/xfs/scrub/dir.c
> index 5ddd95f12b85..d7ac9423ed86 100644
> --- a/fs/xfs/scrub/dir.c
> +++ b/fs/xfs/scrub/dir.c
> @@ -269,7 +269,7 @@ xchk_dir_rec(
>  	/* Retrieve the entry, sanity check it, and compare hashes. */
>  	ino = be64_to_cpu(dent->inumber);
>  	hash = be32_to_cpu(ent->hashval);
> -	tag = be16_to_cpup(dp->d_ops->data_entry_tag_p(dent));
> +	tag = be16_to_cpup(xfs_dir2_data_entry_tag_p(mp, dent));
>  	if (!xfs_verify_dir_ino(mp, ino) || tag != off)
>  		xchk_fblock_set_corrupt(ds->sc, XFS_DATA_FORK, rec_bno);
>  	if (dent->namelen == 0) {
> -- 
> 2.20.1
> 

^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH 28/34] xfs: move the dir2 data block fixed offsets to struct xfs_da_geometry
  2019-11-01 22:07 ` [PATCH 28/34] xfs: move the dir2 data block fixed offsets to struct xfs_da_geometry Christoph Hellwig
@ 2019-11-04 20:46   ` Darrick J. Wong
  0 siblings, 0 replies; 81+ messages in thread
From: Darrick J. Wong @ 2019-11-04 20:46 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-xfs

On Fri, Nov 01, 2019 at 03:07:13PM -0700, Christoph Hellwig wrote:
> Move the data block fixed offsets towards our structure for dir/attr
> geometry parameters.
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>

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

--D

> ---
>  fs/xfs/libxfs/xfs_da_btree.h   |  5 +++++
>  fs/xfs/libxfs/xfs_da_format.c  | 24 ------------------------
>  fs/xfs/libxfs/xfs_dir2.c       |  9 +++++++++
>  fs/xfs/libxfs/xfs_dir2.h       |  5 -----
>  fs/xfs/libxfs/xfs_dir2_block.c | 11 ++++++-----
>  fs/xfs/libxfs/xfs_dir2_data.c  | 18 +++++++++---------
>  fs/xfs/libxfs/xfs_dir2_leaf.c  | 22 ++++++++++++----------
>  fs/xfs/libxfs/xfs_dir2_node.c  | 24 +++++++++++-------------
>  fs/xfs/libxfs/xfs_dir2_sf.c    | 16 +++++-----------
>  fs/xfs/scrub/dir.c             |  4 ++--
>  fs/xfs/xfs_dir2_readdir.c      | 13 +++++--------
>  11 files changed, 64 insertions(+), 87 deletions(-)
> 
> diff --git a/fs/xfs/libxfs/xfs_da_btree.h b/fs/xfs/libxfs/xfs_da_btree.h
> index e3f4329ab882..a3333e7a084d 100644
> --- a/fs/xfs/libxfs/xfs_da_btree.h
> +++ b/fs/xfs/libxfs/xfs_da_btree.h
> @@ -32,6 +32,11 @@ struct xfs_da_geometry {
>  	int		free_hdr_size;	/* dir2 free header size */
>  	unsigned int	free_max_bests;	/* # of bests entries in dir2 free */
>  	xfs_dablk_t	freeblk;	/* blockno of free data v2 */
> +
> +	xfs_dir2_data_aoff_t data_dot_offset;
> +	xfs_dir2_data_aoff_t data_dotdot_offset;
> +	xfs_dir2_data_aoff_t data_first_offset;
> +	size_t		data_entry_offset;
>  };
>  
>  /*========================================================================
> diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c
> index 9c247223326f..0e35e613fbf3 100644
> --- a/fs/xfs/libxfs/xfs_da_format.c
> +++ b/fs/xfs/libxfs/xfs_da_format.c
> @@ -105,42 +105,18 @@ static const struct xfs_dir_ops xfs_dir2_ops = {
>  	.data_get_ftype = xfs_dir2_data_get_ftype,
>  	.data_put_ftype = xfs_dir2_data_put_ftype,
>  	.data_bestfree_p = xfs_dir2_data_bestfree_p,
> -
> -	.data_dot_offset = sizeof(struct xfs_dir2_data_hdr),
> -	.data_dotdot_offset = sizeof(struct xfs_dir2_data_hdr) +
> -				XFS_DIR2_DATA_ENTSIZE(1),
> -	.data_first_offset =  sizeof(struct xfs_dir2_data_hdr) +
> -				XFS_DIR2_DATA_ENTSIZE(1) +
> -				XFS_DIR2_DATA_ENTSIZE(2),
> -	.data_entry_offset = sizeof(struct xfs_dir2_data_hdr),
>  };
>  
>  static const struct xfs_dir_ops xfs_dir2_ftype_ops = {
>  	.data_get_ftype = xfs_dir3_data_get_ftype,
>  	.data_put_ftype = xfs_dir3_data_put_ftype,
>  	.data_bestfree_p = xfs_dir2_data_bestfree_p,
> -
> -	.data_dot_offset = sizeof(struct xfs_dir2_data_hdr),
> -	.data_dotdot_offset = sizeof(struct xfs_dir2_data_hdr) +
> -				XFS_DIR3_DATA_ENTSIZE(1),
> -	.data_first_offset =  sizeof(struct xfs_dir2_data_hdr) +
> -				XFS_DIR3_DATA_ENTSIZE(1) +
> -				XFS_DIR3_DATA_ENTSIZE(2),
> -	.data_entry_offset = sizeof(struct xfs_dir2_data_hdr),
>  };
>  
>  static const struct xfs_dir_ops xfs_dir3_ops = {
>  	.data_get_ftype = xfs_dir3_data_get_ftype,
>  	.data_put_ftype = xfs_dir3_data_put_ftype,
>  	.data_bestfree_p = xfs_dir3_data_bestfree_p,
> -
> -	.data_dot_offset = sizeof(struct xfs_dir3_data_hdr),
> -	.data_dotdot_offset = sizeof(struct xfs_dir3_data_hdr) +
> -				XFS_DIR3_DATA_ENTSIZE(1),
> -	.data_first_offset =  sizeof(struct xfs_dir3_data_hdr) +
> -				XFS_DIR3_DATA_ENTSIZE(1) +
> -				XFS_DIR3_DATA_ENTSIZE(2),
> -	.data_entry_offset = sizeof(struct xfs_dir3_data_hdr),
>  };
>  
>  /*
> diff --git a/fs/xfs/libxfs/xfs_dir2.c b/fs/xfs/libxfs/xfs_dir2.c
> index 6c46893af17e..33a6e8aacdba 100644
> --- a/fs/xfs/libxfs/xfs_dir2.c
> +++ b/fs/xfs/libxfs/xfs_dir2.c
> @@ -126,16 +126,25 @@ xfs_da_mount(
>  		dageo->node_hdr_size = sizeof(struct xfs_da3_node_hdr);
>  		dageo->leaf_hdr_size = sizeof(struct xfs_dir3_leaf_hdr);
>  		dageo->free_hdr_size = sizeof(struct xfs_dir3_free_hdr);
> +		dageo->data_entry_offset = dageo->data_dot_offset =
> +				sizeof(struct xfs_dir3_data_hdr);
>  	} else {
>  		dageo->node_hdr_size = sizeof(struct xfs_da_node_hdr);
>  		dageo->leaf_hdr_size = sizeof(struct xfs_dir2_leaf_hdr);
>  		dageo->free_hdr_size = sizeof(struct xfs_dir2_free_hdr);
> +		dageo->data_entry_offset = dageo->data_dot_offset =
> +				sizeof(struct xfs_dir2_data_hdr);
>  	}
>  	dageo->leaf_max_ents = (dageo->blksize - dageo->leaf_hdr_size) /
>  			sizeof(struct xfs_dir2_leaf_entry);
>  	dageo->free_max_bests = (dageo->blksize - dageo->free_hdr_size) /
>  			sizeof(xfs_dir2_data_off_t);
>  
> +	dageo->data_dotdot_offset = dageo->data_dot_offset +
> +			xfs_dir2_data_entsize(mp, 1);
> +	dageo->data_first_offset = dageo->data_dotdot_offset +
> +			xfs_dir2_data_entsize(mp, 2);
> +
>  	/*
>  	 * Now we've set up the block conversion variables, we can calculate the
>  	 * segment block constants using the geometry structure.
> diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h
> index 8397e35d6b82..11dba3874da0 100644
> --- a/fs/xfs/libxfs/xfs_dir2.h
> +++ b/fs/xfs/libxfs/xfs_dir2.h
> @@ -37,11 +37,6 @@ struct xfs_dir_ops {
>  				uint8_t ftype);
>  	struct xfs_dir2_data_free *
>  		(*data_bestfree_p)(struct xfs_dir2_data_hdr *hdr);
> -
> -	xfs_dir2_data_aoff_t data_dot_offset;
> -	xfs_dir2_data_aoff_t data_dotdot_offset;
> -	xfs_dir2_data_aoff_t data_first_offset;
> -	size_t	data_entry_offset;
>  };
>  
>  extern const struct xfs_dir_ops *
> diff --git a/fs/xfs/libxfs/xfs_dir2_block.c b/fs/xfs/libxfs/xfs_dir2_block.c
> index 4230ea945bc4..d5f4b7187b72 100644
> --- a/fs/xfs/libxfs/xfs_dir2_block.c
> +++ b/fs/xfs/libxfs/xfs_dir2_block.c
> @@ -937,7 +937,7 @@ xfs_dir2_leaf_to_block(
>  	while (dp->i_d.di_size > args->geo->blksize) {
>  		int hdrsz;
>  
> -		hdrsz = dp->d_ops->data_entry_offset;
> +		hdrsz = args->geo->data_entry_offset;
>  		bestsp = xfs_dir2_leaf_bests_p(ltp);
>  		if (be16_to_cpu(bestsp[be32_to_cpu(ltp->bestcount) - 1]) ==
>  					    args->geo->blksize - hdrsz) {
> @@ -1041,6 +1041,7 @@ int						/* error */
>  xfs_dir2_sf_to_block(
>  	xfs_da_args_t		*args)		/* operation arguments */
>  {
> +	struct xfs_da_geometry	*geo = args->geo;
>  	xfs_dir2_db_t		blkno;		/* dir-relative block # (0) */
>  	xfs_dir2_data_hdr_t	*hdr;		/* block header */
>  	xfs_dir2_leaf_entry_t	*blp;		/* block leaf entries */
> @@ -1123,7 +1124,7 @@ xfs_dir2_sf_to_block(
>  	 * The whole thing is initialized to free by the init routine.
>  	 * Say we're using the leaf and tail area.
>  	 */
> -	dup = (void *)hdr + dp->d_ops->data_entry_offset;
> +	dup = (void *)hdr + args->geo->data_entry_offset;
>  	needlog = needscan = 0;
>  	error = xfs_dir2_data_use_free(args, bp, dup, args->geo->blksize - i,
>  			i, &needlog, &needscan);
> @@ -1149,7 +1150,7 @@ xfs_dir2_sf_to_block(
>  	/*
>  	 * Create entry for .
>  	 */
> -	dep = (void *)hdr + dp->d_ops->data_dot_offset;
> +	dep = (void *)hdr + geo->data_dot_offset;
>  	dep->inumber = cpu_to_be64(dp->i_ino);
>  	dep->namelen = 1;
>  	dep->name[0] = '.';
> @@ -1163,7 +1164,7 @@ xfs_dir2_sf_to_block(
>  	/*
>  	 * Create entry for ..
>  	 */
> -	dep = (void *)hdr + dp->d_ops->data_dotdot_offset;
> +	dep = (void *)hdr + geo->data_dotdot_offset;
>  	dep->inumber = cpu_to_be64(xfs_dir2_sf_get_parent_ino(sfp));
>  	dep->namelen = 2;
>  	dep->name[0] = dep->name[1] = '.';
> @@ -1174,7 +1175,7 @@ xfs_dir2_sf_to_block(
>  	blp[1].hashval = cpu_to_be32(xfs_dir_hash_dotdot);
>  	blp[1].address = cpu_to_be32(xfs_dir2_byte_to_dataptr(
>  				(char *)dep - (char *)hdr));
> -	offset = dp->d_ops->data_first_offset;
> +	offset = geo->data_first_offset;
>  	/*
>  	 * Loop over existing entries, stuff them in.
>  	 */
> diff --git a/fs/xfs/libxfs/xfs_dir2_data.c b/fs/xfs/libxfs/xfs_dir2_data.c
> index 750e95997d8c..81ba13854f8d 100644
> --- a/fs/xfs/libxfs/xfs_dir2_data.c
> +++ b/fs/xfs/libxfs/xfs_dir2_data.c
> @@ -84,7 +84,7 @@ __xfs_dir3_data_check(
>  		return __this_address;
>  
>  	hdr = bp->b_addr;
> -	p = (char *)hdr + ops->data_entry_offset;
> +	p = (char *)hdr + geo->data_entry_offset;
>  
>  	switch (hdr->magic) {
>  	case cpu_to_be32(XFS_DIR3_BLOCK_MAGIC):
> @@ -580,6 +580,7 @@ xfs_dir2_data_freescan_int(
>  	struct xfs_dir2_data_hdr *hdr,
>  	int			*loghead)
>  {
> +	struct xfs_da_geometry	*geo = mp->m_dir_geo;
>  	xfs_dir2_data_entry_t	*dep;		/* active data entry */
>  	xfs_dir2_data_unused_t	*dup;		/* unused data entry */
>  	struct xfs_dir2_data_free *bf;
> @@ -600,8 +601,8 @@ xfs_dir2_data_freescan_int(
>  	/*
>  	 * Set up pointers.
>  	 */
> -	p = (char *)hdr + ops->data_entry_offset;
> -	endp = xfs_dir3_data_endp(mp->m_dir_geo, hdr);
> +	p = (char *)hdr + geo->data_entry_offset;
> +	endp = xfs_dir3_data_endp(geo, hdr);
>  	/*
>  	 * Loop over the block's entries.
>  	 */
> @@ -689,7 +690,7 @@ xfs_dir3_data_init(
>  		hdr->magic = cpu_to_be32(XFS_DIR2_DATA_MAGIC);
>  
>  	bf = dp->d_ops->data_bestfree_p(hdr);
> -	bf[0].offset = cpu_to_be16(dp->d_ops->data_entry_offset);
> +	bf[0].offset = cpu_to_be16(args->geo->data_entry_offset);
>  	for (i = 1; i < XFS_DIR2_DATA_FD_COUNT; i++) {
>  		bf[i].length = 0;
>  		bf[i].offset = 0;
> @@ -698,10 +699,10 @@ xfs_dir3_data_init(
>  	/*
>  	 * Set up an unused entry for the block's body.
>  	 */
> -	dup = (void *)hdr + dp->d_ops->data_entry_offset;
> +	dup = (void *)hdr + args->geo->data_entry_offset;
>  	dup->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG);
>  
> -	t = args->geo->blksize - (uint)dp->d_ops->data_entry_offset;
> +	t = args->geo->blksize - args->geo->data_entry_offset;
>  	bf[0].length = cpu_to_be16(t);
>  	dup->length = cpu_to_be16(t);
>  	*xfs_dir2_data_unused_tag_p(dup) = cpu_to_be16((char *)dup - (char *)hdr);
> @@ -753,8 +754,7 @@ xfs_dir2_data_log_header(
>  	       hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC));
>  #endif
>  
> -	xfs_trans_log_buf(args->trans, bp, 0,
> -			  args->dp->d_ops->data_entry_offset - 1);
> +	xfs_trans_log_buf(args->trans, bp, 0, args->geo->data_entry_offset - 1);
>  }
>  
>  /*
> @@ -822,7 +822,7 @@ xfs_dir2_data_make_free(
>  	 * If this isn't the start of the block, then back up to
>  	 * the previous entry and see if it's free.
>  	 */
> -	if (offset > args->dp->d_ops->data_entry_offset) {
> +	if (offset > args->geo->data_entry_offset) {
>  		__be16			*tagp;	/* tag just before us */
>  
>  		tagp = (__be16 *)((char *)hdr + offset) - 1;
> diff --git a/fs/xfs/libxfs/xfs_dir2_leaf.c b/fs/xfs/libxfs/xfs_dir2_leaf.c
> index 3a65b7c8aa83..c228ff66b3f0 100644
> --- a/fs/xfs/libxfs/xfs_dir2_leaf.c
> +++ b/fs/xfs/libxfs/xfs_dir2_leaf.c
> @@ -1343,6 +1343,7 @@ int						/* error */
>  xfs_dir2_leaf_removename(
>  	xfs_da_args_t		*args)		/* operation arguments */
>  {
> +	struct xfs_da_geometry	*geo = args->geo;
>  	__be16			*bestsp;	/* leaf block best freespace */
>  	xfs_dir2_data_hdr_t	*hdr;		/* data block header */
>  	xfs_dir2_db_t		db;		/* data block number */
> @@ -1381,12 +1382,12 @@ xfs_dir2_leaf_removename(
>  	 * Point to the leaf entry, use that to point to the data entry.
>  	 */
>  	lep = &leafhdr.ents[index];
> -	db = xfs_dir2_dataptr_to_db(args->geo, be32_to_cpu(lep->address));
> +	db = xfs_dir2_dataptr_to_db(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)));
> +		xfs_dir2_dataptr_to_off(geo, be32_to_cpu(lep->address)));
>  	needscan = needlog = 0;
>  	oldbest = be16_to_cpu(bf[0].length);
> -	ltp = xfs_dir2_leaf_tail_p(args->geo, leaf);
> +	ltp = xfs_dir2_leaf_tail_p(geo, leaf);
>  	bestsp = xfs_dir2_leaf_bests_p(ltp);
>  	if (be16_to_cpu(bestsp[db]) != oldbest)
>  		return -EFSCORRUPTED;
> @@ -1428,8 +1429,8 @@ xfs_dir2_leaf_removename(
>  	 * If the data block is now empty then get rid of the data block.
>  	 */
>  	if (be16_to_cpu(bf[0].length) ==
> -			args->geo->blksize - dp->d_ops->data_entry_offset) {
> -		ASSERT(db != args->geo->datablk);
> +	    geo->blksize - geo->data_entry_offset) {
> +		ASSERT(db != geo->datablk);
>  		if ((error = xfs_dir2_shrink_inode(args, db, dbp))) {
>  			/*
>  			 * Nope, can't get rid of it because it caused
> @@ -1471,7 +1472,7 @@ xfs_dir2_leaf_removename(
>  	/*
>  	 * If the data block was not the first one, drop it.
>  	 */
> -	else if (db != args->geo->datablk)
> +	else if (db != geo->datablk)
>  		dbp = NULL;
>  
>  	xfs_dir3_leaf_check(dp, lbp);
> @@ -1592,6 +1593,7 @@ xfs_dir2_leaf_trim_data(
>  	struct xfs_buf		*lbp,		/* leaf buffer */
>  	xfs_dir2_db_t		db)		/* data block number */
>  {
> +	struct xfs_da_geometry	*geo = args->geo;
>  	__be16			*bestsp;	/* leaf bests table */
>  	struct xfs_buf		*dbp;		/* data block buffer */
>  	xfs_inode_t		*dp;		/* incore directory inode */
> @@ -1605,13 +1607,13 @@ xfs_dir2_leaf_trim_data(
>  	/*
>  	 * Read the offending data block.  We need its buffer.
>  	 */
> -	error = xfs_dir3_data_read(tp, dp, xfs_dir2_db_to_da(args->geo, db),
> -				   -1, &dbp);
> +	error = xfs_dir3_data_read(tp, dp, xfs_dir2_db_to_da(geo, db), -1,
> +				   &dbp);
>  	if (error)
>  		return error;
>  
>  	leaf = lbp->b_addr;
> -	ltp = xfs_dir2_leaf_tail_p(args->geo, leaf);
> +	ltp = xfs_dir2_leaf_tail_p(geo, leaf);
>  
>  #ifdef DEBUG
>  {
> @@ -1621,7 +1623,7 @@ xfs_dir2_leaf_trim_data(
>  	ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) ||
>  	       hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC));
>  	ASSERT(be16_to_cpu(bf[0].length) ==
> -	       args->geo->blksize - dp->d_ops->data_entry_offset);
> +	       geo->blksize - geo->data_entry_offset);
>  	ASSERT(db == be32_to_cpu(ltp->bestcount) - 1);
>  }
>  #endif
> diff --git a/fs/xfs/libxfs/xfs_dir2_node.c b/fs/xfs/libxfs/xfs_dir2_node.c
> index 7534e35d8aa2..58362169aa57 100644
> --- a/fs/xfs/libxfs/xfs_dir2_node.c
> +++ b/fs/xfs/libxfs/xfs_dir2_node.c
> @@ -1257,6 +1257,7 @@ xfs_dir2_leafn_remove(
>  	xfs_da_state_blk_t	*dblk,		/* data block */
>  	int			*rval)		/* resulting block needs join */
>  {
> +	struct xfs_da_geometry	*geo = args->geo;
>  	xfs_dir2_data_hdr_t	*hdr;		/* data block header */
>  	xfs_dir2_db_t		db;		/* data block number */
>  	struct xfs_buf		*dbp;		/* data block buffer */
> @@ -1287,9 +1288,9 @@ xfs_dir2_leafn_remove(
>  	/*
>  	 * Extract the data block and offset from the entry.
>  	 */
> -	db = xfs_dir2_dataptr_to_db(args->geo, be32_to_cpu(lep->address));
> +	db = xfs_dir2_dataptr_to_db(geo, be32_to_cpu(lep->address));
>  	ASSERT(dblk->blkno == db);
> -	off = xfs_dir2_dataptr_to_off(args->geo, be32_to_cpu(lep->address));
> +	off = xfs_dir2_dataptr_to_off(geo, be32_to_cpu(lep->address));
>  	ASSERT(dblk->index == off);
>  
>  	/*
> @@ -1340,9 +1341,8 @@ xfs_dir2_leafn_remove(
>  		 * Convert the data block number to a free block,
>  		 * read in the free block.
>  		 */
> -		fdb = xfs_dir2_db_to_fdb(args->geo, db);
> -		error = xfs_dir2_free_read(tp, dp,
> -					   xfs_dir2_db_to_da(args->geo, fdb),
> +		fdb = xfs_dir2_db_to_fdb(geo, db);
> +		error = xfs_dir2_free_read(tp, dp, xfs_dir2_db_to_da(geo, fdb),
>  					   &fbp);
>  		if (error)
>  			return error;
> @@ -1352,22 +1352,20 @@ xfs_dir2_leafn_remove(
>  		struct xfs_dir3_icfree_hdr freehdr;
>  
>  		xfs_dir2_free_hdr_from_disk(dp->i_mount, &freehdr, free);
> -		ASSERT(freehdr.firstdb == args->geo->free_max_bests *
> -			(fdb - xfs_dir2_byte_to_db(args->geo,
> -						   XFS_DIR2_FREE_OFFSET)));
> +		ASSERT(freehdr.firstdb == geo->free_max_bests *
> +			(fdb - xfs_dir2_byte_to_db(geo, XFS_DIR2_FREE_OFFSET)));
>  	}
>  #endif
>  		/*
>  		 * Calculate which entry we need to fix.
>  		 */
> -		findex = xfs_dir2_db_to_fdindex(args->geo, db);
> +		findex = xfs_dir2_db_to_fdindex(geo, db);
>  		longest = be16_to_cpu(bf[0].length);
>  		/*
>  		 * If the data block is now empty we can get rid of it
>  		 * (usually).
>  		 */
> -		if (longest == args->geo->blksize -
> -			       dp->d_ops->data_entry_offset) {
> +		if (longest == geo->blksize - geo->data_entry_offset) {
>  			/*
>  			 * Try to punch out the data block.
>  			 */
> @@ -1399,9 +1397,9 @@ xfs_dir2_leafn_remove(
>  	 * Return indication of whether this leaf block is empty enough
>  	 * to justify trying to join it with a neighbor.
>  	 */
> -	*rval = (args->geo->leaf_hdr_size +
> +	*rval = (geo->leaf_hdr_size +
>  		 (uint)sizeof(leafhdr.ents) * (leafhdr.count - leafhdr.stale)) <
> -		args->geo->magicpct;
> +		geo->magicpct;
>  	return 0;
>  }
>  
> diff --git a/fs/xfs/libxfs/xfs_dir2_sf.c b/fs/xfs/libxfs/xfs_dir2_sf.c
> index 4885a0e920c5..8ecbb0828e42 100644
> --- a/fs/xfs/libxfs/xfs_dir2_sf.c
> +++ b/fs/xfs/libxfs/xfs_dir2_sf.c
> @@ -296,7 +296,7 @@ xfs_dir2_block_to_sf(
>  	/*
>  	 * Set up to loop over the block's entries.
>  	 */
> -	ptr = (char *)hdr + dp->d_ops->data_entry_offset;
> +	ptr = (char *)hdr + args->geo->data_entry_offset;
>  	endptr = xfs_dir3_data_endp(args->geo, hdr);
>  	sfep = xfs_dir2_sf_firstentry(sfp);
>  	/*
> @@ -562,7 +562,7 @@ xfs_dir2_sf_addname_hard(
>  	 * to insert the new entry.
>  	 * If it's going to end up at the end then oldsfep will point there.
>  	 */
> -	for (offset = dp->d_ops->data_first_offset,
> +	for (offset = args->geo->data_first_offset,
>  	      oldsfep = xfs_dir2_sf_firstentry(oldsfp),
>  	      add_datasize = xfs_dir2_data_entsize(mp, args->namelen),
>  	      eof = (char *)oldsfep == &buf[old_isize];
> @@ -640,7 +640,7 @@ xfs_dir2_sf_addname_pick(
>  
>  	sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data;
>  	size = xfs_dir2_data_entsize(mp, args->namelen);
> -	offset = dp->d_ops->data_first_offset;
> +	offset = args->geo->data_first_offset;
>  	sfep = xfs_dir2_sf_firstentry(sfp);
>  	holefit = 0;
>  	/*
> @@ -705,7 +705,7 @@ xfs_dir2_sf_check(
>  	xfs_dir2_sf_hdr_t	*sfp;		/* shortform structure */
>  
>  	sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data;
> -	offset = dp->d_ops->data_first_offset;
> +	offset = args->geo->data_first_offset;
>  	ino = xfs_dir2_sf_get_parent_ino(sfp);
>  	i8count = ino > XFS_DIR2_MAX_SHORT_INUM;
>  
> @@ -738,7 +738,6 @@ xfs_dir2_sf_verify(
>  	struct xfs_dir2_sf_entry	*sfep;
>  	struct xfs_dir2_sf_entry	*next_sfep;
>  	char				*endp;
> -	const struct xfs_dir_ops	*dops;
>  	struct xfs_ifork		*ifp;
>  	xfs_ino_t			ino;
>  	int				i;
> @@ -749,11 +748,6 @@ xfs_dir2_sf_verify(
>  	uint8_t				filetype;
>  
>  	ASSERT(ip->i_d.di_format == XFS_DINODE_FMT_LOCAL);
> -	/*
> -	 * xfs_iread calls us before xfs_setup_inode sets up ip->d_ops,
> -	 * so we can only trust the mountpoint to have the right pointer.
> -	 */
> -	dops = xfs_dir_get_ops(mp, NULL);
>  
>  	ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK);
>  	sfp = (struct xfs_dir2_sf_hdr *)ifp->if_u1.if_data;
> @@ -774,7 +768,7 @@ xfs_dir2_sf_verify(
>  	error = xfs_dir_ino_validate(mp, ino);
>  	if (error)
>  		return __this_address;
> -	offset = dops->data_first_offset;
> +	offset = mp->m_dir_geo->data_first_offset;
>  
>  	/* Check all reported entries */
>  	sfep = xfs_dir2_sf_firstentry(sfp);
> diff --git a/fs/xfs/scrub/dir.c b/fs/xfs/scrub/dir.c
> index d7ac9423ed86..d13c863d72a5 100644
> --- a/fs/xfs/scrub/dir.c
> +++ b/fs/xfs/scrub/dir.c
> @@ -241,7 +241,7 @@ xchk_dir_rec(
>  	dent = (struct xfs_dir2_data_entry *)(((char *)bp->b_addr) + off);
>  
>  	/* Make sure we got a real directory entry. */
> -	p = bp->b_addr + mp->m_dir_inode_ops->data_entry_offset;
> +	p = bp->b_addr + mp->m_dir_geo->data_entry_offset;
>  	endp = xfs_dir3_data_endp(mp->m_dir_geo, bp->b_addr);
>  	if (!endp) {
>  		xchk_fblock_set_corrupt(ds->sc, XFS_DATA_FORK, rec_bno);
> @@ -391,7 +391,7 @@ xchk_directory_data_bestfree(
>  	}
>  
>  	/* Make sure the bestfrees are actually the best free spaces. */
> -	ptr = bp->b_addr + d_ops->data_entry_offset;
> +	ptr = bp->b_addr + mp->m_dir_geo->data_entry_offset;
>  	endptr = xfs_dir3_data_endp(mp->m_dir_geo, bp->b_addr);
>  
>  	/* Iterate the entries, stopping when we hit or go past the end. */
> diff --git a/fs/xfs/xfs_dir2_readdir.c b/fs/xfs/xfs_dir2_readdir.c
> index 4cc4102c85f0..7519317d7a21 100644
> --- a/fs/xfs/xfs_dir2_readdir.c
> +++ b/fs/xfs/xfs_dir2_readdir.c
> @@ -71,14 +71,11 @@ xfs_dir2_sf_getdents(
>  
>  	/*
>  	 * Precalculate offsets for . and .. as we will always need them.
> -	 *
> -	 * XXX(hch): the second argument is sometimes 0 and sometimes
> -	 * geo->datablk
>  	 */
>  	dot_offset = xfs_dir2_db_off_to_dataptr(geo, geo->datablk,
> -						dp->d_ops->data_dot_offset);
> +						geo->data_dot_offset);
>  	dotdot_offset = xfs_dir2_db_off_to_dataptr(geo, geo->datablk,
> -						dp->d_ops->data_dotdot_offset);
> +						geo->data_dotdot_offset);
>  
>  	/*
>  	 * Put . entry unless we're starting past it.
> @@ -176,7 +173,7 @@ xfs_dir2_block_getdents(
>  	/*
>  	 * Set up values for the loop.
>  	 */
> -	ptr = (char *)hdr + dp->d_ops->data_entry_offset;
> +	ptr = (char *)hdr + geo->data_entry_offset;
>  	endptr = xfs_dir3_data_endp(geo, hdr);
>  
>  	/*
> @@ -411,13 +408,13 @@ xfs_dir2_leaf_getdents(
>  			/*
>  			 * Find our position in the block.
>  			 */
> -			ptr = (char *)hdr + dp->d_ops->data_entry_offset;
> +			ptr = (char *)hdr + geo->data_entry_offset;
>  			byteoff = xfs_dir2_byte_to_off(geo, curoff);
>  			/*
>  			 * Skip past the header.
>  			 */
>  			if (byteoff == 0)
> -				curoff += dp->d_ops->data_entry_offset;
> +				curoff += geo->data_entry_offset;
>  			/*
>  			 * Skip past entries until we reach our offset.
>  			 */
> -- 
> 2.20.1
> 

^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH 29/34] xfs: cleanup xfs_dir2_data_entsize
  2019-11-01 22:07 ` [PATCH 29/34] xfs: cleanup xfs_dir2_data_entsize Christoph Hellwig
@ 2019-11-04 20:48   ` Darrick J. Wong
  0 siblings, 0 replies; 81+ messages in thread
From: Darrick J. Wong @ 2019-11-04 20:48 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-xfs

On Fri, Nov 01, 2019 at 03:07:14PM -0700, Christoph Hellwig wrote:
> Remove the XFS_DIR2_DATA_ENTSIZE and XFS_DIR3_DATA_ENTSIZE and open
> code them in their only caller.
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>

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

--D

> ---
>  fs/xfs/libxfs/xfs_da_format.c | 33 ---------------------------------
>  fs/xfs/libxfs/xfs_dir2_data.c | 14 ++++++++++++++
>  2 files changed, 14 insertions(+), 33 deletions(-)
> 
> diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c
> index 0e35e613fbf3..dd2389748672 100644
> --- a/fs/xfs/libxfs/xfs_da_format.c
> +++ b/fs/xfs/libxfs/xfs_da_format.c
> @@ -19,39 +19,6 @@
>   * Directory data block operations
>   */
>  
> -/*
> - * For special situations, the dirent size ends up fixed because we always know
> - * what the size of the entry is. That's true for the "." and "..", and
> - * therefore we know that they are a fixed size and hence their offsets are
> - * constant, as is the first entry.
> - *
> - * Hence, this calculation is written as a macro to be able to be calculated at
> - * compile time and so certain offsets can be calculated directly in the
> - * structure initaliser via the macro. There are two macros - one for dirents
> - * with ftype and without so there are no unresolvable conditionals in the
> - * calculations. We also use round_up() as XFS_DIR2_DATA_ALIGN is always a power
> - * of 2 and the compiler doesn't reject it (unlike roundup()).
> - */
> -#define XFS_DIR2_DATA_ENTSIZE(n)					\
> -	round_up((offsetof(struct xfs_dir2_data_entry, name[0]) + (n) +	\
> -		 sizeof(xfs_dir2_data_off_t)), XFS_DIR2_DATA_ALIGN)
> -
> -#define XFS_DIR3_DATA_ENTSIZE(n)					\
> -	round_up((offsetof(struct xfs_dir2_data_entry, name[0]) + (n) +	\
> -		 sizeof(xfs_dir2_data_off_t) + sizeof(uint8_t)),	\
> -		XFS_DIR2_DATA_ALIGN)
> -
> -int
> -xfs_dir2_data_entsize(
> -	struct xfs_mount	*mp,
> -	int			n)
> -{
> -	if (xfs_sb_version_hasftype(&mp->m_sb))
> -		return XFS_DIR3_DATA_ENTSIZE(n);
> -	else
> -		return XFS_DIR2_DATA_ENTSIZE(n);
> -}
> -
>  static uint8_t
>  xfs_dir2_data_get_ftype(
>  	struct xfs_dir2_data_entry *dep)
> diff --git a/fs/xfs/libxfs/xfs_dir2_data.c b/fs/xfs/libxfs/xfs_dir2_data.c
> index 81ba13854f8d..c44c455b961f 100644
> --- a/fs/xfs/libxfs/xfs_dir2_data.c
> +++ b/fs/xfs/libxfs/xfs_dir2_data.c
> @@ -24,6 +24,20 @@ static xfs_failaddr_t xfs_dir2_data_freefind_verify(
>  		struct xfs_dir2_data_unused *dup,
>  		struct xfs_dir2_data_free **bf_ent);
>  
> +int
> +xfs_dir2_data_entsize(
> +	struct xfs_mount	*mp,
> +	int			namelen)
> +{
> +	size_t			len;
> +
> +	len = offsetof(struct xfs_dir2_data_entry, name[0]) + namelen +
> +			sizeof(xfs_dir2_data_off_t) /* tag */;
> +	if (xfs_sb_version_hasftype(&mp->m_sb))
> +		len += sizeof(uint8_t);
> +	return round_up(len, XFS_DIR2_DATA_ALIGN);
> +}
> +
>  /*
>   * Pointer to an entry's tag word.
>   */
> -- 
> 2.20.1
> 

^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH 30/34] xfs: devirtualize ->data_bestfree_p
  2019-11-01 22:07 ` [PATCH 30/34] xfs: devirtualize ->data_bestfree_p Christoph Hellwig
@ 2019-11-04 20:49   ` Darrick J. Wong
  0 siblings, 0 replies; 81+ messages in thread
From: Darrick J. Wong @ 2019-11-04 20:49 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-xfs

On Fri, Nov 01, 2019 at 03:07:15PM -0700, Christoph Hellwig wrote:
> Replace the ->data_bestfree_p dir ops method with a directly called
> xfs_dir2_data_bestfree_p helper that takes care of the differences
> between the v4 and v5 on-disk format.
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>

Woot!
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>

--D

> ---
>  fs/xfs/libxfs/xfs_da_format.c  | 15 ---------------
>  fs/xfs/libxfs/xfs_dir2.h       |  3 ---
>  fs/xfs/libxfs/xfs_dir2_block.c |  6 +++---
>  fs/xfs/libxfs/xfs_dir2_data.c  | 23 ++++++++++++++++-------
>  fs/xfs/libxfs/xfs_dir2_leaf.c  | 11 ++++++-----
>  fs/xfs/libxfs/xfs_dir2_node.c  |  6 +++---
>  fs/xfs/libxfs/xfs_dir2_priv.h  |  2 ++
>  fs/xfs/scrub/dir.c             |  7 ++-----
>  8 files changed, 32 insertions(+), 41 deletions(-)
> 
> diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c
> index dd2389748672..b9f9fbf7eee2 100644
> --- a/fs/xfs/libxfs/xfs_da_format.c
> +++ b/fs/xfs/libxfs/xfs_da_format.c
> @@ -56,34 +56,19 @@ xfs_dir3_data_put_ftype(
>  	dep->name[dep->namelen] = type;
>  }
>  
> -static struct xfs_dir2_data_free *
> -xfs_dir2_data_bestfree_p(struct xfs_dir2_data_hdr *hdr)
> -{
> -	return hdr->bestfree;
> -}
> -
> -static struct xfs_dir2_data_free *
> -xfs_dir3_data_bestfree_p(struct xfs_dir2_data_hdr *hdr)
> -{
> -	return ((struct xfs_dir3_data_hdr *)hdr)->best_free;
> -}
> -
>  static const struct xfs_dir_ops xfs_dir2_ops = {
>  	.data_get_ftype = xfs_dir2_data_get_ftype,
>  	.data_put_ftype = xfs_dir2_data_put_ftype,
> -	.data_bestfree_p = xfs_dir2_data_bestfree_p,
>  };
>  
>  static const struct xfs_dir_ops xfs_dir2_ftype_ops = {
>  	.data_get_ftype = xfs_dir3_data_get_ftype,
>  	.data_put_ftype = xfs_dir3_data_put_ftype,
> -	.data_bestfree_p = xfs_dir2_data_bestfree_p,
>  };
>  
>  static const struct xfs_dir_ops xfs_dir3_ops = {
>  	.data_get_ftype = xfs_dir3_data_get_ftype,
>  	.data_put_ftype = xfs_dir3_data_put_ftype,
> -	.data_bestfree_p = xfs_dir3_data_bestfree_p,
>  };
>  
>  /*
> diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h
> index 11dba3874da0..76d6d38154fb 100644
> --- a/fs/xfs/libxfs/xfs_dir2.h
> +++ b/fs/xfs/libxfs/xfs_dir2.h
> @@ -35,8 +35,6 @@ struct xfs_dir_ops {
>  	uint8_t (*data_get_ftype)(struct xfs_dir2_data_entry *dep);
>  	void	(*data_put_ftype)(struct xfs_dir2_data_entry *dep,
>  				uint8_t ftype);
> -	struct xfs_dir2_data_free *
> -		(*data_bestfree_p)(struct xfs_dir2_data_hdr *hdr);
>  };
>  
>  extern const struct xfs_dir_ops *
> @@ -81,7 +79,6 @@ extern int xfs_dir2_shrink_inode(struct xfs_da_args *args, xfs_dir2_db_t db,
>  				struct xfs_buf *bp);
>  
>  extern void xfs_dir2_data_freescan_int(struct xfs_mount *mp,
> -		const struct xfs_dir_ops *ops,
>  		struct xfs_dir2_data_hdr *hdr, int *loghead);
>  extern void xfs_dir2_data_freescan(struct xfs_inode *dp,
>  		struct xfs_dir2_data_hdr *hdr, int *loghead);
> diff --git a/fs/xfs/libxfs/xfs_dir2_block.c b/fs/xfs/libxfs/xfs_dir2_block.c
> index d5f4b7187b72..50b4f1bf25a3 100644
> --- a/fs/xfs/libxfs/xfs_dir2_block.c
> +++ b/fs/xfs/libxfs/xfs_dir2_block.c
> @@ -172,7 +172,7 @@ xfs_dir2_block_need_space(
>  	struct xfs_dir2_data_unused	*enddup = NULL;
>  
>  	*compact = 0;
> -	bf = dp->d_ops->data_bestfree_p(hdr);
> +	bf = xfs_dir2_data_bestfree_p(dp->i_mount, hdr);
>  
>  	/*
>  	 * If there are stale entries we'll use one for the leaf.
> @@ -1207,8 +1207,8 @@ xfs_dir2_sf_to_block(
>  				((char *)dup - (char *)hdr));
>  			xfs_dir2_data_log_unused(args, bp, dup);
>  			xfs_dir2_data_freeinsert(hdr,
> -						 dp->d_ops->data_bestfree_p(hdr),
> -						 dup, &dummy);
> +					xfs_dir2_data_bestfree_p(mp, hdr),
> +					dup, &dummy);
>  			offset += be16_to_cpu(dup->length);
>  			continue;
>  		}
> diff --git a/fs/xfs/libxfs/xfs_dir2_data.c b/fs/xfs/libxfs/xfs_dir2_data.c
> index c44c455b961f..353629c3a1e8 100644
> --- a/fs/xfs/libxfs/xfs_dir2_data.c
> +++ b/fs/xfs/libxfs/xfs_dir2_data.c
> @@ -24,6 +24,16 @@ static xfs_failaddr_t xfs_dir2_data_freefind_verify(
>  		struct xfs_dir2_data_unused *dup,
>  		struct xfs_dir2_data_free **bf_ent);
>  
> +struct xfs_dir2_data_free *
> +xfs_dir2_data_bestfree_p(
> +	struct xfs_mount		*mp,
> +	struct xfs_dir2_data_hdr	*hdr)
> +{
> +	if (xfs_sb_version_hascrc(&mp->m_sb))
> +		return ((struct xfs_dir3_data_hdr *)hdr)->best_free;
> +	return hdr->bestfree;
> +}
> +
>  int
>  xfs_dir2_data_entsize(
>  	struct xfs_mount	*mp,
> @@ -130,7 +140,7 @@ __xfs_dir3_data_check(
>  	/*
>  	 * Account for zero bestfree entries.
>  	 */
> -	bf = ops->data_bestfree_p(hdr);
> +	bf = xfs_dir2_data_bestfree_p(mp, hdr);
>  	count = lastfree = freeseen = 0;
>  	if (!bf[0].length) {
>  		if (bf[0].offset)
> @@ -590,7 +600,6 @@ xfs_dir2_data_freeremove(
>  void
>  xfs_dir2_data_freescan_int(
>  	struct xfs_mount	*mp,
> -	const struct xfs_dir_ops *ops,
>  	struct xfs_dir2_data_hdr *hdr,
>  	int			*loghead)
>  {
> @@ -609,7 +618,7 @@ xfs_dir2_data_freescan_int(
>  	/*
>  	 * Start by clearing the table.
>  	 */
> -	bf = ops->data_bestfree_p(hdr);
> +	bf = xfs_dir2_data_bestfree_p(mp, hdr);
>  	memset(bf, 0, sizeof(*bf) * XFS_DIR2_DATA_FD_COUNT);
>  	*loghead = 1;
>  	/*
> @@ -650,7 +659,7 @@ xfs_dir2_data_freescan(
>  	struct xfs_dir2_data_hdr *hdr,
>  	int			*loghead)
>  {
> -	return xfs_dir2_data_freescan_int(dp->i_mount, dp->d_ops, hdr, loghead);
> +	return xfs_dir2_data_freescan_int(dp->i_mount, hdr, loghead);
>  }
>  
>  /*
> @@ -703,7 +712,7 @@ xfs_dir3_data_init(
>  	} else
>  		hdr->magic = cpu_to_be32(XFS_DIR2_DATA_MAGIC);
>  
> -	bf = dp->d_ops->data_bestfree_p(hdr);
> +	bf = xfs_dir2_data_bestfree_p(mp, hdr);
>  	bf[0].offset = cpu_to_be16(args->geo->data_entry_offset);
>  	for (i = 1; i < XFS_DIR2_DATA_FD_COUNT; i++) {
>  		bf[i].length = 0;
> @@ -862,7 +871,7 @@ xfs_dir2_data_make_free(
>  	 * Previous and following entries are both free,
>  	 * merge everything into a single free entry.
>  	 */
> -	bf = args->dp->d_ops->data_bestfree_p(hdr);
> +	bf = xfs_dir2_data_bestfree_p(args->dp->i_mount, hdr);
>  	if (prevdup && postdup) {
>  		xfs_dir2_data_free_t	*dfp2;	/* another bestfree pointer */
>  
> @@ -1053,7 +1062,7 @@ xfs_dir2_data_use_free(
>  	 * Look up the entry in the bestfree table.
>  	 */
>  	oldlen = be16_to_cpu(dup->length);
> -	bf = args->dp->d_ops->data_bestfree_p(hdr);
> +	bf = xfs_dir2_data_bestfree_p(args->dp->i_mount, hdr);
>  	dfp = xfs_dir2_data_freefind(hdr, bf, dup);
>  	ASSERT(dfp || oldlen <= be16_to_cpu(bf[2].length));
>  	/*
> diff --git a/fs/xfs/libxfs/xfs_dir2_leaf.c b/fs/xfs/libxfs/xfs_dir2_leaf.c
> index c228ff66b3f0..30ccf44d817a 100644
> --- a/fs/xfs/libxfs/xfs_dir2_leaf.c
> +++ b/fs/xfs/libxfs/xfs_dir2_leaf.c
> @@ -425,7 +425,7 @@ xfs_dir2_block_to_leaf(
>  	xfs_dir3_data_check(dp, dbp);
>  	btp = xfs_dir2_block_tail_p(args->geo, hdr);
>  	blp = xfs_dir2_block_leaf_p(btp);
> -	bf = dp->d_ops->data_bestfree_p(hdr);
> +	bf = xfs_dir2_data_bestfree_p(dp->i_mount, hdr);
>  
>  	/*
>  	 * Set the counts in the leaf header.
> @@ -823,7 +823,7 @@ xfs_dir2_leaf_addname(
>  		else
>  			xfs_dir3_leaf_log_bests(args, lbp, use_block, use_block);
>  		hdr = dbp->b_addr;
> -		bf = dp->d_ops->data_bestfree_p(hdr);
> +		bf = xfs_dir2_data_bestfree_p(dp->i_mount, hdr);
>  		bestsp[use_block] = bf[0].length;
>  		grown = 1;
>  	} else {
> @@ -839,7 +839,7 @@ xfs_dir2_leaf_addname(
>  			return error;
>  		}
>  		hdr = dbp->b_addr;
> -		bf = dp->d_ops->data_bestfree_p(hdr);
> +		bf = xfs_dir2_data_bestfree_p(dp->i_mount, hdr);
>  		grown = 0;
>  	}
>  	/*
> @@ -1376,7 +1376,7 @@ xfs_dir2_leaf_removename(
>  	leaf = lbp->b_addr;
>  	hdr = dbp->b_addr;
>  	xfs_dir3_data_check(dp, dbp);
> -	bf = dp->d_ops->data_bestfree_p(hdr);
> +	bf = xfs_dir2_data_bestfree_p(dp->i_mount, hdr);
>  
>  	/*
>  	 * Point to the leaf entry, use that to point to the data entry.
> @@ -1618,7 +1618,8 @@ xfs_dir2_leaf_trim_data(
>  #ifdef DEBUG
>  {
>  	struct xfs_dir2_data_hdr *hdr = dbp->b_addr;
> -	struct xfs_dir2_data_free *bf = dp->d_ops->data_bestfree_p(hdr);
> +	struct xfs_dir2_data_free *bf =
> +		xfs_dir2_data_bestfree_p(dp->i_mount, hdr);
>  
>  	ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) ||
>  	       hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC));
> diff --git a/fs/xfs/libxfs/xfs_dir2_node.c b/fs/xfs/libxfs/xfs_dir2_node.c
> index 58362169aa57..d4a1d2455e72 100644
> --- a/fs/xfs/libxfs/xfs_dir2_node.c
> +++ b/fs/xfs/libxfs/xfs_dir2_node.c
> @@ -1311,7 +1311,7 @@ xfs_dir2_leafn_remove(
>  	dbp = dblk->bp;
>  	hdr = dbp->b_addr;
>  	dep = (xfs_dir2_data_entry_t *)((char *)hdr + off);
> -	bf = dp->d_ops->data_bestfree_p(hdr);
> +	bf = xfs_dir2_data_bestfree_p(dp->i_mount, hdr);
>  	longest = be16_to_cpu(bf[0].length);
>  	needlog = needscan = 0;
>  	xfs_dir2_data_make_free(args, dbp, off,
> @@ -1769,7 +1769,7 @@ xfs_dir2_node_add_datablk(
>  	}
>  
>  	/* Update the freespace value for the new block in the table. */
> -	bf = dp->d_ops->data_bestfree_p(dbp->b_addr);
> +	bf = xfs_dir2_data_bestfree_p(mp, dbp->b_addr);
>  	hdr->bests[*findex] = bf[0].length;
>  
>  	*dbpp = dbp;
> @@ -1942,7 +1942,7 @@ xfs_dir2_node_addname_int(
>  
>  	/* setup for data block up now */
>  	hdr = dbp->b_addr;
> -	bf = dp->d_ops->data_bestfree_p(hdr);
> +	bf = xfs_dir2_data_bestfree_p(dp->i_mount, hdr);
>  	ASSERT(be16_to_cpu(bf[0].length) >= length);
>  
>  	/* Point to the existing unused space. */
> diff --git a/fs/xfs/libxfs/xfs_dir2_priv.h b/fs/xfs/libxfs/xfs_dir2_priv.h
> index 750344407f27..436693514c7c 100644
> --- a/fs/xfs/libxfs/xfs_dir2_priv.h
> +++ b/fs/xfs/libxfs/xfs_dir2_priv.h
> @@ -47,6 +47,8 @@ extern int xfs_dir2_leaf_to_block(struct xfs_da_args *args,
>  		struct xfs_buf *lbp, struct xfs_buf *dbp);
>  
>  /* xfs_dir2_data.c */
> +struct xfs_dir2_data_free *xfs_dir2_data_bestfree_p(struct xfs_mount *mp,
> +		struct xfs_dir2_data_hdr *hdr);
>  int xfs_dir2_data_entsize(struct xfs_mount *mp, int n);
>  __be16 *xfs_dir2_data_entry_tag_p(struct xfs_mount *mp,
>  		struct xfs_dir2_data_entry *dep);
> diff --git a/fs/xfs/scrub/dir.c b/fs/xfs/scrub/dir.c
> index d13c863d72a5..54772ad9a431 100644
> --- a/fs/xfs/scrub/dir.c
> +++ b/fs/xfs/scrub/dir.c
> @@ -327,7 +327,6 @@ xchk_directory_data_bestfree(
>  	struct xfs_buf			*bp;
>  	struct xfs_dir2_data_free	*bf;
>  	struct xfs_mount		*mp = sc->mp;
> -	const struct xfs_dir_ops	*d_ops;
>  	char				*ptr;
>  	char				*endptr;
>  	u16				tag;
> @@ -338,8 +337,6 @@ xchk_directory_data_bestfree(
>  	int				offset;
>  	int				error;
>  
> -	d_ops = sc->ip->d_ops;
> -
>  	if (is_block) {
>  		/* dir block format */
>  		if (lblk != XFS_B_TO_FSBT(mp, XFS_DIR2_DATA_OFFSET))
> @@ -359,7 +356,7 @@ xchk_directory_data_bestfree(
>  		goto out_buf;
>  
>  	/* Do the bestfrees correspond to actual free space? */
> -	bf = d_ops->data_bestfree_p(bp->b_addr);
> +	bf = xfs_dir2_data_bestfree_p(mp, bp->b_addr);
>  	smallest_bestfree = UINT_MAX;
>  	for (dfp = &bf[0]; dfp < &bf[XFS_DIR2_DATA_FD_COUNT]; dfp++) {
>  		offset = be16_to_cpu(dfp->offset);
> @@ -466,7 +463,7 @@ xchk_directory_check_freesp(
>  {
>  	struct xfs_dir2_data_free	*dfp;
>  
> -	dfp = sc->ip->d_ops->data_bestfree_p(dbp->b_addr);
> +	dfp = xfs_dir2_data_bestfree_p(sc->mp, dbp->b_addr);
>  
>  	if (len != be16_to_cpu(dfp->length))
>  		xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk);
> -- 
> 2.20.1
> 

^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH 31/34] xfs: devirtualize ->data_get_ftype and ->data_put_ftype
  2019-11-01 22:07 ` [PATCH 31/34] xfs: devirtualize ->data_get_ftype and ->data_put_ftype Christoph Hellwig
@ 2019-11-04 20:50   ` Darrick J. Wong
  0 siblings, 0 replies; 81+ messages in thread
From: Darrick J. Wong @ 2019-11-04 20:50 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-xfs

On Fri, Nov 01, 2019 at 03:07:16PM -0700, Christoph Hellwig wrote:
> Replace the ->data_get_ftype and ->data_put_ftype dir ops methods with
> directly called xfs_dir2_data_get_ftype and xfs_dir2_data_put_ftype
> helpers that takes care of the differences between the directory format
> with and without the file type field.
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>

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

--D

> ---
>  fs/xfs/libxfs/xfs_da_format.c  | 47 ----------------------------------
>  fs/xfs/libxfs/xfs_dir2.h       |  3 ---
>  fs/xfs/libxfs/xfs_dir2_block.c | 13 +++++-----
>  fs/xfs/libxfs/xfs_dir2_data.c  | 47 +++++++++++++++++++++++-----------
>  fs/xfs/libxfs/xfs_dir2_leaf.c  |  6 ++---
>  fs/xfs/libxfs/xfs_dir2_node.c  |  6 ++---
>  fs/xfs/libxfs/xfs_dir2_priv.h  |  4 +++
>  fs/xfs/libxfs/xfs_dir2_sf.c    |  2 +-
>  fs/xfs/xfs_dir2_readdir.c      |  4 +--
>  9 files changed, 52 insertions(+), 80 deletions(-)
> 
> diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c
> index b9f9fbf7eee2..498363ac193d 100644
> --- a/fs/xfs/libxfs/xfs_da_format.c
> +++ b/fs/xfs/libxfs/xfs_da_format.c
> @@ -15,60 +15,13 @@
>  #include "xfs_dir2.h"
>  #include "xfs_dir2_priv.h"
>  
> -/*
> - * Directory data block operations
> - */
> -
> -static uint8_t
> -xfs_dir2_data_get_ftype(
> -	struct xfs_dir2_data_entry *dep)
> -{
> -	return XFS_DIR3_FT_UNKNOWN;
> -}
> -
> -static void
> -xfs_dir2_data_put_ftype(
> -	struct xfs_dir2_data_entry *dep,
> -	uint8_t			ftype)
> -{
> -	ASSERT(ftype < XFS_DIR3_FT_MAX);
> -}
> -
> -static uint8_t
> -xfs_dir3_data_get_ftype(
> -	struct xfs_dir2_data_entry *dep)
> -{
> -	uint8_t		ftype = dep->name[dep->namelen];
> -
> -	if (ftype >= XFS_DIR3_FT_MAX)
> -		return XFS_DIR3_FT_UNKNOWN;
> -	return ftype;
> -}
> -
> -static void
> -xfs_dir3_data_put_ftype(
> -	struct xfs_dir2_data_entry *dep,
> -	uint8_t			type)
> -{
> -	ASSERT(type < XFS_DIR3_FT_MAX);
> -	ASSERT(dep->namelen != 0);
> -
> -	dep->name[dep->namelen] = type;
> -}
> -
>  static const struct xfs_dir_ops xfs_dir2_ops = {
> -	.data_get_ftype = xfs_dir2_data_get_ftype,
> -	.data_put_ftype = xfs_dir2_data_put_ftype,
>  };
>  
>  static const struct xfs_dir_ops xfs_dir2_ftype_ops = {
> -	.data_get_ftype = xfs_dir3_data_get_ftype,
> -	.data_put_ftype = xfs_dir3_data_put_ftype,
>  };
>  
>  static const struct xfs_dir_ops xfs_dir3_ops = {
> -	.data_get_ftype = xfs_dir3_data_get_ftype,
> -	.data_put_ftype = xfs_dir3_data_put_ftype,
>  };
>  
>  /*
> diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h
> index 76d6d38154fb..f869ee01a381 100644
> --- a/fs/xfs/libxfs/xfs_dir2.h
> +++ b/fs/xfs/libxfs/xfs_dir2.h
> @@ -32,9 +32,6 @@ extern unsigned char xfs_mode_to_ftype(int mode);
>   * directory operations vector for encode/decode routines
>   */
>  struct xfs_dir_ops {
> -	uint8_t (*data_get_ftype)(struct xfs_dir2_data_entry *dep);
> -	void	(*data_put_ftype)(struct xfs_dir2_data_entry *dep,
> -				uint8_t ftype);
>  };
>  
>  extern const struct xfs_dir_ops *
> diff --git a/fs/xfs/libxfs/xfs_dir2_block.c b/fs/xfs/libxfs/xfs_dir2_block.c
> index 50b4f1bf25a3..94d32e515478 100644
> --- a/fs/xfs/libxfs/xfs_dir2_block.c
> +++ b/fs/xfs/libxfs/xfs_dir2_block.c
> @@ -541,7 +541,7 @@ xfs_dir2_block_addname(
>  	dep->inumber = cpu_to_be64(args->inumber);
>  	dep->namelen = args->namelen;
>  	memcpy(dep->name, args->name, args->namelen);
> -	dp->d_ops->data_put_ftype(dep, args->filetype);
> +	xfs_dir2_data_put_ftype(dp->i_mount, dep, args->filetype);
>  	tagp = xfs_dir2_data_entry_tag_p(dp->i_mount, dep);
>  	*tagp = cpu_to_be16((char *)dep - (char *)hdr);
>  	/*
> @@ -633,7 +633,7 @@ xfs_dir2_block_lookup(
>  	 * Fill in inode number, CI name if appropriate, release the block.
>  	 */
>  	args->inumber = be64_to_cpu(dep->inumber);
> -	args->filetype = dp->d_ops->data_get_ftype(dep);
> +	args->filetype = xfs_dir2_data_get_ftype(dp->i_mount, dep);
>  	error = xfs_dir_cilookup_result(args, dep->name, dep->namelen);
>  	xfs_trans_brelse(args->trans, bp);
>  	return error;
> @@ -865,7 +865,7 @@ xfs_dir2_block_replace(
>  	 * Change the inode number to the new value.
>  	 */
>  	dep->inumber = cpu_to_be64(args->inumber);
> -	dp->d_ops->data_put_ftype(dep, args->filetype);
> +	xfs_dir2_data_put_ftype(dp->i_mount, dep, args->filetype);
>  	xfs_dir2_data_log_entry(args, bp, dep);
>  	xfs_dir3_data_check(dp, bp);
>  	return 0;
> @@ -1154,7 +1154,7 @@ xfs_dir2_sf_to_block(
>  	dep->inumber = cpu_to_be64(dp->i_ino);
>  	dep->namelen = 1;
>  	dep->name[0] = '.';
> -	dp->d_ops->data_put_ftype(dep, XFS_DIR3_FT_DIR);
> +	xfs_dir2_data_put_ftype(mp, dep, XFS_DIR3_FT_DIR);
>  	tagp = xfs_dir2_data_entry_tag_p(mp, dep);
>  	*tagp = cpu_to_be16((char *)dep - (char *)hdr);
>  	xfs_dir2_data_log_entry(args, bp, dep);
> @@ -1168,7 +1168,7 @@ xfs_dir2_sf_to_block(
>  	dep->inumber = cpu_to_be64(xfs_dir2_sf_get_parent_ino(sfp));
>  	dep->namelen = 2;
>  	dep->name[0] = dep->name[1] = '.';
> -	dp->d_ops->data_put_ftype(dep, XFS_DIR3_FT_DIR);
> +	xfs_dir2_data_put_ftype(mp, dep, XFS_DIR3_FT_DIR);
>  	tagp = xfs_dir2_data_entry_tag_p(mp, dep);
>  	*tagp = cpu_to_be16((char *)dep - (char *)hdr);
>  	xfs_dir2_data_log_entry(args, bp, dep);
> @@ -1218,7 +1218,8 @@ xfs_dir2_sf_to_block(
>  		dep = (xfs_dir2_data_entry_t *)((char *)hdr + newoffset);
>  		dep->inumber = cpu_to_be64(xfs_dir2_sf_get_ino(mp, sfp, sfep));
>  		dep->namelen = sfep->namelen;
> -		dp->d_ops->data_put_ftype(dep, xfs_dir2_sf_get_ftype(mp, sfep));
> +		xfs_dir2_data_put_ftype(mp, dep,
> +				xfs_dir2_sf_get_ftype(mp, sfep));
>  		memcpy(dep->name, sfep->name, dep->namelen);
>  		tagp = xfs_dir2_data_entry_tag_p(mp, dep);
>  		*tagp = cpu_to_be16((char *)dep - (char *)hdr);
> diff --git a/fs/xfs/libxfs/xfs_dir2_data.c b/fs/xfs/libxfs/xfs_dir2_data.c
> index 353629c3a1e8..9752a0da5b95 100644
> --- a/fs/xfs/libxfs/xfs_dir2_data.c
> +++ b/fs/xfs/libxfs/xfs_dir2_data.c
> @@ -60,6 +60,34 @@ xfs_dir2_data_entry_tag_p(
>  		xfs_dir2_data_entsize(mp, dep->namelen) - sizeof(__be16));
>  }
>  
> +uint8_t
> +xfs_dir2_data_get_ftype(
> +	struct xfs_mount		*mp,
> +	struct xfs_dir2_data_entry	*dep)
> +{
> +	if (xfs_sb_version_hasftype(&mp->m_sb)) {
> +		uint8_t			ftype = dep->name[dep->namelen];
> +
> +		if (likely(ftype < XFS_DIR3_FT_MAX))
> +			return ftype;
> +	}
> +
> +	return XFS_DIR3_FT_UNKNOWN;
> +}
> +
> +void
> +xfs_dir2_data_put_ftype(
> +	struct xfs_mount		*mp,
> +	struct xfs_dir2_data_entry	*dep,
> +	uint8_t				ftype)
> +{
> +	ASSERT(ftype < XFS_DIR3_FT_MAX);
> +	ASSERT(dep->namelen != 0);
> +
> +	if (xfs_sb_version_hasftype(&mp->m_sb))
> +		dep->name[dep->namelen] = ftype;
> +}
> +
>  /*
>   * Check the consistency of the data block.
>   * The input can also be a block-format directory.
> @@ -88,23 +116,12 @@ __xfs_dir3_data_check(
>  	char			*p;		/* current data position */
>  	int			stale;		/* count of stale leaves */
>  	struct xfs_name		name;
> -	const struct xfs_dir_ops *ops;
> -	struct xfs_da_geometry	*geo;
> -
> -	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);
> +	struct xfs_da_geometry	*geo = mp->m_dir_geo;
>  
>  	/*
> -	 * If this isn't a directory, or we don't get handed the dir ops,
> -	 * something is seriously wrong.  Bail out.
> +	 * If this isn't a directory, something is seriously wrong.  Bail out.
>  	 */
> -	if ((dp && !S_ISDIR(VFS_I(dp)->i_mode)) ||
> -	    ops != xfs_dir_get_ops(mp, NULL))
> +	if (dp && !S_ISDIR(VFS_I(dp)->i_mode))
>  		return __this_address;
>  
>  	hdr = bp->b_addr;
> @@ -215,7 +232,7 @@ __xfs_dir3_data_check(
>  		if (be16_to_cpu(*xfs_dir2_data_entry_tag_p(mp, dep)) !=
>  		    (char *)dep - (char *)hdr)
>  			return __this_address;
> -		if (ops->data_get_ftype(dep) >= XFS_DIR3_FT_MAX)
> +		if (xfs_dir2_data_get_ftype(mp, dep) >= XFS_DIR3_FT_MAX)
>  			return __this_address;
>  		count++;
>  		lastfree = 0;
> diff --git a/fs/xfs/libxfs/xfs_dir2_leaf.c b/fs/xfs/libxfs/xfs_dir2_leaf.c
> index 30ccf44d817a..ff54c8f08ded 100644
> --- a/fs/xfs/libxfs/xfs_dir2_leaf.c
> +++ b/fs/xfs/libxfs/xfs_dir2_leaf.c
> @@ -865,7 +865,7 @@ xfs_dir2_leaf_addname(
>  	dep->inumber = cpu_to_be64(args->inumber);
>  	dep->namelen = args->namelen;
>  	memcpy(dep->name, args->name, dep->namelen);
> -	dp->d_ops->data_put_ftype(dep, args->filetype);
> +	xfs_dir2_data_put_ftype(dp->i_mount, dep, args->filetype);
>  	tagp = xfs_dir2_data_entry_tag_p(dp->i_mount, dep);
>  	*tagp = cpu_to_be16((char *)dep - (char *)hdr);
>  	/*
> @@ -1195,7 +1195,7 @@ xfs_dir2_leaf_lookup(
>  	 * Return the found inode number & CI name if appropriate
>  	 */
>  	args->inumber = be64_to_cpu(dep->inumber);
> -	args->filetype = dp->d_ops->data_get_ftype(dep);
> +	args->filetype = xfs_dir2_data_get_ftype(dp->i_mount, dep);
>  	error = xfs_dir_cilookup_result(args, dep->name, dep->namelen);
>  	xfs_trans_brelse(tp, dbp);
>  	xfs_trans_brelse(tp, lbp);
> @@ -1524,7 +1524,7 @@ xfs_dir2_leaf_replace(
>  	 * Put the new inode number in, log it.
>  	 */
>  	dep->inumber = cpu_to_be64(args->inumber);
> -	dp->d_ops->data_put_ftype(dep, args->filetype);
> +	xfs_dir2_data_put_ftype(dp->i_mount, dep, args->filetype);
>  	tp = args->trans;
>  	xfs_dir2_data_log_entry(args, dbp, dep);
>  	xfs_dir3_leaf_check(dp, lbp);
> diff --git a/fs/xfs/libxfs/xfs_dir2_node.c b/fs/xfs/libxfs/xfs_dir2_node.c
> index d4a1d2455e72..e51b103fd429 100644
> --- a/fs/xfs/libxfs/xfs_dir2_node.c
> +++ b/fs/xfs/libxfs/xfs_dir2_node.c
> @@ -878,7 +878,7 @@ xfs_dir2_leafn_lookup_for_entry(
>  				xfs_trans_brelse(tp, state->extrablk.bp);
>  			args->cmpresult = cmp;
>  			args->inumber = be64_to_cpu(dep->inumber);
> -			args->filetype = dp->d_ops->data_get_ftype(dep);
> +			args->filetype = xfs_dir2_data_get_ftype(mp, dep);
>  			*indexp = index;
>  			state->extravalid = 1;
>  			state->extrablk.bp = curbp;
> @@ -1963,7 +1963,7 @@ xfs_dir2_node_addname_int(
>  	dep->inumber = cpu_to_be64(args->inumber);
>  	dep->namelen = args->namelen;
>  	memcpy(dep->name, args->name, dep->namelen);
> -	dp->d_ops->data_put_ftype(dep, args->filetype);
> +	xfs_dir2_data_put_ftype(dp->i_mount, dep, args->filetype);
>  	tagp = xfs_dir2_data_entry_tag_p(dp->i_mount, dep);
>  	*tagp = cpu_to_be16((char *)dep - (char *)hdr);
>  	xfs_dir2_data_log_entry(args, dbp, dep);
> @@ -2247,7 +2247,7 @@ xfs_dir2_node_replace(
>  		 * Fill in the new inode number and log the entry.
>  		 */
>  		dep->inumber = cpu_to_be64(inum);
> -		args->dp->d_ops->data_put_ftype(dep, ftype);
> +		xfs_dir2_data_put_ftype(state->mp, dep, ftype);
>  		xfs_dir2_data_log_entry(args, state->extrablk.bp, dep);
>  		rval = 0;
>  	}
> diff --git a/fs/xfs/libxfs/xfs_dir2_priv.h b/fs/xfs/libxfs/xfs_dir2_priv.h
> index 436693514c7c..5258d9da5f12 100644
> --- a/fs/xfs/libxfs/xfs_dir2_priv.h
> +++ b/fs/xfs/libxfs/xfs_dir2_priv.h
> @@ -52,6 +52,10 @@ struct xfs_dir2_data_free *xfs_dir2_data_bestfree_p(struct xfs_mount *mp,
>  int xfs_dir2_data_entsize(struct xfs_mount *mp, int n);
>  __be16 *xfs_dir2_data_entry_tag_p(struct xfs_mount *mp,
>  		struct xfs_dir2_data_entry *dep);
> +uint8_t xfs_dir2_data_get_ftype(struct xfs_mount *mp,
> +		struct xfs_dir2_data_entry *dep);
> +void xfs_dir2_data_put_ftype(struct xfs_mount *mp,
> +		struct xfs_dir2_data_entry *dep, uint8_t ftype);
>  
>  #ifdef DEBUG
>  extern void xfs_dir3_data_check(struct xfs_inode *dp, struct xfs_buf *bp);
> diff --git a/fs/xfs/libxfs/xfs_dir2_sf.c b/fs/xfs/libxfs/xfs_dir2_sf.c
> index 8ecbb0828e42..9a3958aee9f2 100644
> --- a/fs/xfs/libxfs/xfs_dir2_sf.c
> +++ b/fs/xfs/libxfs/xfs_dir2_sf.c
> @@ -337,7 +337,7 @@ xfs_dir2_block_to_sf(
>  			xfs_dir2_sf_put_ino(mp, sfp, sfep,
>  					      be64_to_cpu(dep->inumber));
>  			xfs_dir2_sf_put_ftype(mp, sfep,
> -					dp->d_ops->data_get_ftype(dep));
> +					xfs_dir2_data_get_ftype(mp, dep));
>  
>  			sfep = xfs_dir2_sf_nextentry(mp, sfp, sfep);
>  		}
> diff --git a/fs/xfs/xfs_dir2_readdir.c b/fs/xfs/xfs_dir2_readdir.c
> index 7519317d7a21..7885616bdfe5 100644
> --- a/fs/xfs/xfs_dir2_readdir.c
> +++ b/fs/xfs/xfs_dir2_readdir.c
> @@ -208,7 +208,7 @@ xfs_dir2_block_getdents(
>  					    (char *)dep - (char *)hdr);
>  
>  		ctx->pos = cook & 0x7fffffff;
> -		filetype = dp->d_ops->data_get_ftype(dep);
> +		filetype = xfs_dir2_data_get_ftype(dp->i_mount, dep);
>  		/*
>  		 * If it didn't fit, set the final offset to here & return.
>  		 */
> @@ -463,7 +463,7 @@ xfs_dir2_leaf_getdents(
>  
>  		dep = (xfs_dir2_data_entry_t *)ptr;
>  		length = xfs_dir2_data_entsize(mp, dep->namelen);
> -		filetype = dp->d_ops->data_get_ftype(dep);
> +		filetype = xfs_dir2_data_get_ftype(mp, dep);
>  
>  		ctx->pos = xfs_dir2_byte_to_dataptr(curoff) & 0x7fffffff;
>  		if (!xfs_dir2_namecheck(dep->name, dep->namelen)) {
> -- 
> 2.20.1
> 

^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH 32/34] xfs: remove the now unused dir ops infrastructure
  2019-11-01 22:07 ` [PATCH 32/34] xfs: remove the now unused dir ops infrastructure Christoph Hellwig
@ 2019-11-04 20:50   ` Darrick J. Wong
  0 siblings, 0 replies; 81+ messages in thread
From: Darrick J. Wong @ 2019-11-04 20:50 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-xfs

On Fri, Nov 01, 2019 at 03:07:17PM -0700, Christoph Hellwig wrote:
> Signed-off-by: Christoph Hellwig <hch@lst.de>

YAY!
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>

--D

> ---
>  fs/xfs/Makefile               |  1 -
>  fs/xfs/libxfs/xfs_da_btree.h  |  1 -
>  fs/xfs/libxfs/xfs_da_format.c | 46 -----------------------------------
>  fs/xfs/libxfs/xfs_dir2.c      |  2 --
>  fs/xfs/libxfs/xfs_dir2.h      |  9 -------
>  fs/xfs/xfs_inode.h            |  3 ---
>  fs/xfs/xfs_iops.c             |  1 -
>  fs/xfs/xfs_mount.h            |  2 --
>  8 files changed, 65 deletions(-)
>  delete mode 100644 fs/xfs/libxfs/xfs_da_format.c
> 
> diff --git a/fs/xfs/Makefile b/fs/xfs/Makefile
> index 06b68b6115bc..aceca2f9a3db 100644
> --- a/fs/xfs/Makefile
> +++ b/fs/xfs/Makefile
> @@ -27,7 +27,6 @@ xfs-y				+= $(addprefix libxfs/, \
>  				   xfs_bmap_btree.o \
>  				   xfs_btree.o \
>  				   xfs_da_btree.o \
> -				   xfs_da_format.o \
>  				   xfs_defer.o \
>  				   xfs_dir2.o \
>  				   xfs_dir2_block.o \
> diff --git a/fs/xfs/libxfs/xfs_da_btree.h b/fs/xfs/libxfs/xfs_da_btree.h
> index a3333e7a084d..7362e706cda7 100644
> --- a/fs/xfs/libxfs/xfs_da_btree.h
> +++ b/fs/xfs/libxfs/xfs_da_btree.h
> @@ -10,7 +10,6 @@
>  struct xfs_inode;
>  struct xfs_trans;
>  struct zone;
> -struct xfs_dir_ops;
>  
>  /*
>   * Directory/attribute geometry information. There will be one of these for each
> diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c
> deleted file mode 100644
> index 498363ac193d..000000000000
> --- a/fs/xfs/libxfs/xfs_da_format.c
> +++ /dev/null
> @@ -1,46 +0,0 @@
> -// SPDX-License-Identifier: GPL-2.0
> -/*
> - * Copyright (c) 2000,2002,2005 Silicon Graphics, Inc.
> - * Copyright (c) 2013 Red Hat, Inc.
> - * All Rights Reserved.
> - */
> -#include "xfs.h"
> -#include "xfs_fs.h"
> -#include "xfs_shared.h"
> -#include "xfs_format.h"
> -#include "xfs_log_format.h"
> -#include "xfs_trans_resv.h"
> -#include "xfs_mount.h"
> -#include "xfs_inode.h"
> -#include "xfs_dir2.h"
> -#include "xfs_dir2_priv.h"
> -
> -static const struct xfs_dir_ops xfs_dir2_ops = {
> -};
> -
> -static const struct xfs_dir_ops xfs_dir2_ftype_ops = {
> -};
> -
> -static const struct xfs_dir_ops xfs_dir3_ops = {
> -};
> -
> -/*
> - * Return the ops structure according to the current config.  If we are passed
> - * an inode, then that overrides the default config we use which is based on
> - * feature bits.
> - */
> -const struct xfs_dir_ops *
> -xfs_dir_get_ops(
> -	struct xfs_mount	*mp,
> -	struct xfs_inode	*dp)
> -{
> -	if (dp)
> -		return dp->d_ops;
> -	if (mp->m_dir_inode_ops)
> -		return mp->m_dir_inode_ops;
> -	if (xfs_sb_version_hascrc(&mp->m_sb))
> -		return &xfs_dir3_ops;
> -	if (xfs_sb_version_hasftype(&mp->m_sb))
> -		return &xfs_dir2_ftype_ops;
> -	return &xfs_dir2_ops;
> -}
> diff --git a/fs/xfs/libxfs/xfs_dir2.c b/fs/xfs/libxfs/xfs_dir2.c
> index 33a6e8aacdba..b1fc89173ea6 100644
> --- a/fs/xfs/libxfs/xfs_dir2.c
> +++ b/fs/xfs/libxfs/xfs_dir2.c
> @@ -104,8 +104,6 @@ xfs_da_mount(
>  	ASSERT(mp->m_sb.sb_versionnum & XFS_SB_VERSION_DIRV2BIT);
>  	ASSERT(xfs_dir2_dirblock_bytes(&mp->m_sb) <= XFS_MAX_BLOCKSIZE);
>  
> -	mp->m_dir_inode_ops = xfs_dir_get_ops(mp, NULL);
> -
>  	mp->m_dir_geo = kmem_zalloc(sizeof(struct xfs_da_geometry),
>  				    KM_MAYFAIL);
>  	mp->m_attr_geo = kmem_zalloc(sizeof(struct xfs_da_geometry),
> diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h
> index f869ee01a381..ccdbc612fb76 100644
> --- a/fs/xfs/libxfs/xfs_dir2.h
> +++ b/fs/xfs/libxfs/xfs_dir2.h
> @@ -28,15 +28,6 @@ extern struct xfs_name	xfs_name_dotdot;
>   */
>  extern unsigned char xfs_mode_to_ftype(int mode);
>  
> -/*
> - * directory operations vector for encode/decode routines
> - */
> -struct xfs_dir_ops {
> -};
> -
> -extern const struct xfs_dir_ops *
> -	xfs_dir_get_ops(struct xfs_mount *mp, struct xfs_inode *dp);
> -
>  /*
>   * Generic directory interface routines
>   */
> diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h
> index bcfb35a9c5ca..6516dd1fc86a 100644
> --- a/fs/xfs/xfs_inode.h
> +++ b/fs/xfs/xfs_inode.h
> @@ -37,9 +37,6 @@ typedef struct xfs_inode {
>  	struct xfs_ifork	*i_cowfp;	/* copy on write extents */
>  	struct xfs_ifork	i_df;		/* data fork */
>  
> -	/* operations vectors */
> -	const struct xfs_dir_ops *d_ops;		/* directory ops vector */
> -
>  	/* Transaction and locking information. */
>  	struct xfs_inode_log_item *i_itemp;	/* logging information */
>  	mrlock_t		i_lock;		/* inode lock */
> diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c
> index 40d4495e013c..155c9269b7bb 100644
> --- a/fs/xfs/xfs_iops.c
> +++ b/fs/xfs/xfs_iops.c
> @@ -1317,7 +1317,6 @@ xfs_setup_inode(
>  		lockdep_set_class(&inode->i_rwsem,
>  				  &inode->i_sb->s_type->i_mutex_dir_key);
>  		lockdep_set_class(&ip->i_lock.mr_lock, &xfs_dir_ilock_class);
> -		ip->d_ops = ip->i_mount->m_dir_inode_ops;
>  	} else {
>  		lockdep_set_class(&ip->i_lock.mr_lock, &xfs_nondir_ilock_class);
>  	}
> diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
> index 3ddc5f4d1053..6dc1ff761572 100644
> --- a/fs/xfs/xfs_mount.h
> +++ b/fs/xfs/xfs_mount.h
> @@ -12,7 +12,6 @@ struct xfs_mru_cache;
>  struct xfs_nameops;
>  struct xfs_ail;
>  struct xfs_quotainfo;
> -struct xfs_dir_ops;
>  struct xfs_da_geometry;
>  
>  /* dynamic preallocation free space thresholds, 5% down to 1% */
> @@ -158,7 +157,6 @@ typedef struct xfs_mount {
>  	int			m_swidth;	/* stripe width */
>  	uint8_t			m_sectbb_log;	/* sectlog - BBSHIFT */
>  	const struct xfs_nameops *m_dirnameops;	/* vector of dir name ops */
> -	const struct xfs_dir_ops *m_dir_inode_ops; /* vector of dir inode ops */
>  	uint			m_chsize;	/* size of next field */
>  	atomic_t		m_active_trans;	/* number trans frozen */
>  	struct xfs_mru_cache	*m_filestream;  /* per-mount filestream data */
> -- 
> 2.20.1
> 

^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH 33/34] xfs: merge xfs_dir2_data_freescan and xfs_dir2_data_freescan_int
  2019-11-01 22:07 ` [PATCH 33/34] xfs: merge xfs_dir2_data_freescan and xfs_dir2_data_freescan_int Christoph Hellwig
@ 2019-11-04 20:51   ` Darrick J. Wong
  0 siblings, 0 replies; 81+ messages in thread
From: Darrick J. Wong @ 2019-11-04 20:51 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-xfs

On Fri, Nov 01, 2019 at 03:07:18PM -0700, Christoph Hellwig wrote:
> There is no real need for xfs_dir2_data_freescan wrapper, so rename
> xfs_dir2_data_freescan_int to xfs_dir2_data_freescan and let the
> callers dereference the mount pointer from the inode.
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>

Seems reasonable to me,
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>

--D

> ---
>  fs/xfs/libxfs/xfs_dir2.h       |  4 +---
>  fs/xfs/libxfs/xfs_dir2_block.c | 10 +++++-----
>  fs/xfs/libxfs/xfs_dir2_data.c  | 11 +----------
>  fs/xfs/libxfs/xfs_dir2_leaf.c  |  6 +++---
>  fs/xfs/libxfs/xfs_dir2_node.c  |  4 ++--
>  5 files changed, 12 insertions(+), 23 deletions(-)
> 
> diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h
> index ccdbc612fb76..8bf4cf227740 100644
> --- a/fs/xfs/libxfs/xfs_dir2.h
> +++ b/fs/xfs/libxfs/xfs_dir2.h
> @@ -66,9 +66,7 @@ extern int xfs_dir2_isleaf(struct xfs_da_args *args, int *r);
>  extern int xfs_dir2_shrink_inode(struct xfs_da_args *args, xfs_dir2_db_t db,
>  				struct xfs_buf *bp);
>  
> -extern void xfs_dir2_data_freescan_int(struct xfs_mount *mp,
> -		struct xfs_dir2_data_hdr *hdr, int *loghead);
> -extern void xfs_dir2_data_freescan(struct xfs_inode *dp,
> +extern void xfs_dir2_data_freescan(struct xfs_mount *mp,
>  		struct xfs_dir2_data_hdr *hdr, int *loghead);
>  extern void xfs_dir2_data_log_entry(struct xfs_da_args *args,
>  		struct xfs_buf *bp, struct xfs_dir2_data_entry *dep);
> diff --git a/fs/xfs/libxfs/xfs_dir2_block.c b/fs/xfs/libxfs/xfs_dir2_block.c
> index 94d32e515478..4b3ea6730775 100644
> --- a/fs/xfs/libxfs/xfs_dir2_block.c
> +++ b/fs/xfs/libxfs/xfs_dir2_block.c
> @@ -311,7 +311,7 @@ xfs_dir2_block_compact(
>  	 * This needs to happen before the next call to use_free.
>  	 */
>  	if (needscan)
> -		xfs_dir2_data_freescan(args->dp, hdr, needlog);
> +		xfs_dir2_data_freescan(args->dp->i_mount, hdr, needlog);
>  }
>  
>  /*
> @@ -458,7 +458,7 @@ xfs_dir2_block_addname(
>  		 * This needs to happen before the next call to use_free.
>  		 */
>  		if (needscan) {
> -			xfs_dir2_data_freescan(dp, hdr, &needlog);
> +			xfs_dir2_data_freescan(dp->i_mount, hdr, &needlog);
>  			needscan = 0;
>  		}
>  		/*
> @@ -548,7 +548,7 @@ xfs_dir2_block_addname(
>  	 * Clean up the bestfree array and log the header, tail, and entry.
>  	 */
>  	if (needscan)
> -		xfs_dir2_data_freescan(dp, hdr, &needlog);
> +		xfs_dir2_data_freescan(dp->i_mount, hdr, &needlog);
>  	if (needlog)
>  		xfs_dir2_data_log_header(args, bp);
>  	xfs_dir2_block_log_tail(tp, bp);
> @@ -807,7 +807,7 @@ xfs_dir2_block_removename(
>  	 * Fix up bestfree, log the header if necessary.
>  	 */
>  	if (needscan)
> -		xfs_dir2_data_freescan(dp, hdr, &needlog);
> +		xfs_dir2_data_freescan(dp->i_mount, hdr, &needlog);
>  	if (needlog)
>  		xfs_dir2_data_log_header(args, bp);
>  	xfs_dir3_data_check(dp, bp);
> @@ -1014,7 +1014,7 @@ xfs_dir2_leaf_to_block(
>  	 * Scan the bestfree if we need it and log the data block header.
>  	 */
>  	if (needscan)
> -		xfs_dir2_data_freescan(dp, hdr, &needlog);
> +		xfs_dir2_data_freescan(dp->i_mount, hdr, &needlog);
>  	if (needlog)
>  		xfs_dir2_data_log_header(args, dbp);
>  	/*
> diff --git a/fs/xfs/libxfs/xfs_dir2_data.c b/fs/xfs/libxfs/xfs_dir2_data.c
> index 9752a0da5b95..4304c62796dd 100644
> --- a/fs/xfs/libxfs/xfs_dir2_data.c
> +++ b/fs/xfs/libxfs/xfs_dir2_data.c
> @@ -615,7 +615,7 @@ xfs_dir2_data_freeremove(
>   * Given a data block, reconstruct its bestfree map.
>   */
>  void
> -xfs_dir2_data_freescan_int(
> +xfs_dir2_data_freescan(
>  	struct xfs_mount	*mp,
>  	struct xfs_dir2_data_hdr *hdr,
>  	int			*loghead)
> @@ -670,15 +670,6 @@ xfs_dir2_data_freescan_int(
>  	}
>  }
>  
> -void
> -xfs_dir2_data_freescan(
> -	struct xfs_inode	*dp,
> -	struct xfs_dir2_data_hdr *hdr,
> -	int			*loghead)
> -{
> -	return xfs_dir2_data_freescan_int(dp->i_mount, hdr, loghead);
> -}
> -
>  /*
>   * Initialize a data block at the given block number in the directory.
>   * Give back the buffer for the created block.
> diff --git a/fs/xfs/libxfs/xfs_dir2_leaf.c b/fs/xfs/libxfs/xfs_dir2_leaf.c
> index ff54c8f08ded..6912264e081e 100644
> --- a/fs/xfs/libxfs/xfs_dir2_leaf.c
> +++ b/fs/xfs/libxfs/xfs_dir2_leaf.c
> @@ -465,7 +465,7 @@ xfs_dir2_block_to_leaf(
>  		hdr->magic = cpu_to_be32(XFS_DIR3_DATA_MAGIC);
>  
>  	if (needscan)
> -		xfs_dir2_data_freescan(dp, hdr, &needlog);
> +		xfs_dir2_data_freescan(dp->i_mount, hdr, &needlog);
>  	/*
>  	 * Set up leaf tail and bests table.
>  	 */
> @@ -872,7 +872,7 @@ xfs_dir2_leaf_addname(
>  	 * Need to scan fix up the bestfree table.
>  	 */
>  	if (needscan)
> -		xfs_dir2_data_freescan(dp, hdr, &needlog);
> +		xfs_dir2_data_freescan(dp->i_mount, hdr, &needlog);
>  	/*
>  	 * Need to log the data block's header.
>  	 */
> @@ -1413,7 +1413,7 @@ xfs_dir2_leaf_removename(
>  	 * log the data block header if necessary.
>  	 */
>  	if (needscan)
> -		xfs_dir2_data_freescan(dp, hdr, &needlog);
> +		xfs_dir2_data_freescan(dp->i_mount, hdr, &needlog);
>  	if (needlog)
>  		xfs_dir2_data_log_header(args, dbp);
>  	/*
> diff --git a/fs/xfs/libxfs/xfs_dir2_node.c b/fs/xfs/libxfs/xfs_dir2_node.c
> index e51b103fd429..a131ed5e5f3b 100644
> --- a/fs/xfs/libxfs/xfs_dir2_node.c
> +++ b/fs/xfs/libxfs/xfs_dir2_node.c
> @@ -1322,7 +1322,7 @@ xfs_dir2_leafn_remove(
>  	 * Log the data block header if needed.
>  	 */
>  	if (needscan)
> -		xfs_dir2_data_freescan(dp, hdr, &needlog);
> +		xfs_dir2_data_freescan(dp->i_mount, hdr, &needlog);
>  	if (needlog)
>  		xfs_dir2_data_log_header(args, dbp);
>  	xfs_dir3_data_check(dp, dbp);
> @@ -1970,7 +1970,7 @@ xfs_dir2_node_addname_int(
>  
>  	/* Rescan the freespace and log the data block if needed. */
>  	if (needscan)
> -		xfs_dir2_data_freescan(dp, hdr, &needlog);
> +		xfs_dir2_data_freescan(dp->i_mount, hdr, &needlog);
>  	if (needlog)
>  		xfs_dir2_data_log_header(args, dbp);
>  
> -- 
> 2.20.1
> 

^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH 34/34] xfs: always pass a valid hdr to xfs_dir3_leaf_check_int
  2019-11-01 22:07 ` [PATCH 34/34] xfs: always pass a valid hdr to xfs_dir3_leaf_check_int Christoph Hellwig
@ 2019-11-04 20:53   ` Darrick J. Wong
  0 siblings, 0 replies; 81+ messages in thread
From: Darrick J. Wong @ 2019-11-04 20:53 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-xfs

On Fri, Nov 01, 2019 at 03:07:19PM -0700, Christoph Hellwig wrote:
> Move the code for extracting the incore header to the only caller that
> didn't already do that.
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>

Well, that was quite the cleanup.  Even more surprisingly it didn't
clash too badly with the health reporting patch series I sent yesterday.
:)

Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>

--D

> ---
>  fs/xfs/libxfs/xfs_dir2_leaf.c | 31 +++++++++++++------------------
>  1 file changed, 13 insertions(+), 18 deletions(-)
> 
> diff --git a/fs/xfs/libxfs/xfs_dir2_leaf.c b/fs/xfs/libxfs/xfs_dir2_leaf.c
> index 6912264e081e..fecec1ac8e40 100644
> --- a/fs/xfs/libxfs/xfs_dir2_leaf.c
> +++ b/fs/xfs/libxfs/xfs_dir2_leaf.c
> @@ -137,20 +137,14 @@ xfs_dir3_leaf_check(
>  
>  xfs_failaddr_t
>  xfs_dir3_leaf_check_int(
> -	struct xfs_mount	*mp,
> -	struct xfs_dir3_icleaf_hdr *hdr,
> -	struct xfs_dir2_leaf	*leaf)
> +	struct xfs_mount		*mp,
> +	struct xfs_dir3_icleaf_hdr	*hdr,
> +	struct xfs_dir2_leaf		*leaf)
>  {
> -	xfs_dir2_leaf_tail_t	*ltp;
> -	int			stale;
> -	int			i;
> -	struct xfs_dir3_icleaf_hdr leafhdr;
> -	struct xfs_da_geometry	*geo = mp->m_dir_geo;
> -
> -	if (!hdr) {
> -		xfs_dir2_leaf_hdr_from_disk(mp, &leafhdr, leaf);
> -		hdr = &leafhdr;
> -	}
> +	struct xfs_da_geometry		*geo = mp->m_dir_geo;
> +	xfs_dir2_leaf_tail_t		*ltp;
> +	int				stale;
> +	int				i;
>  
>  	ltp = xfs_dir2_leaf_tail_p(geo, leaf);
>  
> @@ -190,17 +184,18 @@ xfs_dir3_leaf_check_int(
>   */
>  static xfs_failaddr_t
>  xfs_dir3_leaf_verify(
> -	struct xfs_buf		*bp)
> +	struct xfs_buf			*bp)
>  {
> -	struct xfs_mount	*mp = bp->b_mount;
> -	struct xfs_dir2_leaf	*leaf = bp->b_addr;
> -	xfs_failaddr_t		fa;
> +	struct xfs_mount		*mp = bp->b_mount;
> +	struct xfs_dir3_icleaf_hdr	leafhdr;
> +	xfs_failaddr_t			fa;
>  
>  	fa = xfs_da3_blkinfo_verify(bp, bp->b_addr);
>  	if (fa)
>  		return fa;
>  
> -	return xfs_dir3_leaf_check_int(mp, NULL, leaf);
> +	xfs_dir2_leaf_hdr_from_disk(mp, &leafhdr, bp->b_addr);
> +	return xfs_dir3_leaf_check_int(mp, &leafhdr, bp->b_addr);
>  }
>  
>  static void
> -- 
> 2.20.1
> 

^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH 02/34] xfs: refactor btree node scrubbing
  2019-11-04 18:36   ` Darrick J. Wong
@ 2019-11-05  1:35     ` Christoph Hellwig
  0 siblings, 0 replies; 81+ messages in thread
From: Christoph Hellwig @ 2019-11-05  1:35 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: Christoph Hellwig, linux-xfs

On Mon, Nov 04, 2019 at 10:36:18AM -0800, Darrick J. Wong wrote:
> Seeing as this function returns a pointer to struct xfs_attr_leaf_entry,
> why not clean this up to:
> 
> ent = xfs_attr3_leaf_entryp(...)[blk->index]; ?

Well, it should really be xfs_attr3_leaf_entryp + blk->index.  But
otherwise agreed and fixed up for the next version.

^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH 05/34] xfs: add a btree entries pointer to struct xfs_da3_icnode_hdr
  2019-11-04 19:52   ` Darrick J. Wong
@ 2019-11-05  1:38     ` Christoph Hellwig
  2019-11-05  1:58       ` Darrick J. Wong
  0 siblings, 1 reply; 81+ messages in thread
From: Christoph Hellwig @ 2019-11-05  1:38 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: Christoph Hellwig, linux-xfs

On Mon, Nov 04, 2019 at 11:52:33AM -0800, Darrick J. Wong wrote:
> On Fri, Nov 01, 2019 at 03:06:50PM -0700, Christoph Hellwig wrote:
> > All but two callers of the ->node_tree_p dir operation already have a
> > xfs_da3_icnode_hdr from a previous call to xfs_da3_node_hdr_from_disk at
> > hand.  Add a pointer to the btree entries to struct xfs_da3_icnode_hdr
> > to clean up this pattern.  The two remaining callers now expand the
> > whole header as well, but that isn't very expensive and not in a super
> > hot path anyway.
> > 
> > Signed-off-by: Christoph Hellwig <hch@lst.de>
> > ---
> >  fs/xfs/libxfs/xfs_attr_leaf.c |  6 ++--
> >  fs/xfs/libxfs/xfs_da_btree.c  | 68 ++++++++++++++++-------------------
> >  fs/xfs/libxfs/xfs_da_btree.h  |  1 +
> >  fs/xfs/libxfs/xfs_da_format.c | 21 -----------
> >  fs/xfs/libxfs/xfs_dir2.h      |  2 --
> >  fs/xfs/scrub/dabtree.c        |  6 ++--
> >  fs/xfs/xfs_attr_inactive.c    | 34 +++++++++---------
> >  fs/xfs/xfs_attr_list.c        |  2 +-
> >  8 files changed, 55 insertions(+), 85 deletions(-)
> > 
> 
> <snip>
> 
> > diff --git a/fs/xfs/libxfs/xfs_da_btree.h b/fs/xfs/libxfs/xfs_da_btree.h
> > index 69ebf6a50d85..63ed45057fa5 100644
> > --- a/fs/xfs/libxfs/xfs_da_btree.h
> > +++ b/fs/xfs/libxfs/xfs_da_btree.h
> > @@ -135,6 +135,7 @@ struct xfs_da3_icnode_hdr {
> >  	uint16_t		magic;
> >  	uint16_t		count;
> >  	uint16_t		level;
> > +	struct xfs_da_node_entry *btree;
> 
> This adds to the incore node header structure a pointer to raw disk
> structures, right?  Can we make this a little more explicit by naming
> the field "raw_entries" or something?

Hmm, is that really so much of an issue?  Even something that a comment
wouldn't help?  I'd kinda hate making identifiers extremely long, but
if that's what is needed I can change it.  Same for the other patches
doing something similar.

^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH 11/34] xfs: move the max dir2 leaf entries count to struct xfs_da_geometry
  2019-11-04 20:07   ` Darrick J. Wong
@ 2019-11-05  1:42     ` Christoph Hellwig
  2019-11-05  1:58       ` Darrick J. Wong
  0 siblings, 1 reply; 81+ messages in thread
From: Christoph Hellwig @ 2019-11-05  1:42 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: Christoph Hellwig, linux-xfs

On Mon, Nov 04, 2019 at 12:07:44PM -0800, Darrick J. Wong wrote:
> > diff --git a/fs/xfs/libxfs/xfs_da_btree.h b/fs/xfs/libxfs/xfs_da_btree.h
> > index 5e3e954fee77..c8b137685ca7 100644
> > --- a/fs/xfs/libxfs/xfs_da_btree.h
> > +++ b/fs/xfs/libxfs/xfs_da_btree.h
> > @@ -27,6 +27,7 @@ struct xfs_da_geometry {
> >  	int		magicpct;	/* 37% of block size in bytes */
> >  	xfs_dablk_t	datablk;	/* blockno of dir data v2 */
> >  	int		leaf_hdr_size;	/* dir2 leaf header size */
> > +	unsigned int	leaf_max_ents;	/* # of entries in dir2 leaf */
> 
> Why does this one get 'unsigned' but the header size fields don't?
> Or maybe I should rephase that: Why aren't the header sizes unsigned
> too?

They probably should all be unsigned and I should add a prep patch
for the existing ones.

^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH 15/34] xfs: add a bests pointer to struct xfs_dir3_icfree_hdr
  2019-11-04 20:21   ` Darrick J. Wong
@ 2019-11-05  1:44     ` Christoph Hellwig
  2019-11-05  2:05       ` Darrick J. Wong
  0 siblings, 1 reply; 81+ messages in thread
From: Christoph Hellwig @ 2019-11-05  1:44 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: Christoph Hellwig, linux-xfs

On Mon, Nov 04, 2019 at 12:21:45PM -0800, Darrick J. Wong wrote:
> > @@ -233,6 +233,7 @@ xfs_dir2_free_hdr_from_disk(
> >  		to->firstdb = be32_to_cpu(from3->hdr.firstdb);
> >  		to->nvalid = be32_to_cpu(from3->hdr.nvalid);
> >  		to->nused = be32_to_cpu(from3->hdr.nused);
> > +		to->bests = (void *)from3 + sizeof(struct xfs_dir3_free_hdr);
> 
> Urgh, isn't void pointer arithmetic technically illegal according to C?

It is not specified in ISO C, but clearly specified in the GNU C
extensions and used all over the kernel.

> In any case, shouldn't this cast through struct xfs_dir3_free instead of
> open-coding details of the disk format that we've already captured?  The
> same question also applies to the other patches that add pointers to
> ondisk leaf and intnode pointers into the incore header struct.

I don't really understand that sentence.  What would do you instead?

^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH 14/34] xfs: make the xfs_dir3_icfree_hdr available to xfs_dir2_node_addname_int
  2019-11-04 20:25   ` Darrick J. Wong
@ 2019-11-05  1:52     ` Christoph Hellwig
  2019-11-05  1:59       ` Darrick J. Wong
  0 siblings, 1 reply; 81+ messages in thread
From: Christoph Hellwig @ 2019-11-05  1:52 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: Christoph Hellwig, linux-xfs

On Mon, Nov 04, 2019 at 12:25:23PM -0800, Darrick J. Wong wrote:
> On Fri, Nov 01, 2019 at 03:06:59PM -0700, Christoph Hellwig wrote:
> > Return the xfs_dir3_icfree_hdr used by the helpers called from
> > xfs_dir2_node_addname_int to the main function to prepare for the
> > next round of changes.
> 
> How does this help?  Is this purely to reduce stack usage?  Or will we
> use this later to skip some xfs_dir2_free_hdr_from_disk calls?

The latter.

^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH 05/34] xfs: add a btree entries pointer to struct xfs_da3_icnode_hdr
  2019-11-05  1:38     ` Christoph Hellwig
@ 2019-11-05  1:58       ` Darrick J. Wong
  0 siblings, 0 replies; 81+ messages in thread
From: Darrick J. Wong @ 2019-11-05  1:58 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-xfs

On Tue, Nov 05, 2019 at 02:38:32AM +0100, Christoph Hellwig wrote:
> On Mon, Nov 04, 2019 at 11:52:33AM -0800, Darrick J. Wong wrote:
> > On Fri, Nov 01, 2019 at 03:06:50PM -0700, Christoph Hellwig wrote:
> > > All but two callers of the ->node_tree_p dir operation already have a
> > > xfs_da3_icnode_hdr from a previous call to xfs_da3_node_hdr_from_disk at
> > > hand.  Add a pointer to the btree entries to struct xfs_da3_icnode_hdr
> > > to clean up this pattern.  The two remaining callers now expand the
> > > whole header as well, but that isn't very expensive and not in a super
> > > hot path anyway.
> > > 
> > > Signed-off-by: Christoph Hellwig <hch@lst.de>
> > > ---
> > >  fs/xfs/libxfs/xfs_attr_leaf.c |  6 ++--
> > >  fs/xfs/libxfs/xfs_da_btree.c  | 68 ++++++++++++++++-------------------
> > >  fs/xfs/libxfs/xfs_da_btree.h  |  1 +
> > >  fs/xfs/libxfs/xfs_da_format.c | 21 -----------
> > >  fs/xfs/libxfs/xfs_dir2.h      |  2 --
> > >  fs/xfs/scrub/dabtree.c        |  6 ++--
> > >  fs/xfs/xfs_attr_inactive.c    | 34 +++++++++---------
> > >  fs/xfs/xfs_attr_list.c        |  2 +-
> > >  8 files changed, 55 insertions(+), 85 deletions(-)
> > > 
> > 
> > <snip>
> > 
> > > diff --git a/fs/xfs/libxfs/xfs_da_btree.h b/fs/xfs/libxfs/xfs_da_btree.h
> > > index 69ebf6a50d85..63ed45057fa5 100644
> > > --- a/fs/xfs/libxfs/xfs_da_btree.h
> > > +++ b/fs/xfs/libxfs/xfs_da_btree.h
> > > @@ -135,6 +135,7 @@ struct xfs_da3_icnode_hdr {
> > >  	uint16_t		magic;
> > >  	uint16_t		count;
> > >  	uint16_t		level;
> > > +	struct xfs_da_node_entry *btree;
> > 
> > This adds to the incore node header structure a pointer to raw disk
> > structures, right?  Can we make this a little more explicit by naming
> > the field "raw_entries" or something?
> 
> Hmm, is that really so much of an issue?  Even something that a comment
> wouldn't help?  I'd kinda hate making identifiers extremely long, but
> if that's what is needed I can change it.  Same for the other patches
> doing something similar.

<shrug> I think a comment would work.  Or just "__btree"...?

--D

^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH 11/34] xfs: move the max dir2 leaf entries count to struct xfs_da_geometry
  2019-11-05  1:42     ` Christoph Hellwig
@ 2019-11-05  1:58       ` Darrick J. Wong
  0 siblings, 0 replies; 81+ messages in thread
From: Darrick J. Wong @ 2019-11-05  1:58 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-xfs

On Tue, Nov 05, 2019 at 02:42:15AM +0100, Christoph Hellwig wrote:
> On Mon, Nov 04, 2019 at 12:07:44PM -0800, Darrick J. Wong wrote:
> > > diff --git a/fs/xfs/libxfs/xfs_da_btree.h b/fs/xfs/libxfs/xfs_da_btree.h
> > > index 5e3e954fee77..c8b137685ca7 100644
> > > --- a/fs/xfs/libxfs/xfs_da_btree.h
> > > +++ b/fs/xfs/libxfs/xfs_da_btree.h
> > > @@ -27,6 +27,7 @@ struct xfs_da_geometry {
> > >  	int		magicpct;	/* 37% of block size in bytes */
> > >  	xfs_dablk_t	datablk;	/* blockno of dir data v2 */
> > >  	int		leaf_hdr_size;	/* dir2 leaf header size */
> > > +	unsigned int	leaf_max_ents;	/* # of entries in dir2 leaf */
> > 
> > Why does this one get 'unsigned' but the header size fields don't?
> > Or maybe I should rephase that: Why aren't the header sizes unsigned
> > too?
> 
> They probably should all be unsigned and I should add a prep patch
> for the existing ones.

Sounds good!

--D

^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH 14/34] xfs: make the xfs_dir3_icfree_hdr available to xfs_dir2_node_addname_int
  2019-11-05  1:52     ` Christoph Hellwig
@ 2019-11-05  1:59       ` Darrick J. Wong
  0 siblings, 0 replies; 81+ messages in thread
From: Darrick J. Wong @ 2019-11-05  1:59 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-xfs

On Tue, Nov 05, 2019 at 02:52:54AM +0100, Christoph Hellwig wrote:
> On Mon, Nov 04, 2019 at 12:25:23PM -0800, Darrick J. Wong wrote:
> > On Fri, Nov 01, 2019 at 03:06:59PM -0700, Christoph Hellwig wrote:
> > > Return the xfs_dir3_icfree_hdr used by the helpers called from
> > > xfs_dir2_node_addname_int to the main function to prepare for the
> > > next round of changes.
> > 
> > How does this help?  Is this purely to reduce stack usage?  Or will we
> > use this later to skip some xfs_dir2_free_hdr_from_disk calls?
> 
> The latter.

Might be a good idea at least to hint at that in the commit message.

--D

^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH 15/34] xfs: add a bests pointer to struct xfs_dir3_icfree_hdr
  2019-11-05  1:44     ` Christoph Hellwig
@ 2019-11-05  2:05       ` Darrick J. Wong
  2019-11-05 16:44         ` Christoph Hellwig
  0 siblings, 1 reply; 81+ messages in thread
From: Darrick J. Wong @ 2019-11-05  2:05 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-xfs

On Tue, Nov 05, 2019 at 02:44:03AM +0100, Christoph Hellwig wrote:
> On Mon, Nov 04, 2019 at 12:21:45PM -0800, Darrick J. Wong wrote:
> > > @@ -233,6 +233,7 @@ xfs_dir2_free_hdr_from_disk(
> > >  		to->firstdb = be32_to_cpu(from3->hdr.firstdb);
> > >  		to->nvalid = be32_to_cpu(from3->hdr.nvalid);
> > >  		to->nused = be32_to_cpu(from3->hdr.nused);
> > > +		to->bests = (void *)from3 + sizeof(struct xfs_dir3_free_hdr);
> > 
> > Urgh, isn't void pointer arithmetic technically illegal according to C?
> 
> It is not specified in ISO C, but clearly specified in the GNU C
> extensions and used all over the kernel.

Just out of curiosity, do you know if clang supports that extension?

Once in a while we get patches from them to fix various clang warnings,
and at least as of a few years ago clang got grouchy about void pointer
arithmetic.

> > In any case, shouldn't this cast through struct xfs_dir3_free instead of
> > open-coding details of the disk format that we've already captured?  The
> > same question also applies to the other patches that add pointers to
> > ondisk leaf and intnode pointers into the incore header struct.
> 
> I don't really understand that sentence.  What would do you instead?

if (xfs_sb_version_hascrc(&mp->m_sb)) {
	struct xfs_dir3_free	*from3 = (struct xfs_dir3_free *)from;

	...
	to->nused = be32_to_cpu(from3->hdr.nused);
	to->bests = &from3->bests[0];
}

Since we're already passing around pointers to the xfs_dir[23]_free
structure, we might as well use it instead of open-coding the arithmetic.
Sorry that wasn't clear. :/

--D

^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH 15/34] xfs: add a bests pointer to struct xfs_dir3_icfree_hdr
  2019-11-05  2:05       ` Darrick J. Wong
@ 2019-11-05 16:44         ` Christoph Hellwig
  0 siblings, 0 replies; 81+ messages in thread
From: Christoph Hellwig @ 2019-11-05 16:44 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: Christoph Hellwig, linux-xfs

On Mon, Nov 04, 2019 at 06:05:53PM -0800, Darrick J. Wong wrote:
> > It is not specified in ISO C, but clearly specified in the GNU C
> > extensions and used all over the kernel.
> 
> Just out of curiosity, do you know if clang supports that extension?

Yes.  Basically any modern C compiler does.

> > I don't really understand that sentence.  What would do you instead?
> 
> if (xfs_sb_version_hascrc(&mp->m_sb)) {
> 	struct xfs_dir3_free	*from3 = (struct xfs_dir3_free *)from;
> 
> 	...
> 	to->nused = be32_to_cpu(from3->hdr.nused);
> 	to->bests = &from3->bests[0];
> }
> 
> Since we're already passing around pointers to the xfs_dir[23]_free
> structure, we might as well use it instead of open-coding the arithmetic.
> Sorry that wasn't clear. :/

Sure, that is much better and I'll switch to it.

^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH 21/34] xfs: devirtualize ->sf_get_ino and ->sf_put_ino
  2019-11-04 20:33   ` Darrick J. Wong
@ 2019-11-07  1:05     ` Darrick J. Wong
  2019-11-07  8:29       ` Christoph Hellwig
  0 siblings, 1 reply; 81+ messages in thread
From: Darrick J. Wong @ 2019-11-07  1:05 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-xfs

On Mon, Nov 04, 2019 at 12:33:34PM -0800, Darrick J. Wong wrote:
> On Fri, Nov 01, 2019 at 03:07:06PM -0700, Christoph Hellwig wrote:
> > Replace the ->sf_get_ino and ->sf_put_ino dir ops methods with directly
> > called xfs_dir2_sf_get_ino nd xfs_dir2_sf_put_ino helpers that take care
> 
>                             ^^^ "and"
> 
> > of the difference between the directory format with and without the file
> > type field.  Also move xfs_dir2_sf_get_parent_ino and
> > xfs_dir2_sf_put_parent_ino to xfs_dir2_sf.c with the rest of the
> > low-level short form entry handling.
> > 
> > Signed-off-by: Christoph Hellwig <hch@lst.de>
> 
> Looks ok, except...
> 
> <snip>
> 
> > diff --git a/fs/xfs/libxfs/xfs_dir2_sf.c b/fs/xfs/libxfs/xfs_dir2_sf.c
> > index f3a4f0ddfc1a..c33d838b1a5c 100644
> > --- a/fs/xfs/libxfs/xfs_dir2_sf.c
> > +++ b/fs/xfs/libxfs/xfs_dir2_sf.c
> > @@ -63,6 +63,69 @@ xfs_dir2_sf_nextentry(
> >  		((char *)sfep + xfs_dir2_sf_entsize(mp, hdr, sfep->namelen));
> >  }
> >  
> > +/*
> > + * In short-form directory entries the inode numbers are stored at variable
> > + * offset behind the entry name. If the entry stores a filetype value, then it
> > + * sits between the name and the inode number.  The actual inode numbers can
> > + * come in two formats as well, either 4 bytes or 8 bytes wide.
> > + */
> > +xfs_ino_t
> > +xfs_dir2_sf_get_ino(
> > +	struct xfs_mount		*mp,
> > +	struct xfs_dir2_sf_hdr		*hdr,
> > +	struct xfs_dir2_sf_entry	*sfep)
> > +{
> > +	uint8_t				*from = sfep->name + sfep->namelen;
> > +
> > +	if (xfs_sb_version_hasftype(&mp->m_sb))
> > +		from++;
> > +
> > +	if (!hdr->i8count)
> > +		return get_unaligned_be32(from);
> > +	return get_unaligned_be64(from) & 0x00ffffffffffffffULL;
> 
> ...maybe we ought to convert this to use XFS_MAXINUMBER instead of
> encoding magic numbers?
> 
> > +}
> > +
> > +void
> > +xfs_dir2_sf_put_ino(

Also, I think these helpers can be static now...

--D

> > +	struct xfs_mount		*mp,
> > +	struct xfs_dir2_sf_hdr		*hdr,
> > +	struct xfs_dir2_sf_entry	*sfep,
> > +	xfs_ino_t			ino)
> > +{
> > +	uint8_t				*to = sfep->name + sfep->namelen;
> > +
> > +	ASSERT((ino & 0xff00000000000000ULL) == 0);
> 
> Same here...
> 
> > +	if (xfs_sb_version_hasftype(&mp->m_sb))
> > +		to++;
> > +
> > +	if (hdr->i8count)
> > +		put_unaligned_be64(ino, to);
> > +	else
> > +		put_unaligned_be32(ino, to);
> > +}
> > +
> > +xfs_ino_t
> > +xfs_dir2_sf_get_parent_ino(
> > +	struct xfs_dir2_sf_hdr	*hdr)
> > +{
> > +	if (!hdr->i8count)
> > +		return get_unaligned_be32(hdr->parent);
> > +	return get_unaligned_be64(hdr->parent) & 0x00ffffffffffffffULL;
> 
> And here...
> 
> > +}
> > +
> > +void
> > +xfs_dir2_sf_put_parent_ino(
> > +	struct xfs_dir2_sf_hdr		*hdr,
> > +	xfs_ino_t			ino)
> > +{
> > +	ASSERT((ino & 0xff00000000000000ULL) == 0);
> 
> And here?
> 
> --D
> 
> > +	if (hdr->i8count)
> > +		put_unaligned_be64(ino, hdr->parent);
> > +	else
> > +		put_unaligned_be32(ino, hdr->parent);
> > +}
> > +
> >  /*
> >   * Given a block directory (dp/block), calculate its size as a shortform (sf)
> >   * directory and a header for the sf directory, if it will fit it the
> > @@ -240,7 +303,7 @@ xfs_dir2_block_to_sf(
> >  				(xfs_dir2_data_aoff_t)
> >  				((char *)dep - (char *)hdr));
> >  			memcpy(sfep->name, dep->name, dep->namelen);
> > -			dp->d_ops->sf_put_ino(sfp, sfep,
> > +			xfs_dir2_sf_put_ino(mp, sfp, sfep,
> >  					      be64_to_cpu(dep->inumber));
> >  			dp->d_ops->sf_put_ftype(sfep,
> >  					dp->d_ops->data_get_ftype(dep));
> > @@ -413,7 +476,7 @@ xfs_dir2_sf_addname_easy(
> >  	sfep->namelen = args->namelen;
> >  	xfs_dir2_sf_put_offset(sfep, offset);
> >  	memcpy(sfep->name, args->name, sfep->namelen);
> > -	dp->d_ops->sf_put_ino(sfp, sfep, args->inumber);
> > +	xfs_dir2_sf_put_ino(mp, sfp, sfep, args->inumber);
> >  	dp->d_ops->sf_put_ftype(sfep, args->filetype);
> >  
> >  	/*
> > @@ -503,7 +566,7 @@ xfs_dir2_sf_addname_hard(
> >  	sfep->namelen = args->namelen;
> >  	xfs_dir2_sf_put_offset(sfep, offset);
> >  	memcpy(sfep->name, args->name, sfep->namelen);
> > -	dp->d_ops->sf_put_ino(sfp, sfep, args->inumber);
> > +	xfs_dir2_sf_put_ino(mp, sfp, sfep, args->inumber);
> >  	dp->d_ops->sf_put_ftype(sfep, args->filetype);
> >  	sfp->count++;
> >  	if (args->inumber > XFS_DIR2_MAX_SHORT_INUM && !objchange)
> > @@ -620,7 +683,7 @@ xfs_dir2_sf_check(
> >  	     i < sfp->count;
> >  	     i++, sfep = xfs_dir2_sf_nextentry(dp->i_mount, sfp, sfep)) {
> >  		ASSERT(xfs_dir2_sf_get_offset(sfep) >= offset);
> > -		ino = dp->d_ops->sf_get_ino(sfp, sfep);
> > +		ino = xfs_dir2_sf_get_ino(dp->i_mount, sfp, sfep);
> >  		i8count += ino > XFS_DIR2_MAX_SHORT_INUM;
> >  		offset =
> >  			xfs_dir2_sf_get_offset(sfep) +
> > @@ -712,7 +775,7 @@ xfs_dir2_sf_verify(
> >  			return __this_address;
> >  
> >  		/* Check the inode number. */
> > -		ino = dops->sf_get_ino(sfp, sfep);
> > +		ino = xfs_dir2_sf_get_ino(mp, sfp, sfep);
> >  		i8count += ino > XFS_DIR2_MAX_SHORT_INUM;
> >  		error = xfs_dir_ino_validate(mp, ino);
> >  		if (error)
> > @@ -861,7 +924,7 @@ xfs_dir2_sf_lookup(
> >  								sfep->namelen);
> >  		if (cmp != XFS_CMP_DIFFERENT && cmp != args->cmpresult) {
> >  			args->cmpresult = cmp;
> > -			args->inumber = dp->d_ops->sf_get_ino(sfp, sfep);
> > +			args->inumber = xfs_dir2_sf_get_ino(mp, sfp, sfep);
> >  			args->filetype = dp->d_ops->sf_get_ftype(sfep);
> >  			if (cmp == XFS_CMP_EXACT)
> >  				return -EEXIST;
> > @@ -920,7 +983,7 @@ xfs_dir2_sf_removename(
> >  	     i++, sfep = xfs_dir2_sf_nextentry(mp, sfp, sfep)) {
> >  		if (xfs_da_compname(args, sfep->name, sfep->namelen) ==
> >  								XFS_CMP_EXACT) {
> > -			ASSERT(dp->d_ops->sf_get_ino(sfp, sfep) ==
> > +			ASSERT(xfs_dir2_sf_get_ino(mp, sfp, sfep) ==
> >  			       args->inumber);
> >  			break;
> >  		}
> > @@ -1041,9 +1104,10 @@ xfs_dir2_sf_replace(
> >  		     i++, sfep = xfs_dir2_sf_nextentry(mp, sfp, sfep)) {
> >  			if (xfs_da_compname(args, sfep->name, sfep->namelen) ==
> >  								XFS_CMP_EXACT) {
> > -				ino = dp->d_ops->sf_get_ino(sfp, sfep);
> > +				ino = xfs_dir2_sf_get_ino(mp, sfp, sfep);
> >  				ASSERT(args->inumber != ino);
> > -				dp->d_ops->sf_put_ino(sfp, sfep, args->inumber);
> > +				xfs_dir2_sf_put_ino(mp, sfp, sfep,
> > +						args->inumber);
> >  				dp->d_ops->sf_put_ftype(sfep, args->filetype);
> >  				break;
> >  			}
> > @@ -1148,8 +1212,8 @@ xfs_dir2_sf_toino4(
> >  		sfep->namelen = oldsfep->namelen;
> >  		memcpy(sfep->offset, oldsfep->offset, sizeof(sfep->offset));
> >  		memcpy(sfep->name, oldsfep->name, sfep->namelen);
> > -		dp->d_ops->sf_put_ino(sfp, sfep,
> > -				      dp->d_ops->sf_get_ino(oldsfp, oldsfep));
> > +		xfs_dir2_sf_put_ino(mp, sfp, sfep,
> > +				xfs_dir2_sf_get_ino(mp, oldsfp, oldsfep));
> >  		dp->d_ops->sf_put_ftype(sfep, dp->d_ops->sf_get_ftype(oldsfep));
> >  	}
> >  	/*
> > @@ -1220,8 +1284,8 @@ xfs_dir2_sf_toino8(
> >  		sfep->namelen = oldsfep->namelen;
> >  		memcpy(sfep->offset, oldsfep->offset, sizeof(sfep->offset));
> >  		memcpy(sfep->name, oldsfep->name, sfep->namelen);
> > -		dp->d_ops->sf_put_ino(sfp, sfep,
> > -				      dp->d_ops->sf_get_ino(oldsfp, oldsfep));
> > +		xfs_dir2_sf_put_ino(mp, sfp, sfep,
> > +				xfs_dir2_sf_get_ino(mp, oldsfp, oldsfep));
> >  		dp->d_ops->sf_put_ftype(sfep, dp->d_ops->sf_get_ftype(oldsfep));
> >  	}
> >  	/*
> > diff --git a/fs/xfs/xfs_dir2_readdir.c b/fs/xfs/xfs_dir2_readdir.c
> > index 7d150e914d00..9d318f091a73 100644
> > --- a/fs/xfs/xfs_dir2_readdir.c
> > +++ b/fs/xfs/xfs_dir2_readdir.c
> > @@ -114,7 +114,7 @@ xfs_dir2_sf_getdents(
> >  			continue;
> >  		}
> >  
> > -		ino = dp->d_ops->sf_get_ino(sfp, sfep);
> > +		ino = xfs_dir2_sf_get_ino(mp, sfp, sfep);
> >  		filetype = dp->d_ops->sf_get_ftype(sfep);
> >  		ctx->pos = off & 0x7fffffff;
> >  		if (!xfs_dir2_namecheck(sfep->name, sfep->namelen)) {
> > -- 
> > 2.20.1
> > 

^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH 21/34] xfs: devirtualize ->sf_get_ino and ->sf_put_ino
  2019-11-07  1:05     ` Darrick J. Wong
@ 2019-11-07  8:29       ` Christoph Hellwig
  0 siblings, 0 replies; 81+ messages in thread
From: Christoph Hellwig @ 2019-11-07  8:29 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: Christoph Hellwig, linux-xfs

On Wed, Nov 06, 2019 at 05:05:55PM -0800, Darrick J. Wong wrote:
> > > +}
> > > +
> > > +void
> > > +xfs_dir2_sf_put_ino(
> 
> Also, I think these helpers can be static now...

xfs_dir2_sf_put_ino can and should be marked static.  xfs_dir2_sf_get_ino
is used elsewhere, though.

^ permalink raw reply	[flat|nested] 81+ messages in thread

end of thread, other threads:[~2019-11-07  8:29 UTC | newest]

Thread overview: 81+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-11-01 22:06 remove m_dirops Christoph Hellwig
2019-11-01 22:06 ` [PATCH 01/34] xfs: move incore structures out of xfs_da_format.h Christoph Hellwig
2019-11-04 18:21   ` Darrick J. Wong
2019-11-01 22:06 ` [PATCH 02/34] xfs: refactor btree node scrubbing Christoph Hellwig
2019-11-04 18:36   ` Darrick J. Wong
2019-11-05  1:35     ` Christoph Hellwig
2019-11-01 22:06 ` [PATCH 03/34] xfs: devirtualize ->node_hdr_from_disk Christoph Hellwig
2019-11-04 18:37   ` Darrick J. Wong
2019-11-01 22:06 ` [PATCH 04/34] xfs: devirtualize ->node_hdr_to_disk Christoph Hellwig
2019-11-04 18:39   ` Darrick J. Wong
2019-11-01 22:06 ` [PATCH 05/34] xfs: add a btree entries pointer to struct xfs_da3_icnode_hdr Christoph Hellwig
2019-11-04 19:52   ` Darrick J. Wong
2019-11-05  1:38     ` Christoph Hellwig
2019-11-05  1:58       ` Darrick J. Wong
2019-11-01 22:06 ` [PATCH 06/34] xfs: move the node header size to struct xfs_da_geometry Christoph Hellwig
2019-11-04 19:58   ` Darrick J. Wong
2019-11-01 22:06 ` [PATCH 07/34] xfs: devirtualize ->leaf_hdr_from_disk Christoph Hellwig
2019-11-04 19:59   ` Darrick J. Wong
2019-11-01 22:06 ` [PATCH 08/34] xfs: devirtualize ->leaf_hdr_to_disk Christoph Hellwig
2019-11-04 20:00   ` Darrick J. Wong
2019-11-01 22:06 ` [PATCH 09/34] xfs: add a entries pointer to struct xfs_dir3_icleaf_hdr Christoph Hellwig
2019-11-04 20:04   ` Darrick J. Wong
2019-11-01 22:06 ` [PATCH 10/34] xfs: move the dir2 leaf header size to struct xfs_da_geometry Christoph Hellwig
2019-11-04 20:05   ` Darrick J. Wong
2019-11-01 22:06 ` [PATCH 11/34] xfs: move the max dir2 leaf entries count " Christoph Hellwig
2019-11-04 20:07   ` Darrick J. Wong
2019-11-05  1:42     ` Christoph Hellwig
2019-11-05  1:58       ` Darrick J. Wong
2019-11-01 22:06 ` [PATCH 12/34] xfs: devirtualize ->free_hdr_from_disk Christoph Hellwig
2019-11-04 20:08   ` Darrick J. Wong
2019-11-01 22:06 ` [PATCH 13/34] xfs: devirtualize ->free_hdr_to_disk Christoph Hellwig
2019-11-04 20:08   ` Darrick J. Wong
2019-11-01 22:06 ` [PATCH 14/34] xfs: make the xfs_dir3_icfree_hdr available to xfs_dir2_node_addname_int Christoph Hellwig
2019-11-04 20:25   ` Darrick J. Wong
2019-11-05  1:52     ` Christoph Hellwig
2019-11-05  1:59       ` Darrick J. Wong
2019-11-01 22:07 ` [PATCH 15/34] xfs: add a bests pointer to struct xfs_dir3_icfree_hdr Christoph Hellwig
2019-11-04 20:21   ` Darrick J. Wong
2019-11-05  1:44     ` Christoph Hellwig
2019-11-05  2:05       ` Darrick J. Wong
2019-11-05 16:44         ` Christoph Hellwig
2019-11-01 22:07 ` [PATCH 16/34] xfs: move the dir2 free header size to struct xfs_da_geometry Christoph Hellwig
2019-11-04 20:22   ` Darrick J. Wong
2019-11-01 22:07 ` [PATCH 17/34] xfs: move the max dir2 free bests count " Christoph Hellwig
2019-11-04 20:23   ` Darrick J. Wong
2019-11-01 22:07 ` [PATCH 18/34] xfs: devirtualize ->db_to_fdb and ->db_to_fdindex Christoph Hellwig
2019-11-04 20:26   ` Darrick J. Wong
2019-11-01 22:07 ` [PATCH 19/34] xfs: devirtualize ->sf_get_parent_ino and ->sf_put_parent_ino Christoph Hellwig
2019-11-04 20:26   ` Darrick J. Wong
2019-11-01 22:07 ` [PATCH 20/34] xfs: devirtualize ->sf_entsize and ->sf_nextentry Christoph Hellwig
2019-11-04 20:28   ` Darrick J. Wong
2019-11-01 22:07 ` [PATCH 21/34] xfs: devirtualize ->sf_get_ino and ->sf_put_ino Christoph Hellwig
2019-11-04 20:33   ` Darrick J. Wong
2019-11-07  1:05     ` Darrick J. Wong
2019-11-07  8:29       ` Christoph Hellwig
2019-11-01 22:07 ` [PATCH 22/34] xfs: devirtualize ->sf_get_ftype and ->sf_put_ftype Christoph Hellwig
2019-11-04 20:34   ` Darrick J. Wong
2019-11-01 22:07 ` [PATCH 23/34] xfs: remove the ->data_dot_entry_p and ->data_dotdot_entry_p methods Christoph Hellwig
2019-11-04 20:37   ` Darrick J. Wong
2019-11-01 22:07 ` [PATCH 24/34] xfs: remove the unused ->data_first_entry_p method Christoph Hellwig
2019-11-04 20:38   ` Darrick J. Wong
2019-11-01 22:07 ` [PATCH 25/34] xfs: remove the ->data_entry_entry_p method Christoph Hellwig
2019-11-04 20:41   ` Darrick J. Wong
2019-11-01 22:07 ` [PATCH 26/34] xfs: devirtualize ->data_entsize Christoph Hellwig
2019-11-04 20:45   ` Darrick J. Wong
2019-11-01 22:07 ` [PATCH 27/34] xfs: devirtualize ->data_entry_tag_p Christoph Hellwig
2019-11-04 20:45   ` Darrick J. Wong
2019-11-01 22:07 ` [PATCH 28/34] xfs: move the dir2 data block fixed offsets to struct xfs_da_geometry Christoph Hellwig
2019-11-04 20:46   ` Darrick J. Wong
2019-11-01 22:07 ` [PATCH 29/34] xfs: cleanup xfs_dir2_data_entsize Christoph Hellwig
2019-11-04 20:48   ` Darrick J. Wong
2019-11-01 22:07 ` [PATCH 30/34] xfs: devirtualize ->data_bestfree_p Christoph Hellwig
2019-11-04 20:49   ` Darrick J. Wong
2019-11-01 22:07 ` [PATCH 31/34] xfs: devirtualize ->data_get_ftype and ->data_put_ftype Christoph Hellwig
2019-11-04 20:50   ` Darrick J. Wong
2019-11-01 22:07 ` [PATCH 32/34] xfs: remove the now unused dir ops infrastructure Christoph Hellwig
2019-11-04 20:50   ` Darrick J. Wong
2019-11-01 22:07 ` [PATCH 33/34] xfs: merge xfs_dir2_data_freescan and xfs_dir2_data_freescan_int Christoph Hellwig
2019-11-04 20:51   ` Darrick J. Wong
2019-11-01 22:07 ` [PATCH 34/34] xfs: always pass a valid hdr to xfs_dir3_leaf_check_int Christoph Hellwig
2019-11-04 20:53   ` Darrick J. Wong

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.