All of lore.kernel.org
 help / color / mirror / Atom feed
* remove m_dirops v2
@ 2019-11-07 18:23 Christoph Hellwig
  2019-11-07 18:23 ` [PATCH 01/46] xfs: move incore structures out of xfs_da_format.h Christoph Hellwig
                   ` (45 more replies)
  0 siblings, 46 replies; 73+ messages in thread
From: Christoph Hellwig @ 2019-11-07 18:23 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.

Changes since v1:
 - use unsigned int everywhere in struct xfs_da_geometry
 - cleanup pointer arithmetics in various places, and document the reasons why
   we are doing pointer arithmetics better in various changelog
 - use unsigned types more consistently
 - document the pointers to the on-disk antry arrays in the various
   in-core header structures
 - use XFS_MAXINUMBER instead of open coded constants
 - misc additional cleanups

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

* [PATCH 01/46] xfs: move incore structures out of xfs_da_format.h
  2019-11-07 18:23 remove m_dirops v2 Christoph Hellwig
@ 2019-11-07 18:23 ` Christoph Hellwig
  2019-11-07 18:23 ` [PATCH 02/46] xfs: use unsigned int for all size values in struct xfs_da_geometry Christoph Hellwig
                   ` (44 subsequent siblings)
  45 siblings, 0 replies; 73+ messages in thread
From: Christoph Hellwig @ 2019-11-07 18:23 UTC (permalink / raw)
  To: linux-xfs; +Cc: Darrick J . Wong

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>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 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 | 19 ++++++++++++
 6 files changed, 58 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..d2eaea663e7f 100644
--- a/fs/xfs/libxfs/xfs_dir2_priv.h
+++ b/fs/xfs/libxfs/xfs_dir2_priv.h
@@ -8,6 +8,25 @@
 
 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] 73+ messages in thread

* [PATCH 02/46] xfs: use unsigned int for all size values in struct xfs_da_geometry
  2019-11-07 18:23 remove m_dirops v2 Christoph Hellwig
  2019-11-07 18:23 ` [PATCH 01/46] xfs: move incore structures out of xfs_da_format.h Christoph Hellwig
@ 2019-11-07 18:23 ` Christoph Hellwig
  2019-11-07 22:33   ` Darrick J. Wong
  2019-11-07 18:23 ` [PATCH 03/46] xfs: refactor btree node scrubbing Christoph Hellwig
                   ` (43 subsequent siblings)
  45 siblings, 1 reply; 73+ messages in thread
From: Christoph Hellwig @ 2019-11-07 18:23 UTC (permalink / raw)
  To: linux-xfs

None of these can ever be negative, so use unsigned types.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 fs/xfs/libxfs/xfs_da_btree.h | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_da_btree.h b/fs/xfs/libxfs/xfs_da_btree.h
index 02f7a21ab3a5..01b0bbe8b266 100644
--- a/fs/xfs/libxfs/xfs_da_btree.h
+++ b/fs/xfs/libxfs/xfs_da_btree.h
@@ -18,12 +18,12 @@ struct xfs_dir_ops;
  * structures will be attached to the xfs_mount.
  */
 struct xfs_da_geometry {
-	int		blksize;	/* da block size in bytes */
-	int		fsbcount;	/* da block size in filesystem blocks */
+	unsigned int	blksize;	/* da block size in bytes */
+	unsigned int	fsbcount;	/* da block size in filesystem blocks */
 	uint8_t		fsblog;		/* log2 of _filesystem_ block size */
 	uint8_t		blklog;		/* log2 of da block size */
-	uint		node_ents;	/* # of entries in a danode */
-	int		magicpct;	/* 37% of block size in bytes */
+	unsigned int	node_ents;	/* # of entries in a danode */
+	unsigned int	magicpct;	/* 37% of block size in bytes */
 	xfs_dablk_t	datablk;	/* blockno of dir data v2 */
 	xfs_dablk_t	leafblk;	/* blockno of leaf data v2 */
 	xfs_dablk_t	freeblk;	/* blockno of free data v2 */
-- 
2.20.1


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

* [PATCH 03/46] xfs: refactor btree node scrubbing
  2019-11-07 18:23 remove m_dirops v2 Christoph Hellwig
  2019-11-07 18:23 ` [PATCH 01/46] xfs: move incore structures out of xfs_da_format.h Christoph Hellwig
  2019-11-07 18:23 ` [PATCH 02/46] xfs: use unsigned int for all size values in struct xfs_da_geometry Christoph Hellwig
@ 2019-11-07 18:23 ` Christoph Hellwig
  2019-11-07 22:43   ` Darrick J. Wong
  2019-11-07 18:23 ` [PATCH 04/46] xfs: devirtualize ->node_hdr_from_disk Christoph Hellwig
                   ` (42 subsequent siblings)
  45 siblings, 1 reply; 73+ messages in thread
From: Christoph Hellwig @ 2019-11-07 18:23 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    | 11 +++++-----
 fs/xfs/scrub/dabtree.c | 48 ++++++++++--------------------------------
 fs/xfs/scrub/dabtree.h |  3 +--
 fs/xfs/scrub/dir.c     | 12 ++++++++---
 4 files changed, 27 insertions(+), 47 deletions(-)

diff --git a/fs/xfs/scrub/attr.c b/fs/xfs/scrub/attr.c
index 0edc7f8eb96e..d9f0dd444b80 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,9 @@ xchk_xattr_rec(
 	unsigned int			badflags;
 	int				error;
 
-	blk = &ds->state->path.blk[level];
+	ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC);
+
+	ent = xfs_attr3_leaf_entryp(blk->bp->b_addr) + blk->index;
 
 	/* 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] 73+ messages in thread

* [PATCH 04/46] xfs: devirtualize ->node_hdr_from_disk
  2019-11-07 18:23 remove m_dirops v2 Christoph Hellwig
                   ` (2 preceding siblings ...)
  2019-11-07 18:23 ` [PATCH 03/46] xfs: refactor btree node scrubbing Christoph Hellwig
@ 2019-11-07 18:23 ` Christoph Hellwig
  2019-11-07 18:23 ` [PATCH 05/46] xfs: devirtualize ->node_hdr_to_disk Christoph Hellwig
                   ` (41 subsequent siblings)
  45 siblings, 0 replies; 73+ messages in thread
From: Christoph Hellwig @ 2019-11-07 18:23 UTC (permalink / raw)
  To: linux-xfs; +Cc: Darrick J . Wong

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>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 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 dca8840496ea..08176cf261fb 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 9925d4a7dc33..434f1e7191e4 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)
@@ -579,7 +601,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;
@@ -639,7 +661,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);
@@ -688,7 +710,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.
@@ -735,7 +757,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);
@@ -790,8 +812,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);
 
@@ -806,8 +828,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;
@@ -888,8 +910,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);
 	}
@@ -923,7 +945,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);
@@ -1094,7 +1116,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);
 
@@ -1174,7 +1196,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 */
@@ -1232,7 +1254,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)
@@ -1279,7 +1301,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)
@@ -1330,7 +1352,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;
@@ -1362,7 +1384,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);
 
@@ -1418,8 +1440,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;
@@ -1554,7 +1576,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! */
@@ -1690,8 +1712,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);
 
@@ -1914,7 +1936,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)) {
@@ -1975,7 +1997,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)
@@ -2260,7 +2282,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);
@@ -2320,7 +2342,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);
@@ -2371,7 +2393,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 01b0bbe8b266..21dc03c818e9 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 43ae392992e7..88bc796c83f6 100644
--- a/fs/xfs/xfs_attr_inactive.c
+++ b/fs/xfs/xfs_attr_inactive.c
@@ -215,7 +215,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 64f6ceba9254..d89b83e89387 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] 73+ messages in thread

* [PATCH 05/46] xfs: devirtualize ->node_hdr_to_disk
  2019-11-07 18:23 remove m_dirops v2 Christoph Hellwig
                   ` (3 preceding siblings ...)
  2019-11-07 18:23 ` [PATCH 04/46] xfs: devirtualize ->node_hdr_from_disk Christoph Hellwig
@ 2019-11-07 18:23 ` Christoph Hellwig
  2019-11-07 18:23 ` [PATCH 06/46] xfs: add a btree entries pointer to struct xfs_da3_icnode_hdr Christoph Hellwig
                   ` (40 subsequent siblings)
  45 siblings, 0 replies; 73+ messages in thread
From: Christoph Hellwig @ 2019-11-07 18:23 UTC (permalink / raw)
  To: linux-xfs; +Cc: Darrick J . Wong

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>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 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 08176cf261fb..ba1c3486fe54 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 434f1e7191e4..2a0221fcad82 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));
 
@@ -668,7 +693,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) ||
@@ -893,11 +918,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 +
@@ -969,7 +994,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));
 
@@ -1405,7 +1430,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));
 
@@ -1477,7 +1502,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 21dc03c818e9..932f3ba6a813 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] 73+ messages in thread

* [PATCH 06/46] xfs: add a btree entries pointer to struct xfs_da3_icnode_hdr
  2019-11-07 18:23 remove m_dirops v2 Christoph Hellwig
                   ` (4 preceding siblings ...)
  2019-11-07 18:23 ` [PATCH 05/46] xfs: devirtualize ->node_hdr_to_disk Christoph Hellwig
@ 2019-11-07 18:23 ` Christoph Hellwig
  2019-11-08  0:21   ` Darrick J. Wong
  2019-11-07 18:23 ` [PATCH 07/46] xfs: move the node header size to struct xfs_da_geometry Christoph Hellwig
                   ` (39 subsequent siblings)
  45 siblings, 1 reply; 73+ messages in thread
From: Christoph Hellwig @ 2019-11-07 18:23 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  |  6 ++++
 fs/xfs/libxfs/xfs_da_format.c | 21 -----------
 fs/xfs/libxfs/xfs_dir2.h      |  2 --
 fs/xfs/scrub/dabtree.c        |  7 ++--
 fs/xfs/xfs_attr_inactive.c    | 34 +++++++++---------
 fs/xfs/xfs_attr_list.c        |  2 +-
 8 files changed, 60 insertions(+), 86 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_attr_leaf.c b/fs/xfs/libxfs/xfs_attr_leaf.c
index ba1c3486fe54..13d034e8f076 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 2a0221fcad82..6ffecab08d9e 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);
 	}
 }
@@ -627,7 +629,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;
 
@@ -687,7 +689,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);
@@ -839,8 +841,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.
@@ -855,8 +857,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;
 	}
 
@@ -937,8 +939,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);
@@ -971,7 +973,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);
@@ -1131,7 +1133,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;
 
@@ -1155,8 +1156,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);
@@ -1321,18 +1321,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);
 }
 
 /*
@@ -1378,7 +1374,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;
@@ -1417,7 +1413,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);
@@ -1467,8 +1463,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;
 
 	/*
@@ -1602,7 +1598,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) {
@@ -1739,8 +1735,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)) ||
@@ -1937,7 +1933,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;
@@ -1960,17 +1955,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;
 		}
 	}
@@ -2021,9 +2015,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;
@@ -2308,7 +2302,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);
 	}
@@ -2375,7 +2369,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;
@@ -2425,7 +2419,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 932f3ba6a813..4955c1fb8b0d 100644
--- a/fs/xfs/libxfs/xfs_da_btree.h
+++ b/fs/xfs/libxfs/xfs_da_btree.h
@@ -135,6 +135,12 @@ struct xfs_da3_icnode_hdr {
 	uint16_t		magic;
 	uint16_t		count;
 	uint16_t		level;
+
+	/*
+	 * Pointer to the on-disk format entries, which are behind the
+	 * variable size (v4 vs v5) header in the on-disk block.
+	 */
+	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..dbcb9d932816 100644
--- a/fs/xfs/scrub/dabtree.c
+++ b/fs/xfs/scrub/dabtree.c
@@ -83,11 +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) +
-		(blk->index * sizeof(struct xfs_da_node_entry));
+	xfs_da3_node_hdr_from_disk(ds->sc->mp, &hdr, blk->bp->b_addr);
+	return hdr.btree + blk->index;
 }
 
 /* Scrub a da btree hash (key). */
@@ -411,7 +412,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 88bc796c83f6..a78c501f6fb1 100644
--- a/fs/xfs/xfs_attr_inactive.c
+++ b/fs/xfs/xfs_attr_inactive.c
@@ -191,19 +191,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.
@@ -214,15 +212,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 */
 
 	/*
@@ -282,13 +278,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 d89b83e89387..0ec6606149a2 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] 73+ messages in thread

* [PATCH 07/46] xfs: move the node header size to struct xfs_da_geometry
  2019-11-07 18:23 remove m_dirops v2 Christoph Hellwig
                   ` (5 preceding siblings ...)
  2019-11-07 18:23 ` [PATCH 06/46] xfs: add a btree entries pointer to struct xfs_da3_icnode_hdr Christoph Hellwig
@ 2019-11-07 18:23 ` Christoph Hellwig
  2019-11-07 18:23 ` [PATCH 08/46] xfs: devirtualize ->leaf_hdr_from_disk Christoph Hellwig
                   ` (38 subsequent siblings)
  45 siblings, 0 replies; 73+ messages in thread
From: Christoph Hellwig @ 2019-11-07 18:23 UTC (permalink / raw)
  To: linux-xfs; +Cc: Darrick J . Wong

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>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 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 6ffecab08d9e..34928c96ea5f 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;
@@ -922,12 +922,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)));
 
 	/*
@@ -998,7 +999,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.
@@ -1428,7 +1430,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.
@@ -1501,7 +1503,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 4955c1fb8b0d..396b76ac02d6 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 {
 	unsigned int	fsbcount;	/* da block size in filesystem blocks */
 	uint8_t		fsblog;		/* log2 of _filesystem_ block size */
 	uint8_t		blklog;		/* log2 of da block size */
+	unsigned int	node_hdr_size;	/* danode header size in bytes */
 	unsigned int	node_ents;	/* # of entries in a danode */
 	unsigned 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 452d04ae10ce..98cc0631e7d5 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 4c7962ccb0c4..21e6d08e3e18 100644
--- a/fs/xfs/xfs_iops.c
+++ b/fs/xfs/xfs_iops.c
@@ -1323,7 +1323,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 0481e6d086a7..9719f2aa8be3 100644
--- a/fs/xfs/xfs_mount.h
+++ b/fs/xfs/xfs_mount.h
@@ -157,7 +157,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] 73+ messages in thread

* [PATCH 08/46] xfs: devirtualize ->leaf_hdr_from_disk
  2019-11-07 18:23 remove m_dirops v2 Christoph Hellwig
                   ` (6 preceding siblings ...)
  2019-11-07 18:23 ` [PATCH 07/46] xfs: move the node header size to struct xfs_da_geometry Christoph Hellwig
@ 2019-11-07 18:23 ` Christoph Hellwig
  2019-11-07 18:23 ` [PATCH 09/46] xfs: devirtualize ->leaf_hdr_to_disk Christoph Hellwig
                   ` (37 subsequent siblings)
  45 siblings, 0 replies; 73+ messages in thread
From: Christoph Hellwig @ 2019-11-07 18:23 UTC (permalink / raw)
  To: linux-xfs; +Cc: Darrick J . Wong

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>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 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 34928c96ea5f..1742e8293574 100644
--- a/fs/xfs/libxfs/xfs_da_btree.c
+++ b/fs/xfs/libxfs/xfs_da_btree.c
@@ -643,7 +643,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 ||
@@ -2295,7 +2295,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 e1afa35141c5..d9ad89f6fd79 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 388b5da12228..b27609c852c5 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.
@@ -1511,7 +1540,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.
@@ -1699,7 +1728,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 72d7ed17eef5..d4402b491a41 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;
@@ -440,7 +440,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);
 
 	/*
@@ -538,7 +538,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 ||
@@ -587,7 +587,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);
@@ -739,7 +739,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);
@@ -977,8 +977,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);
 
@@ -1030,8 +1030,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);
 
@@ -1228,7 +1228,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);
 
 	/*
@@ -1450,7 +1450,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);
 
@@ -1513,7 +1513,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]);
@@ -1576,8 +1576,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 d2eaea663e7f..5f42f2c81869 100644
--- a/fs/xfs/libxfs/xfs_dir2_priv.h
+++ b/fs/xfs/libxfs/xfs_dir2_priv.h
@@ -66,6 +66,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] 73+ messages in thread

* [PATCH 09/46] xfs: devirtualize ->leaf_hdr_to_disk
  2019-11-07 18:23 remove m_dirops v2 Christoph Hellwig
                   ` (7 preceding siblings ...)
  2019-11-07 18:23 ` [PATCH 08/46] xfs: devirtualize ->leaf_hdr_from_disk Christoph Hellwig
@ 2019-11-07 18:23 ` Christoph Hellwig
  2019-11-07 18:23 ` [PATCH 10/46] xfs: add a entries pointer to struct xfs_dir3_icleaf_hdr Christoph Hellwig
                   ` (36 subsequent siblings)
  45 siblings, 0 replies; 73+ messages in thread
From: Christoph Hellwig @ 2019-11-07 18:23 UTC (permalink / raw)
  To: linux-xfs; +Cc: Darrick J . Wong

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>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 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 b27609c852c5..07734c0fe8a7 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);
@@ -1386,7 +1415,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);
@@ -1777,7 +1806,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 d4402b491a41..98cd645a8c99 100644
--- a/fs/xfs/libxfs/xfs_dir2_node.c
+++ b/fs/xfs/libxfs/xfs_dir2_node.c
@@ -497,7 +497,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);
@@ -1079,8 +1079,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);
 
@@ -1249,7 +1249,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);
@@ -1605,8 +1605,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 5f42f2c81869..af96e3faefaf 100644
--- a/fs/xfs/libxfs/xfs_dir2_priv.h
+++ b/fs/xfs/libxfs/xfs_dir2_priv.h
@@ -68,6 +68,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] 73+ messages in thread

* [PATCH 10/46] xfs: add a entries pointer to struct xfs_dir3_icleaf_hdr
  2019-11-07 18:23 remove m_dirops v2 Christoph Hellwig
                   ` (8 preceding siblings ...)
  2019-11-07 18:23 ` [PATCH 09/46] xfs: devirtualize ->leaf_hdr_to_disk Christoph Hellwig
@ 2019-11-07 18:23 ` Christoph Hellwig
  2019-11-08  0:28   ` Darrick J. Wong
  2019-11-07 18:23 ` [PATCH 11/46] xfs: move the dir2 leaf header size to struct xfs_da_geometry Christoph Hellwig
                   ` (35 subsequent siblings)
  45 siblings, 1 reply; 73+ messages in thread
From: Christoph Hellwig @ 2019-11-07 18:23 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  |   9 ++-
 fs/xfs/scrub/dir.c             |  14 ++---
 8 files changed, 93 insertions(+), 126 deletions(-)

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


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

* [PATCH 11/46] xfs: move the dir2 leaf header size to struct xfs_da_geometry
  2019-11-07 18:23 remove m_dirops v2 Christoph Hellwig
                   ` (9 preceding siblings ...)
  2019-11-07 18:23 ` [PATCH 10/46] xfs: add a entries pointer to struct xfs_dir3_icleaf_hdr Christoph Hellwig
@ 2019-11-07 18:23 ` Christoph Hellwig
  2019-11-07 18:23 ` [PATCH 12/46] xfs: move the max dir2 leaf entries count " Christoph Hellwig
                   ` (34 subsequent siblings)
  45 siblings, 0 replies; 73+ messages in thread
From: Christoph Hellwig @ 2019-11-07 18:23 UTC (permalink / raw)
  To: linux-xfs; +Cc: Darrick J . Wong

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

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 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 396b76ac02d6..b262ec403bba 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 {
 	unsigned int	node_ents;	/* # of entries in a danode */
 	unsigned int	magicpct;	/* 37% of block size in bytes */
 	xfs_dablk_t	datablk;	/* blockno of dir data v2 */
+	unsigned 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 98cc0631e7d5..6e7a4e9ced5e 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 5e3e96efdaca..888d4b0acab8 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 721dd2dcba8d..f7ba4d22165c 100644
--- a/fs/xfs/libxfs/xfs_dir2_node.c
+++ b/fs/xfs/libxfs/xfs_dir2_node.c
@@ -1340,7 +1340,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;
@@ -1446,7 +1446,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] 73+ messages in thread

* [PATCH 12/46] xfs: move the max dir2 leaf entries count to struct xfs_da_geometry
  2019-11-07 18:23 remove m_dirops v2 Christoph Hellwig
                   ` (10 preceding siblings ...)
  2019-11-07 18:23 ` [PATCH 11/46] xfs: move the dir2 leaf header size to struct xfs_da_geometry Christoph Hellwig
@ 2019-11-07 18:23 ` Christoph Hellwig
  2019-11-07 18:23 ` [PATCH 13/46] xfs: devirtualize ->free_hdr_from_disk Christoph Hellwig
                   ` (33 subsequent siblings)
  45 siblings, 0 replies; 73+ messages in thread
From: Christoph Hellwig @ 2019-11-07 18:23 UTC (permalink / raw)
  To: linux-xfs; +Cc: Darrick J . Wong

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

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 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 b262ec403bba..c6ff5329e92b 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 {
 	unsigned int	magicpct;	/* 37% of block size in bytes */
 	xfs_dablk_t	datablk;	/* blockno of dir data v2 */
 	unsigned 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 6e7a4e9ced5e..8093afb389a1 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 888d4b0acab8..7e4e77f2f5b5 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 f7ba4d22165c..2c44248b7b4a 100644
--- a/fs/xfs/libxfs/xfs_dir2_node.c
+++ b/fs/xfs/libxfs/xfs_dir2_node.c
@@ -459,7 +459,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 6754e1477661..5ca9b5bde60a 100644
--- a/fs/xfs/scrub/dir.c
+++ b/fs/xfs/scrub/dir.c
@@ -486,7 +486,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;
@@ -526,7 +525,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] 73+ messages in thread

* [PATCH 13/46] xfs: devirtualize ->free_hdr_from_disk
  2019-11-07 18:23 remove m_dirops v2 Christoph Hellwig
                   ` (11 preceding siblings ...)
  2019-11-07 18:23 ` [PATCH 12/46] xfs: move the max dir2 leaf entries count " Christoph Hellwig
@ 2019-11-07 18:23 ` Christoph Hellwig
  2019-11-07 18:23 ` [PATCH 14/46] xfs: devirtualize ->free_hdr_to_disk Christoph Hellwig
                   ` (32 subsequent siblings)
  45 siblings, 0 replies; 73+ messages in thread
From: Christoph Hellwig @ 2019-11-07 18:23 UTC (permalink / raw)
  To: linux-xfs; +Cc: Darrick J . Wong

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>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 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 7e4e77f2f5b5..b435379ddaa2 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
@@ -1758,7 +1750,7 @@ xfs_dir2_node_to_leaf(
 	if (error)
 		return error;
 	free = fbp->b_addr;
-	dp->d_ops->free_hdr_from_disk(&freehdr, free);
+	xfs_dir2_free_hdr_from_disk(mp, &freehdr, free);
 
 	ASSERT(!freehdr.firstdb);
 
diff --git a/fs/xfs/libxfs/xfs_dir2_node.c b/fs/xfs/libxfs/xfs_dir2_node.c
index 2c44248b7b4a..d337ecd4e3be 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) >
@@ -513,7 +537,7 @@ xfs_dir2_free_hdr_check(
 {
 	struct xfs_dir3_icfree_hdr hdr;
 
-	dp->d_ops->free_hdr_from_disk(&hdr, bp->b_addr);
+	xfs_dir2_free_hdr_from_disk(dp->i_mount, &hdr, bp->b_addr);
 
 	ASSERT((hdr.firstdb %
 		dp->d_ops->free_max_bests(dp->i_mount->m_dir_geo)) == 0);
@@ -1123,7 +1147,7 @@ xfs_dir3_data_block_free(
 	struct xfs_dir3_icfree_hdr freehdr;
 	struct xfs_inode	*dp = args->dp;
 
-	dp->d_ops->free_hdr_from_disk(&freehdr, free);
+	xfs_dir2_free_hdr_from_disk(dp->i_mount, &freehdr, free);
 	bests = dp->d_ops->free_bests_p(free);
 	if (hdr) {
 		/*
@@ -1292,7 +1316,8 @@ xfs_dir2_leafn_remove(
 #ifdef DEBUG
 	{
 		struct xfs_dir3_icfree_hdr freehdr;
-		dp->d_ops->free_hdr_from_disk(&freehdr, free);
+
+		xfs_dir2_free_hdr_from_disk(dp->i_mount, &freehdr, free);
 		ASSERT(freehdr.firstdb == dp->d_ops->free_max_bests(args->geo) *
 			(fdb - xfs_dir2_byte_to_db(args->geo,
 						   XFS_DIR2_FREE_OFFSET)));
@@ -1686,7 +1711,7 @@ xfs_dir2_node_add_datablk(
 			return error;
 		free = fbp->b_addr;
 		bests = dp->d_ops->free_bests_p(free);
-		dp->d_ops->free_hdr_from_disk(&freehdr, free);
+		xfs_dir2_free_hdr_from_disk(mp, &freehdr, free);
 
 		/* Remember the first slot as our empty slot. */
 		freehdr.firstdb = (fbno - xfs_dir2_byte_to_db(args->geo,
@@ -1695,7 +1720,7 @@ xfs_dir2_node_add_datablk(
 	} else {
 		free = fbp->b_addr;
 		bests = dp->d_ops->free_bests_p(free);
-		dp->d_ops->free_hdr_from_disk(&freehdr, free);
+		xfs_dir2_free_hdr_from_disk(mp, &freehdr, free);
 	}
 
 	/* Set the freespace block index from the data block number. */
@@ -1764,7 +1789,8 @@ xfs_dir2_node_find_freeblk(
 		if (findex >= 0) {
 			/* caller already found the freespace for us. */
 			bests = dp->d_ops->free_bests_p(free);
-			dp->d_ops->free_hdr_from_disk(&freehdr, free);
+			xfs_dir2_free_hdr_from_disk(dp->i_mount, &freehdr,
+						    free);
 
 			ASSERT(findex < freehdr.nvalid);
 			ASSERT(be16_to_cpu(bests[findex]) != NULLDATAOFF);
@@ -1813,7 +1839,7 @@ xfs_dir2_node_find_freeblk(
 
 		free = fbp->b_addr;
 		bests = dp->d_ops->free_bests_p(free);
-		dp->d_ops->free_hdr_from_disk(&freehdr, free);
+		xfs_dir2_free_hdr_from_disk(dp->i_mount, &freehdr, free);
 
 		/* Scan the free entry array for a large enough free space. */
 		for (findex = freehdr.nvalid - 1; findex >= 0; findex--) {
@@ -2266,7 +2292,7 @@ xfs_dir2_node_trim_free(
 	if (!bp)
 		return 0;
 	free = bp->b_addr;
-	dp->d_ops->free_hdr_from_disk(&freehdr, free);
+	xfs_dir2_free_hdr_from_disk(dp->i_mount, &freehdr, free);
 
 	/*
 	 * If there are used entries, there's nothing to do.
diff --git a/fs/xfs/libxfs/xfs_dir2_priv.h b/fs/xfs/libxfs/xfs_dir2_priv.h
index 1f068812c453..2c3370a3c010 100644
--- a/fs/xfs/libxfs/xfs_dir2_priv.h
+++ b/fs/xfs/libxfs/xfs_dir2_priv.h
@@ -109,10 +109,11 @@ xfs_dir3_leaf_find_entry(struct xfs_dir3_icleaf_hdr *leafhdr,
 extern int xfs_dir2_node_to_leaf(struct xfs_da_state *state);
 
 extern xfs_failaddr_t xfs_dir3_leaf_check_int(struct xfs_mount *mp,
-		struct xfs_inode *dp, struct xfs_dir3_icleaf_hdr *hdr,
-		struct xfs_dir2_leaf *leaf);
+		struct xfs_dir3_icleaf_hdr *hdr, struct xfs_dir2_leaf *leaf);
 
 /* xfs_dir2_node.c */
+void xfs_dir2_free_hdr_from_disk(struct xfs_mount *mp,
+		struct xfs_dir3_icfree_hdr *to, struct xfs_dir2_free *from);
 extern int xfs_dir2_leaf_to_node(struct xfs_da_args *args,
 		struct xfs_buf *lbp);
 extern xfs_dahash_t xfs_dir2_leaf_lasthash(struct xfs_inode *dp,
diff --git a/fs/xfs/scrub/dir.c b/fs/xfs/scrub/dir.c
index 5ca9b5bde60a..b0af252dccb3 100644
--- a/fs/xfs/scrub/dir.c
+++ b/fs/xfs/scrub/dir.c
@@ -600,7 +600,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] 73+ messages in thread

* [PATCH 14/46] xfs: devirtualize ->free_hdr_to_disk
  2019-11-07 18:23 remove m_dirops v2 Christoph Hellwig
                   ` (12 preceding siblings ...)
  2019-11-07 18:23 ` [PATCH 13/46] xfs: devirtualize ->free_hdr_from_disk Christoph Hellwig
@ 2019-11-07 18:23 ` Christoph Hellwig
  2019-11-07 18:23 ` [PATCH 15/46] xfs: make the xfs_dir3_icfree_hdr available to xfs_dir2_node_addname_int Christoph Hellwig
                   ` (31 subsequent siblings)
  45 siblings, 0 replies; 73+ messages in thread
From: Christoph Hellwig @ 2019-11-07 18:23 UTC (permalink / raw)
  To: linux-xfs; +Cc: Darrick J . Wong

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>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 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 d337ecd4e3be..4e49ac64a2ff 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;
 }
@@ -420,7 +445,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);
 
@@ -1182,7 +1207,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);
 
 	/*
@@ -1739,7 +1764,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] 73+ messages in thread

* [PATCH 15/46] xfs: make the xfs_dir3_icfree_hdr available to xfs_dir2_node_addname_int
  2019-11-07 18:23 remove m_dirops v2 Christoph Hellwig
                   ` (13 preceding siblings ...)
  2019-11-07 18:23 ` [PATCH 14/46] xfs: devirtualize ->free_hdr_to_disk Christoph Hellwig
@ 2019-11-07 18:23 ` Christoph Hellwig
  2019-11-08  1:06   ` Darrick J. Wong
  2019-11-07 18:23 ` [PATCH 16/46] xfs: add a bests pointer to struct xfs_dir3_icfree_hdr Christoph Hellwig
                   ` (30 subsequent siblings)
  45 siblings, 1 reply; 73+ messages in thread
From: Christoph Hellwig @ 2019-11-07 18:23 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 where we'll use the ichdr in xfs_dir3_icfree_hdr
to avoid extra operations to find the bests pointers.

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 4e49ac64a2ff..6d67ceac48b7 100644
--- a/fs/xfs/libxfs/xfs_dir2_node.c
+++ b/fs/xfs/libxfs/xfs_dir2_node.c
@@ -1666,14 +1666,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;
@@ -1736,25 +1735,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);
 	}
 
@@ -1763,14 +1762,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;
@@ -1784,10 +1782,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;
@@ -1814,13 +1812,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;
 		}
 
@@ -1864,13 +1861,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;
 			}
 		}
@@ -1904,6 +1901,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;
@@ -1918,8 +1916,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;
 
@@ -1941,7 +1939,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] 73+ messages in thread

* [PATCH 16/46] xfs: add a bests pointer to struct xfs_dir3_icfree_hdr
  2019-11-07 18:23 remove m_dirops v2 Christoph Hellwig
                   ` (14 preceding siblings ...)
  2019-11-07 18:23 ` [PATCH 15/46] xfs: make the xfs_dir3_icfree_hdr available to xfs_dir2_node_addname_int Christoph Hellwig
@ 2019-11-07 18:23 ` Christoph Hellwig
  2019-11-08  0:34   ` Darrick J. Wong
  2019-11-07 18:23 ` [PATCH 17/46] xfs: move the dir2 free header size to struct xfs_da_geometry Christoph Hellwig
                   ` (29 subsequent siblings)
  45 siblings, 1 reply; 73+ messages in thread
From: Christoph Hellwig @ 2019-11-07 18:23 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 |  6 +++
 fs/xfs/scrub/dir.c            |  6 +--
 6 files changed, 48 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 b435379ddaa2..bbbd7b96678a 100644
--- a/fs/xfs/libxfs/xfs_dir2_leaf.c
+++ b/fs/xfs/libxfs/xfs_dir2_leaf.c
@@ -1680,7 +1680,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 */
@@ -1749,8 +1748,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);
 
@@ -1784,7 +1782,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 6d67ceac48b7..e9b4667faeac 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 = from3->bests;
 
 		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 = from->bests;
+
 		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) >
@@ -432,11 +430,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);
 	}
 
 	/*
@@ -446,7 +444,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);
 
 	/*
@@ -677,7 +675,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;
 			/*
@@ -712,8 +710,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)
@@ -721,7 +720,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;
 		}
 	}
@@ -1168,19 +1167,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;
 	}
 
@@ -1196,14 +1193,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;
 	}
 
@@ -1232,7 +1229,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;
 }
 
@@ -1673,11 +1670,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. */
@@ -1733,18 +1728,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. */
@@ -1754,14 +1745,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);
@@ -1769,7 +1760,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;
@@ -1786,7 +1777,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;
@@ -1796,7 +1786,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;
 
@@ -1807,16 +1796,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;
 		}
@@ -1859,14 +1845,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;
 			}
@@ -1883,7 +1867,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.
@@ -1898,7 +1881,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;
@@ -1913,7 +1895,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,
@@ -1984,16 +1965,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 2c3370a3c010..9128f7aae0be 100644
--- a/fs/xfs/libxfs/xfs_dir2_priv.h
+++ b/fs/xfs/libxfs/xfs_dir2_priv.h
@@ -31,6 +31,12 @@ struct xfs_dir3_icfree_hdr {
 	uint32_t		firstdb;
 	uint32_t		nvalid;
 	uint32_t		nused;
+
+	/*
+	 * Pointer to the on-disk format entries, which are behind the
+	 * variable size (v4 vs v5) header in the on-disk block.
+	 */
+	__be16			*bests;
 };
 
 /* xfs_dir2.c */
diff --git a/fs/xfs/scrub/dir.c b/fs/xfs/scrub/dir.c
index b0af252dccb3..bb08a1cbe523 100644
--- a/fs/xfs/scrub/dir.c
+++ b/fs/xfs/scrub/dir.c
@@ -580,7 +580,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;
@@ -601,9 +600,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] 73+ messages in thread

* [PATCH 17/46] xfs: move the dir2 free header size to struct xfs_da_geometry
  2019-11-07 18:23 remove m_dirops v2 Christoph Hellwig
                   ` (15 preceding siblings ...)
  2019-11-07 18:23 ` [PATCH 16/46] xfs: add a bests pointer to struct xfs_dir3_icfree_hdr Christoph Hellwig
@ 2019-11-07 18:23 ` Christoph Hellwig
  2019-11-08  0:34   ` Darrick J. Wong
  2019-11-07 18:23 ` [PATCH 18/46] xfs: move the max dir2 free bests count " Christoph Hellwig
                   ` (28 subsequent siblings)
  45 siblings, 1 reply; 73+ messages in thread
From: Christoph Hellwig @ 2019-11-07 18:23 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 c6ff5329e92b..e8f0b7ac051c 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 {
 	unsigned 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 */
+	unsigned 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 8093afb389a1..eee75ec9707f 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 e9b4667faeac..c9a52e4e515d 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] 73+ messages in thread

* [PATCH 18/46] xfs: move the max dir2 free bests count to struct xfs_da_geometry
  2019-11-07 18:23 remove m_dirops v2 Christoph Hellwig
                   ` (16 preceding siblings ...)
  2019-11-07 18:23 ` [PATCH 17/46] xfs: move the dir2 free header size to struct xfs_da_geometry Christoph Hellwig
@ 2019-11-07 18:23 ` Christoph Hellwig
  2019-11-07 18:23 ` [PATCH 19/46] xfs: devirtualize ->db_to_fdb and ->db_to_fdindex Christoph Hellwig
                   ` (27 subsequent siblings)
  45 siblings, 0 replies; 73+ messages in thread
From: Christoph Hellwig @ 2019-11-07 18:23 UTC (permalink / raw)
  To: linux-xfs; +Cc: Darrick J . Wong

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

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 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 e8f0b7ac051c..40110acf9f8a 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 */
 	unsigned 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 eee75ec9707f..77a297e7d91c 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 c9a52e4e515d..826651f72527 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;
@@ -562,8 +561,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);
 }
@@ -1340,7 +1338,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)));
 	}
@@ -1733,7 +1731,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);
 	}
@@ -1743,7 +1741,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] 73+ messages in thread

* [PATCH 19/46] xfs: devirtualize ->db_to_fdb and ->db_to_fdindex
  2019-11-07 18:23 remove m_dirops v2 Christoph Hellwig
                   ` (17 preceding siblings ...)
  2019-11-07 18:23 ` [PATCH 18/46] xfs: move the max dir2 free bests count " Christoph Hellwig
@ 2019-11-07 18:23 ` Christoph Hellwig
  2019-11-07 18:23 ` [PATCH 20/46] xfs: devirtualize ->sf_get_parent_ino and ->sf_put_parent_ino Christoph Hellwig
                   ` (26 subsequent siblings)
  45 siblings, 0 replies; 73+ messages in thread
From: Christoph Hellwig @ 2019-11-07 18:23 UTC (permalink / raw)
  To: linux-xfs; +Cc: Darrick J . Wong

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>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 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 826651f72527..7b0de42c2c77 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.
  */
@@ -680,7 +699,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.
 			 */
@@ -704,7 +723,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.
 			 */
@@ -1326,7 +1345,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);
@@ -1346,7 +1365,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
@@ -1689,7 +1708,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)
@@ -1704,11 +1723,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,
@@ -1737,7 +1756,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] 73+ messages in thread

* [PATCH 20/46] xfs: devirtualize ->sf_get_parent_ino and ->sf_put_parent_ino
  2019-11-07 18:23 remove m_dirops v2 Christoph Hellwig
                   ` (18 preceding siblings ...)
  2019-11-07 18:23 ` [PATCH 19/46] xfs: devirtualize ->db_to_fdb and ->db_to_fdindex Christoph Hellwig
@ 2019-11-07 18:23 ` Christoph Hellwig
  2019-11-07 18:23 ` [PATCH 21/46] xfs: devirtualize ->sf_entsize and ->sf_nextentry Christoph Hellwig
                   ` (25 subsequent siblings)
  45 siblings, 0 replies; 73+ messages in thread
From: Christoph Hellwig @ 2019-11-07 18:23 UTC (permalink / raw)
  To: linux-xfs; +Cc: Darrick J . Wong

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>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 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 065fe10a842b..bc47113b78e5 100644
--- a/fs/xfs/libxfs/xfs_dir2_block.c
+++ b/fs/xfs/libxfs/xfs_dir2_block.c
@@ -1157,7 +1157,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 9128f7aae0be..bb50853d0988 100644
--- a/fs/xfs/libxfs/xfs_dir2_priv.h
+++ b/fs/xfs/libxfs/xfs_dir2_priv.h
@@ -145,6 +145,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 d6b164a2fe57..c7ca25acdb18 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.
 		 */
@@ -584,7 +584,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);
@@ -647,7 +647,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)
@@ -757,7 +757,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);
@@ -806,7 +806,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;
@@ -984,9 +984,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.
@@ -1092,7 +1092,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.
 	 */
@@ -1165,7 +1165,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] 73+ messages in thread

* [PATCH 21/46] xfs: devirtualize ->sf_entsize and ->sf_nextentry
  2019-11-07 18:23 remove m_dirops v2 Christoph Hellwig
                   ` (19 preceding siblings ...)
  2019-11-07 18:23 ` [PATCH 20/46] xfs: devirtualize ->sf_get_parent_ino and ->sf_put_parent_ino Christoph Hellwig
@ 2019-11-07 18:23 ` Christoph Hellwig
  2019-11-07 18:23 ` [PATCH 22/46] xfs: devirtualize ->sf_get_ino and ->sf_put_ino Christoph Hellwig
                   ` (24 subsequent siblings)
  45 siblings, 0 replies; 73+ messages in thread
From: Christoph Hellwig @ 2019-11-07 18:23 UTC (permalink / raw)
  To: linux-xfs; +Cc: Darrick J . Wong

Just check for file-type enabled directories directly.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 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    | 96 ++++++++++++++++++++--------------
 fs/xfs/xfs_dir2_readdir.c      |  7 +--
 6 files changed, 64 insertions(+), 95 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 bc47113b78e5..a6decb4c079a 100644
--- a/fs/xfs/libxfs/xfs_dir2_block.c
+++ b/fs/xfs/libxfs/xfs_dir2_block.c
@@ -1225,7 +1225,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 bb50853d0988..357b388a5be0 100644
--- a/fs/xfs/libxfs/xfs_dir2_priv.h
+++ b/fs/xfs/libxfs/xfs_dir2_priv.h
@@ -147,6 +147,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 c7ca25acdb18..36d79ec57d55 100644
--- a/fs/xfs/libxfs/xfs_dir2_sf.c
+++ b/fs/xfs/libxfs/xfs_dir2_sf.c
@@ -37,6 +37,31 @@ 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 (void *)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 +244,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);
 	}
@@ -285,7 +310,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;
 
 	/*
@@ -358,18 +383,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.
@@ -410,9 +434,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 */
@@ -426,8 +451,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);
@@ -444,7 +467,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)
@@ -482,7 +505,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);
@@ -504,7 +527,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 */
@@ -513,8 +537,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;
@@ -530,7 +552,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
@@ -589,7 +611,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;
@@ -674,7 +696,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;
 
@@ -773,7 +795,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 */
@@ -784,7 +807,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);
 	ASSERT(dp->i_d.di_size >= offsetof(struct xfs_dir2_sf_hdr, parent));
@@ -816,7 +838,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
@@ -852,8 +874,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 */
@@ -863,8 +886,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;
 	ASSERT(oldsize >= offsetof(struct xfs_dir2_sf_hdr, parent));
@@ -877,7 +898,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) ==
@@ -894,7 +915,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.
@@ -933,7 +954,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 */
@@ -942,8 +964,6 @@ xfs_dir2_sf_replace(
 
 	trace_xfs_dir2_sf_replace(args);
 
-	dp = args->dp;
-
 	ASSERT(dp->i_df.if_flags & XFS_IFINLINE);
 	ASSERT(dp->i_d.di_size >= offsetof(struct xfs_dir2_sf_hdr, parent));
 	ASSERT(dp->i_df.if_bytes == dp->i_d.di_size);
@@ -993,7 +1013,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);
@@ -1052,8 +1072,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 */
@@ -1064,8 +1085,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.
@@ -1099,8 +1118,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);
@@ -1125,8 +1144,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 */
@@ -1137,8 +1157,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.
@@ -1172,8 +1190,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] 73+ messages in thread

* [PATCH 22/46] xfs: devirtualize ->sf_get_ino and ->sf_put_ino
  2019-11-07 18:23 remove m_dirops v2 Christoph Hellwig
                   ` (20 preceding siblings ...)
  2019-11-07 18:23 ` [PATCH 21/46] xfs: devirtualize ->sf_entsize and ->sf_nextentry Christoph Hellwig
@ 2019-11-07 18:23 ` Christoph Hellwig
  2019-11-08  0:36   ` Darrick J. Wong
  2019-11-07 18:23 ` [PATCH 23/46] xfs: devirtualize ->sf_get_ftype and ->sf_put_ftype Christoph Hellwig
                   ` (23 subsequent siblings)
  45 siblings, 1 reply; 73+ messages in thread
From: Christoph Hellwig @ 2019-11-07 18:23 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 and 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 and use XFS_MAXINUMBER istead of
opencoded constants.

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    | 91 +++++++++++++++++++++++++++-----
 fs/xfs/xfs_dir2_readdir.c      |  2 +-
 6 files changed, 82 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 a6decb4c079a..02b0344508e0 100644
--- a/fs/xfs/libxfs/xfs_dir2_block.c
+++ b/fs/xfs/libxfs/xfs_dir2_block.c
@@ -1208,7 +1208,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 357b388a5be0..a194a7b57277 100644
--- a/fs/xfs/libxfs/xfs_dir2_priv.h
+++ b/fs/xfs/libxfs/xfs_dir2_priv.h
@@ -145,6 +145,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 36d79ec57d55..f63fb044bd15 100644
--- a/fs/xfs/libxfs/xfs_dir2_sf.c
+++ b/fs/xfs/libxfs/xfs_dir2_sf.c
@@ -62,6 +62,70 @@ xfs_dir2_sf_nextentry(
 	return (void *)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) & XFS_MAXINUMBER;
+}
+
+static 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 <= XFS_MAXINUMBER);
+
+	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) & XFS_MAXINUMBER;
+}
+
+void
+xfs_dir2_sf_put_parent_ino(
+	struct xfs_dir2_sf_hdr		*hdr,
+	xfs_ino_t			ino)
+{
+	ASSERT(ino <= XFS_MAXINUMBER);
+
+	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
@@ -239,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));
@@ -406,7 +470,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);
 
 	/*
@@ -496,7 +560,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)
@@ -613,7 +677,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) +
@@ -705,7 +769,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)
@@ -848,7 +912,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;
@@ -901,7 +965,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;
 		}
@@ -1016,9 +1080,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;
 			}
@@ -1123,8 +1188,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));
 	}
 	/*
@@ -1195,8 +1260,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] 73+ messages in thread

* [PATCH 23/46] xfs: devirtualize ->sf_get_ftype and ->sf_put_ftype
  2019-11-07 18:23 remove m_dirops v2 Christoph Hellwig
                   ` (21 preceding siblings ...)
  2019-11-07 18:23 ` [PATCH 22/46] xfs: devirtualize ->sf_get_ino and ->sf_put_ino Christoph Hellwig
@ 2019-11-07 18:23 ` Christoph Hellwig
  2019-11-07 18:23 ` [PATCH 24/46] xfs: remove the unused ->data_first_entry_p method Christoph Hellwig
                   ` (22 subsequent siblings)
  45 siblings, 0 replies; 73+ messages in thread
From: Christoph Hellwig @ 2019-11-07 18:23 UTC (permalink / raw)
  To: linux-xfs; +Cc: Darrick J . Wong

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>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 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 02b0344508e0..6bc82a02b228 100644
--- a/fs/xfs/libxfs/xfs_dir2_block.c
+++ b/fs/xfs/libxfs/xfs_dir2_block.c
@@ -1210,7 +1210,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 a194a7b57277..b49f745f1bc3 100644
--- a/fs/xfs/libxfs/xfs_dir2_priv.h
+++ b/fs/xfs/libxfs/xfs_dir2_priv.h
@@ -149,6 +149,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 f63fb044bd15..39a537c61b04 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);
@@ -471,7 +502,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.
@@ -561,7 +592,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++;
@@ -658,7 +689,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 */
@@ -666,8 +698,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);
@@ -675,14 +705,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);
@@ -776,7 +806,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;
 
@@ -913,7 +943,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;
@@ -1084,7 +1114,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;
 			}
 		}
@@ -1190,7 +1220,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.
@@ -1262,7 +1293,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] 73+ messages in thread

* [PATCH 24/46] xfs: remove the unused ->data_first_entry_p method
  2019-11-07 18:23 remove m_dirops v2 Christoph Hellwig
                   ` (22 preceding siblings ...)
  2019-11-07 18:23 ` [PATCH 23/46] xfs: devirtualize ->sf_get_ftype and ->sf_put_ftype Christoph Hellwig
@ 2019-11-07 18:23 ` Christoph Hellwig
  2019-11-07 18:23 ` [PATCH 25/46] xfs: remove the data_dot_offset field in struct xfs_dir_ops Christoph Hellwig
                   ` (21 subsequent siblings)
  45 siblings, 0 replies; 73+ messages in thread
From: Christoph Hellwig @ 2019-11-07 18:23 UTC (permalink / raw)
  To: linux-xfs; +Cc: Darrick J . Wong

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 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 1c72b46344d6..19343c65be91 100644
--- a/fs/xfs/libxfs/xfs_da_format.c
+++ b/fs/xfs/libxfs/xfs_da_format.c
@@ -131,16 +131,6 @@ xfs_dir2_data_dotdot_entry_p(
 				XFS_DIR2_DATA_ENTSIZE(1));
 }
 
-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_dotdot_entry_p(
 	struct xfs_dir2_data_hdr *hdr)
@@ -150,16 +140,6 @@ xfs_dir2_ftype_data_dotdot_entry_p(
 				XFS_DIR3_DATA_ENTSIZE(1));
 }
 
-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_dot_entry_p(
 	struct xfs_dir2_data_hdr *hdr)
@@ -177,16 +157,6 @@ xfs_dir3_data_dotdot_entry_p(
 				XFS_DIR3_DATA_ENTSIZE(1));
 }
 
-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)
 {
@@ -244,7 +214,6 @@ static const struct xfs_dir_ops xfs_dir2_ops = {
 
 	.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,
 };
@@ -266,7 +235,6 @@ static const struct xfs_dir_ops xfs_dir2_ftype_ops = {
 
 	.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,
 };
@@ -288,7 +256,6 @@ static const struct xfs_dir_ops xfs_dir3_ops = {
 
 	.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..9169da84065a 100644
--- a/fs/xfs/libxfs/xfs_dir2.h
+++ b/fs/xfs/libxfs/xfs_dir2.h
@@ -49,8 +49,6 @@ struct xfs_dir_ops {
 		(*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 *
 		(*data_entry_p)(struct xfs_dir2_data_hdr *hdr);
 	struct xfs_dir2_data_unused *
-- 
2.20.1


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

* [PATCH 25/46] xfs: remove the data_dot_offset field in struct xfs_dir_ops
  2019-11-07 18:23 remove m_dirops v2 Christoph Hellwig
                   ` (23 preceding siblings ...)
  2019-11-07 18:23 ` [PATCH 24/46] xfs: remove the unused ->data_first_entry_p method Christoph Hellwig
@ 2019-11-07 18:23 ` Christoph Hellwig
  2019-11-08  0:38   ` Darrick J. Wong
  2019-11-07 18:23 ` [PATCH 26/46] xfs: remove the data_dotdot_offset " Christoph Hellwig
                   ` (20 subsequent siblings)
  45 siblings, 1 reply; 73+ messages in thread
From: Christoph Hellwig @ 2019-11-07 18:23 UTC (permalink / raw)
  To: linux-xfs

The data_dot_offset value is always equal to data_entry_offset given
that "." is always the first entry in the directory.

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

diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c
index 19343c65be91..54754eef2437 100644
--- a/fs/xfs/libxfs/xfs_da_format.c
+++ b/fs/xfs/libxfs/xfs_da_format.c
@@ -204,7 +204,6 @@ static const struct xfs_dir_ops xfs_dir2_ops = {
 	.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),
 	.data_dotdot_offset = sizeof(struct xfs_dir2_data_hdr) +
 				XFS_DIR2_DATA_ENTSIZE(1),
 	.data_first_offset =  sizeof(struct xfs_dir2_data_hdr) +
@@ -225,7 +224,6 @@ static const struct xfs_dir_ops xfs_dir2_ftype_ops = {
 	.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),
 	.data_dotdot_offset = sizeof(struct xfs_dir2_data_hdr) +
 				XFS_DIR3_DATA_ENTSIZE(1),
 	.data_first_offset =  sizeof(struct xfs_dir2_data_hdr) +
@@ -246,7 +244,6 @@ static const struct xfs_dir_ops xfs_dir3_ops = {
 	.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),
 	.data_dotdot_offset = sizeof(struct xfs_dir3_data_hdr) +
 				XFS_DIR3_DATA_ENTSIZE(1),
 	.data_first_offset =  sizeof(struct xfs_dir3_data_hdr) +
diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h
index 9169da84065a..94e8c40a7d19 100644
--- a/fs/xfs/libxfs/xfs_dir2.h
+++ b/fs/xfs/libxfs/xfs_dir2.h
@@ -40,7 +40,6 @@ struct xfs_dir_ops {
 	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;
diff --git a/fs/xfs/xfs_dir2_readdir.c b/fs/xfs/xfs_dir2_readdir.c
index e18045465455..39985ca6ae2d 100644
--- a/fs/xfs/xfs_dir2_readdir.c
+++ b/fs/xfs/xfs_dir2_readdir.c
@@ -70,13 +70,12 @@ xfs_dir2_sf_getdents(
 		return 0;
 
 	/*
-	 * Precalculate offsets for . and .. as we will always need them.
-	 *
-	 * XXX(hch): the second argument is sometimes 0 and sometimes
-	 * geo->datablk
+	 * Precalculate offsets for "." and ".." as we will always need them.
+	 * This relies on the fact that directories always start with the
+	 * entries for "." and "..".
 	 */
 	dot_offset = xfs_dir2_db_off_to_dataptr(geo, geo->datablk,
-						dp->d_ops->data_dot_offset);
+			dp->d_ops->data_entry_offset);
 	dotdot_offset = xfs_dir2_db_off_to_dataptr(geo, geo->datablk,
 						dp->d_ops->data_dotdot_offset);
 
-- 
2.20.1


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

* [PATCH 26/46] xfs: remove the data_dotdot_offset field in struct xfs_dir_ops
  2019-11-07 18:23 remove m_dirops v2 Christoph Hellwig
                   ` (24 preceding siblings ...)
  2019-11-07 18:23 ` [PATCH 25/46] xfs: remove the data_dot_offset field in struct xfs_dir_ops Christoph Hellwig
@ 2019-11-07 18:23 ` Christoph Hellwig
  2019-11-08  0:50   ` Darrick J. Wong
  2019-11-07 18:23 ` [PATCH 27/46] xfs: remove the ->data_dot_entry_p and ->data_dotdot_entry_p methods Christoph Hellwig
                   ` (19 subsequent siblings)
  45 siblings, 1 reply; 73+ messages in thread
From: Christoph Hellwig @ 2019-11-07 18:23 UTC (permalink / raw)
  To: linux-xfs

The data_dotdot_offset value is always equal to data_entry_offset plus
the fixed size of the "." entry.  Right now calculating that fixed size
requires an indirect call, but by the end of this series it will be
an inline function that can be constant folded.

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

diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c
index 54754eef2437..7b783b11790d 100644
--- a/fs/xfs/libxfs/xfs_da_format.c
+++ b/fs/xfs/libxfs/xfs_da_format.c
@@ -204,8 +204,6 @@ static const struct xfs_dir_ops xfs_dir2_ops = {
 	.data_entry_tag_p = xfs_dir2_data_entry_tag_p,
 	.data_bestfree_p = xfs_dir2_data_bestfree_p,
 
-	.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),
@@ -224,8 +222,6 @@ static const struct xfs_dir_ops xfs_dir2_ftype_ops = {
 	.data_entry_tag_p = xfs_dir3_data_entry_tag_p,
 	.data_bestfree_p = xfs_dir2_data_bestfree_p,
 
-	.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),
@@ -244,8 +240,6 @@ static const struct xfs_dir_ops xfs_dir3_ops = {
 	.data_entry_tag_p = xfs_dir3_data_entry_tag_p,
 	.data_bestfree_p = xfs_dir3_data_bestfree_p,
 
-	.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),
diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h
index 94e8c40a7d19..8b937993263d 100644
--- a/fs/xfs/libxfs/xfs_dir2.h
+++ b/fs/xfs/libxfs/xfs_dir2.h
@@ -40,7 +40,6 @@ struct xfs_dir_ops {
 	struct xfs_dir2_data_free *
 		(*data_bestfree_p)(struct xfs_dir2_data_hdr *hdr);
 
-	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/xfs_dir2_readdir.c b/fs/xfs/xfs_dir2_readdir.c
index 39985ca6ae2d..187bb51875c2 100644
--- a/fs/xfs/xfs_dir2_readdir.c
+++ b/fs/xfs/xfs_dir2_readdir.c
@@ -77,7 +77,8 @@ xfs_dir2_sf_getdents(
 	dot_offset = xfs_dir2_db_off_to_dataptr(geo, geo->datablk,
 			dp->d_ops->data_entry_offset);
 	dotdot_offset = xfs_dir2_db_off_to_dataptr(geo, geo->datablk,
-						dp->d_ops->data_dotdot_offset);
+			dp->d_ops->data_entry_offset +
+			dp->d_ops->data_entsize(sizeof(".") - 1));
 
 	/*
 	 * Put . entry unless we're starting past it.
-- 
2.20.1


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

* [PATCH 27/46] xfs: remove the ->data_dot_entry_p and ->data_dotdot_entry_p methods
  2019-11-07 18:23 remove m_dirops v2 Christoph Hellwig
                   ` (25 preceding siblings ...)
  2019-11-07 18:23 ` [PATCH 26/46] xfs: remove the data_dotdot_offset " Christoph Hellwig
@ 2019-11-07 18:23 ` Christoph Hellwig
  2019-11-08  0:49   ` Darrick J. Wong
  2019-11-07 18:23 ` [PATCH 28/46] xfs: remove the ->data_unused_p method Christoph Hellwig
                   ` (18 subsequent siblings)
  45 siblings, 1 reply; 73+ messages in thread
From: Christoph Hellwig @ 2019-11-07 18:23 UTC (permalink / raw)
  To: linux-xfs

The only user of the ->data_dot_entry_p and ->data_dotdot_entry_p
methods is the xfs_dir2_sf_to_block function that builds block format
directorys from a short form directory.  It already uses pointer
arithmetics with a offset variable to do so for the real entries in
the directory, so switch the generation of the . and .. entries to
the same scheme, and clean up some of the later pointer arithmetics
to use bp->b_addr directly as well and avoid some casts.

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 | 54 ++++++++++++++++------------------
 3 files changed, 26 insertions(+), 84 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c
index 7b783b11790d..711faff4aea2 100644
--- a/fs/xfs/libxfs/xfs_da_format.c
+++ b/fs/xfs/libxfs/xfs_da_format.c
@@ -111,52 +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_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_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_free *
 xfs_dir2_data_bestfree_p(struct xfs_dir2_data_hdr *hdr)
 {
@@ -209,8 +163,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_entry_p = xfs_dir2_data_entry_p,
 	.data_unused_p = xfs_dir2_data_unused_p,
 };
@@ -227,8 +179,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_entry_p = xfs_dir2_data_entry_p,
 	.data_unused_p = xfs_dir2_data_unused_p,
 };
@@ -245,8 +195,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_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 8b937993263d..8bfcf4c1b9c4 100644
--- a/fs/xfs/libxfs/xfs_dir2.h
+++ b/fs/xfs/libxfs/xfs_dir2.h
@@ -43,10 +43,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_entry_p)(struct xfs_dir2_data_hdr *hdr);
 	struct xfs_dir2_data_unused *
diff --git a/fs/xfs/libxfs/xfs_dir2_block.c b/fs/xfs/libxfs/xfs_dir2_block.c
index 6bc82a02b228..e7719356829d 100644
--- a/fs/xfs/libxfs/xfs_dir2_block.c
+++ b/fs/xfs/libxfs/xfs_dir2_block.c
@@ -1038,39 +1038,35 @@ xfs_dir2_leaf_to_block(
  */
 int						/* error */
 xfs_dir2_sf_to_block(
-	xfs_da_args_t		*args)		/* operation arguments */
+	struct xfs_da_args	*args)
 {
+	struct xfs_trans	*tp = args->trans;
+	struct xfs_inode	*dp = args->dp;
+	struct xfs_mount	*mp = dp->i_mount;
+	struct xfs_ifork	*ifp = XFS_IFORK_PTR(dp, XFS_DATA_FORK);
 	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 */
 	struct xfs_buf		*bp;		/* block buffer */
 	xfs_dir2_block_tail_t	*btp;		/* block tail pointer */
 	xfs_dir2_data_entry_t	*dep;		/* data entry pointer */
-	xfs_inode_t		*dp;		/* incore directory inode */
 	int			dummy;		/* trash */
 	xfs_dir2_data_unused_t	*dup;		/* unused entry pointer */
 	int			endoffset;	/* end of data objects */
 	int			error;		/* error return value */
 	int			i;		/* index */
-	xfs_mount_t		*mp;		/* filesystem mount point */
 	int			needlog;	/* need to log block header */
 	int			needscan;	/* need to scan block freespc */
 	int			newoffset;	/* offset from current entry */
-	int			offset;		/* target block offset */
+	unsigned int		offset = dp->d_ops->data_entry_offset;
 	xfs_dir2_sf_entry_t	*sfep;		/* sf entry pointer */
 	xfs_dir2_sf_hdr_t	*oldsfp;	/* old shortform header  */
 	xfs_dir2_sf_hdr_t	*sfp;		/* shortform header  */
 	__be16			*tagp;		/* end of data entry */
-	xfs_trans_t		*tp;		/* transaction pointer */
 	struct xfs_name		name;
-	struct xfs_ifork	*ifp;
 
 	trace_xfs_dir2_sf_to_block(args);
 
-	dp = args->dp;
-	tp = args->trans;
-	mp = dp->i_mount;
-	ifp = XFS_IFORK_PTR(dp, XFS_DATA_FORK);
 	ASSERT(ifp->if_flags & XFS_IFINLINE);
 	ASSERT(dp->i_d.di_size >= offsetof(struct xfs_dir2_sf_hdr, parent));
 
@@ -1139,35 +1135,37 @@ xfs_dir2_sf_to_block(
 			be16_to_cpu(dup->length), &needlog, &needscan);
 	if (error)
 		goto out_free;
+
 	/*
 	 * Create entry for .
 	 */
-	dep = dp->d_ops->data_dot_entry_p(hdr);
+	dep = bp->b_addr + offset;
 	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);
 	tagp = dp->d_ops->data_entry_tag_p(dep);
-	*tagp = cpu_to_be16((char *)dep - (char *)hdr);
+	*tagp = cpu_to_be16(offset);
 	xfs_dir2_data_log_entry(args, bp, dep);
 	blp[0].hashval = cpu_to_be32(xfs_dir_hash_dot);
-	blp[0].address = cpu_to_be32(xfs_dir2_byte_to_dataptr(
-				(char *)dep - (char *)hdr));
+	blp[0].address = cpu_to_be32(xfs_dir2_byte_to_dataptr(offset));
+	offset += dp->d_ops->data_entsize(dep->namelen);
+
 	/*
 	 * Create entry for ..
 	 */
-	dep = dp->d_ops->data_dotdot_entry_p(hdr);
+	dep = bp->b_addr + offset;
 	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);
 	tagp = dp->d_ops->data_entry_tag_p(dep);
-	*tagp = cpu_to_be16((char *)dep - (char *)hdr);
+	*tagp = cpu_to_be16(offset);
 	xfs_dir2_data_log_entry(args, bp, dep);
 	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;
+	blp[1].address = cpu_to_be32(xfs_dir2_byte_to_dataptr(offset));
+	offset += dp->d_ops->data_entsize(dep->namelen);
+
 	/*
 	 * Loop over existing entries, stuff them in.
 	 */
@@ -1176,6 +1174,7 @@ xfs_dir2_sf_to_block(
 		sfep = NULL;
 	else
 		sfep = xfs_dir2_sf_firstentry(sfp);
+
 	/*
 	 * Need to preserve the existing offset values in the sf directory.
 	 * Insert holes (unused entries) where necessary.
@@ -1192,11 +1191,10 @@ xfs_dir2_sf_to_block(
 		 * There should be a hole here, make one.
 		 */
 		if (offset < newoffset) {
-			dup = (xfs_dir2_data_unused_t *)((char *)hdr + offset);
+			dup = bp->b_addr + offset;
 			dup->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG);
 			dup->length = cpu_to_be16(newoffset - offset);
-			*xfs_dir2_data_unused_tag_p(dup) = cpu_to_be16(
-				((char *)dup - (char *)hdr));
+			*xfs_dir2_data_unused_tag_p(dup) = cpu_to_be16(offset);
 			xfs_dir2_data_log_unused(args, bp, dup);
 			xfs_dir2_data_freeinsert(hdr,
 						 dp->d_ops->data_bestfree_p(hdr),
@@ -1207,20 +1205,20 @@ xfs_dir2_sf_to_block(
 		/*
 		 * Copy a real entry.
 		 */
-		dep = (xfs_dir2_data_entry_t *)((char *)hdr + newoffset);
+		dep = bp->b_addr + 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));
 		memcpy(dep->name, sfep->name, dep->namelen);
 		tagp = dp->d_ops->data_entry_tag_p(dep);
-		*tagp = cpu_to_be16((char *)dep - (char *)hdr);
+		*tagp = cpu_to_be16(newoffset);
 		xfs_dir2_data_log_entry(args, bp, dep);
 		name.name = sfep->name;
 		name.len = sfep->namelen;
-		blp[2 + i].hashval = cpu_to_be32(mp->m_dirnameops->
-							hashname(&name));
-		blp[2 + i].address = cpu_to_be32(xfs_dir2_byte_to_dataptr(
-						 (char *)dep - (char *)hdr));
+		blp[2 + i].hashval =
+			cpu_to_be32(mp->m_dirnameops->hashname(&name));
+		blp[2 + i].address =
+			cpu_to_be32(xfs_dir2_byte_to_dataptr(newoffset));
 		offset = (int)((char *)(tagp + 1) - (char *)hdr);
 		if (++i == sfp->count)
 			sfep = NULL;
-- 
2.20.1


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

* [PATCH 28/46] xfs: remove the ->data_unused_p method
  2019-11-07 18:23 remove m_dirops v2 Christoph Hellwig
                   ` (26 preceding siblings ...)
  2019-11-07 18:23 ` [PATCH 27/46] xfs: remove the ->data_dot_entry_p and ->data_dotdot_entry_p methods Christoph Hellwig
@ 2019-11-07 18:23 ` Christoph Hellwig
  2019-11-08  0:51   ` Darrick J. Wong
  2019-11-07 18:23 ` [PATCH 29/46] xfs: cleanup xfs_dir2_block_getdents Christoph Hellwig
                   ` (17 subsequent siblings)
  45 siblings, 1 reply; 73+ messages in thread
From: Christoph Hellwig @ 2019-11-07 18:23 UTC (permalink / raw)
  To: linux-xfs

Replace the two users of the ->data_unused_p dir ops method with a
direct calculation using ->data_entry_offset, and clean them up a bit.
xfs_dir2_sf_to_block already had an offset variable containing the
value of ->data_entry_offset, which we are now reusing to make it
clear that the initial freespace entry is at the same place that
we later fill in the 1 entry, and in xfs_dir3_data_init the function
is cleaned up a bit to keep the initialization of fields of a given
structure close to each other, and to avoid a local variable.

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

diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c
index 711faff4aea2..347092ec28ab 100644
--- a/fs/xfs/libxfs/xfs_da_format.c
+++ b/fs/xfs/libxfs/xfs_da_format.c
@@ -130,13 +130,6 @@ xfs_dir2_data_entry_p(struct xfs_dir2_data_hdr *hdr)
 		((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)
 {
@@ -144,13 +137,6 @@ xfs_dir3_data_entry_p(struct xfs_dir2_data_hdr *hdr)
 		((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,
@@ -164,7 +150,6 @@ static const struct xfs_dir_ops xfs_dir2_ops = {
 	.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 = {
@@ -180,7 +165,6 @@ static const struct xfs_dir_ops xfs_dir2_ftype_ops = {
 	.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 = {
@@ -196,7 +180,6 @@ static const struct xfs_dir_ops xfs_dir3_ops = {
 	.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 8bfcf4c1b9c4..75aec05aae10 100644
--- a/fs/xfs/libxfs/xfs_dir2.h
+++ b/fs/xfs/libxfs/xfs_dir2.h
@@ -45,8 +45,6 @@ struct xfs_dir_ops {
 
 	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 e7719356829d..9061f378d52a 100644
--- a/fs/xfs/libxfs/xfs_dir2_block.c
+++ b/fs/xfs/libxfs/xfs_dir2_block.c
@@ -1112,7 +1112,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 = bp->b_addr + 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..3ecec8e1c5f6 100644
--- a/fs/xfs/libxfs/xfs_dir2_data.c
+++ b/fs/xfs/libxfs/xfs_dir2_data.c
@@ -631,24 +631,20 @@ xfs_dir2_data_freescan(
  */
 int						/* error */
 xfs_dir3_data_init(
-	xfs_da_args_t		*args,		/* directory operation args */
-	xfs_dir2_db_t		blkno,		/* logical dir block number */
-	struct xfs_buf		**bpp)		/* output block buffer */
+	struct xfs_da_args		*args,	/* directory operation args */
+	xfs_dir2_db_t			blkno,	/* logical dir block number */
+	struct xfs_buf			**bpp)	/* output block buffer */
 {
-	struct xfs_buf		*bp;		/* block buffer */
-	xfs_dir2_data_hdr_t	*hdr;		/* data block header */
-	xfs_inode_t		*dp;		/* incore directory inode */
-	xfs_dir2_data_unused_t	*dup;		/* unused entry pointer */
-	struct xfs_dir2_data_free *bf;
-	int			error;		/* error return value */
-	int			i;		/* bestfree index */
-	xfs_mount_t		*mp;		/* filesystem mount point */
-	xfs_trans_t		*tp;		/* transaction pointer */
-	int                     t;              /* temp */
-
-	dp = args->dp;
-	mp = dp->i_mount;
-	tp = args->trans;
+	struct xfs_trans		*tp = args->trans;
+	struct xfs_inode		*dp = args->dp;
+	struct xfs_mount		*mp = dp->i_mount;
+	struct xfs_buf			*bp;
+	struct xfs_dir2_data_hdr	*hdr;
+	struct xfs_dir2_data_unused	*dup;
+	struct xfs_dir2_data_free 	*bf;
+	int				error;
+	int				i;
+
 	/*
 	 * Get the buffer set up for the block.
 	 */
@@ -677,6 +673,8 @@ xfs_dir3_data_init(
 
 	bf = dp->d_ops->data_bestfree_p(hdr);
 	bf[0].offset = cpu_to_be16(dp->d_ops->data_entry_offset);
+	bf[0].length =
+		cpu_to_be16(args->geo->blksize - dp->d_ops->data_entry_offset);
 	for (i = 1; i < XFS_DIR2_DATA_FD_COUNT; i++) {
 		bf[i].length = 0;
 		bf[i].offset = 0;
@@ -685,13 +683,11 @@ xfs_dir3_data_init(
 	/*
 	 * Set up an unused entry for the block's body.
 	 */
-	dup = dp->d_ops->data_unused_p(hdr);
+	dup = bp->b_addr + 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;
-	bf[0].length = cpu_to_be16(t);
-	dup->length = cpu_to_be16(t);
+	dup->length = bf[0].length;
 	*xfs_dir2_data_unused_tag_p(dup) = cpu_to_be16((char *)dup - (char *)hdr);
+
 	/*
 	 * Log it and return it.
 	 */
-- 
2.20.1


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

* [PATCH 29/46] xfs: cleanup xfs_dir2_block_getdents
  2019-11-07 18:23 remove m_dirops v2 Christoph Hellwig
                   ` (27 preceding siblings ...)
  2019-11-07 18:23 ` [PATCH 28/46] xfs: remove the ->data_unused_p method Christoph Hellwig
@ 2019-11-07 18:23 ` Christoph Hellwig
  2019-11-08  0:52   ` Darrick J. Wong
  2019-11-07 18:23 ` [PATCH 30/46] xfs: cleanup xfs_dir2_leaf_getdents Christoph Hellwig
                   ` (16 subsequent siblings)
  45 siblings, 1 reply; 73+ messages in thread
From: Christoph Hellwig @ 2019-11-07 18:23 UTC (permalink / raw)
  To: linux-xfs

Use an offset as the main means for iteration, and only do pointer
arithmetics to find the data/unused entries.

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

diff --git a/fs/xfs/xfs_dir2_readdir.c b/fs/xfs/xfs_dir2_readdir.c
index 187bb51875c2..0d234b649d65 100644
--- a/fs/xfs/xfs_dir2_readdir.c
+++ b/fs/xfs/xfs_dir2_readdir.c
@@ -142,17 +142,14 @@ xfs_dir2_block_getdents(
 	struct dir_context	*ctx)
 {
 	struct xfs_inode	*dp = args->dp;	/* incore directory inode */
-	xfs_dir2_data_hdr_t	*hdr;		/* block header */
 	struct xfs_buf		*bp;		/* buffer for block */
-	xfs_dir2_data_entry_t	*dep;		/* block data entry */
-	xfs_dir2_data_unused_t	*dup;		/* block unused entry */
-	char			*endptr;	/* end of the data entries */
 	int			error;		/* error return value */
-	char			*ptr;		/* current data entry */
 	int			wantoff;	/* starting block offset */
 	xfs_off_t		cook;
 	struct xfs_da_geometry	*geo = args->geo;
 	int			lock_mode;
+	unsigned int		offset;
+	unsigned int		end;
 
 	/*
 	 * If the block number in the offset is out of range, we're done.
@@ -171,44 +168,39 @@ xfs_dir2_block_getdents(
 	 * We'll skip entries before this.
 	 */
 	wantoff = xfs_dir2_dataptr_to_off(geo, ctx->pos);
-	hdr = bp->b_addr;
 	xfs_dir3_data_check(dp, bp);
-	/*
-	 * Set up values for the loop.
-	 */
-	ptr = (char *)dp->d_ops->data_entry_p(hdr);
-	endptr = xfs_dir3_data_endp(geo, hdr);
 
 	/*
 	 * Loop over the data portion of the block.
 	 * Each object is a real entry (dep) or an unused one (dup).
 	 */
-	while (ptr < endptr) {
+	offset = dp->d_ops->data_entry_offset;
+	end = xfs_dir3_data_endp(geo, bp->b_addr) - bp->b_addr;
+	while (offset < end) {
+		struct xfs_dir2_data_unused	*dup = bp->b_addr + offset;
+		struct xfs_dir2_data_entry	*dep = bp->b_addr + offset;
 		uint8_t filetype;
 
-		dup = (xfs_dir2_data_unused_t *)ptr;
 		/*
 		 * Unused, skip it.
 		 */
 		if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) {
-			ptr += be16_to_cpu(dup->length);
+			offset += be16_to_cpu(dup->length);
 			continue;
 		}
 
-		dep = (xfs_dir2_data_entry_t *)ptr;
-
 		/*
 		 * Bump pointer for the next iteration.
 		 */
-		ptr += dp->d_ops->data_entsize(dep->namelen);
+		offset += dp->d_ops->data_entsize(dep->namelen);
+
 		/*
 		 * The entry is before the desired starting point, skip it.
 		 */
-		if ((char *)dep - (char *)hdr < wantoff)
+		if (offset < wantoff)
 			continue;
 
-		cook = xfs_dir2_db_off_to_dataptr(geo, geo->datablk,
-					    (char *)dep - (char *)hdr);
+		cook = xfs_dir2_db_off_to_dataptr(geo, geo->datablk, offset);
 
 		ctx->pos = cook & 0x7fffffff;
 		filetype = dp->d_ops->data_get_ftype(dep);
-- 
2.20.1


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

* [PATCH 30/46] xfs: cleanup xfs_dir2_leaf_getdents
  2019-11-07 18:23 remove m_dirops v2 Christoph Hellwig
                   ` (28 preceding siblings ...)
  2019-11-07 18:23 ` [PATCH 29/46] xfs: cleanup xfs_dir2_block_getdents Christoph Hellwig
@ 2019-11-07 18:23 ` Christoph Hellwig
  2019-11-07 22:41   ` Darrick J. Wong
  2019-11-07 18:23 ` [PATCH 31/46] xfs: cleanup xchk_dir_rec Christoph Hellwig
                   ` (15 subsequent siblings)
  45 siblings, 1 reply; 73+ messages in thread
From: Christoph Hellwig @ 2019-11-07 18:23 UTC (permalink / raw)
  To: linux-xfs

Use an offset as the main means for iteration, and only do pointer
arithmetics to find the data/unused entries.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 fs/xfs/xfs_dir2_readdir.c | 34 +++++++++++++++++-----------------
 1 file changed, 17 insertions(+), 17 deletions(-)

diff --git a/fs/xfs/xfs_dir2_readdir.c b/fs/xfs/xfs_dir2_readdir.c
index 0d234b649d65..c4314e9e3dd8 100644
--- a/fs/xfs/xfs_dir2_readdir.c
+++ b/fs/xfs/xfs_dir2_readdir.c
@@ -351,13 +351,13 @@ xfs_dir2_leaf_getdents(
 	xfs_dir2_data_hdr_t	*hdr;		/* data block header */
 	xfs_dir2_data_entry_t	*dep;		/* data entry */
 	xfs_dir2_data_unused_t	*dup;		/* unused entry */
-	char			*ptr = NULL;	/* pointer to current data */
 	struct xfs_da_geometry	*geo = args->geo;
 	xfs_dablk_t		rablk = 0;	/* current readahead block */
 	xfs_dir2_off_t		curoff;		/* current overall offset */
 	int			length;		/* temporary length value */
 	int			byteoff;	/* offset in current block */
 	int			lock_mode;
+	unsigned int		offset = 0;
 	int			error = 0;	/* error return value */
 
 	/*
@@ -384,7 +384,7 @@ xfs_dir2_leaf_getdents(
 		 * If we have no buffer, or we're off the end of the
 		 * current buffer, need to get another one.
 		 */
-		if (!bp || ptr >= (char *)bp->b_addr + geo->blksize) {
+		if (!bp || offset + geo->blksize) {
 			if (bp) {
 				xfs_trans_brelse(args->trans, bp);
 				bp = NULL;
@@ -402,7 +402,7 @@ xfs_dir2_leaf_getdents(
 			/*
 			 * Find our position in the block.
 			 */
-			ptr = (char *)dp->d_ops->data_entry_p(hdr);
+			offset = dp->d_ops->data_entry_offset;
 			byteoff = xfs_dir2_byte_to_off(geo, curoff);
 			/*
 			 * Skip past the header.
@@ -413,20 +413,20 @@ xfs_dir2_leaf_getdents(
 			 * Skip past entries until we reach our offset.
 			 */
 			else {
-				while ((char *)ptr - (char *)hdr < byteoff) {
-					dup = (xfs_dir2_data_unused_t *)ptr;
+				while (offset < byteoff) {
+					dup = bp->b_addr + offset;
 
 					if (be16_to_cpu(dup->freetag)
 						  == XFS_DIR2_DATA_FREE_TAG) {
 
 						length = be16_to_cpu(dup->length);
-						ptr += length;
+						offset += length;
 						continue;
 					}
-					dep = (xfs_dir2_data_entry_t *)ptr;
+					dep = bp->b_addr + offset;
 					length =
 					   dp->d_ops->data_entsize(dep->namelen);
-					ptr += length;
+					offset += length;
 				}
 				/*
 				 * Now set our real offset.
@@ -434,28 +434,28 @@ xfs_dir2_leaf_getdents(
 				curoff =
 					xfs_dir2_db_off_to_byte(geo,
 					    xfs_dir2_byte_to_db(geo, curoff),
-					    (char *)ptr - (char *)hdr);
-				if (ptr >= (char *)hdr + geo->blksize) {
+					    offset);
+				if (offset >= geo->blksize)
 					continue;
-				}
 			}
 		}
+
 		/*
-		 * We have a pointer to an entry.
-		 * Is it a live one?
+		 * We have a pointer to an entry.  Is it a live one?
 		 */
-		dup = (xfs_dir2_data_unused_t *)ptr;
+		dup = bp->b_addr + offset;
+
 		/*
 		 * No, it's unused, skip over it.
 		 */
 		if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) {
 			length = be16_to_cpu(dup->length);
-			ptr += length;
+			offset += length;
 			curoff += length;
 			continue;
 		}
 
-		dep = (xfs_dir2_data_entry_t *)ptr;
+		dep = bp->b_addr + offset;
 		length = dp->d_ops->data_entsize(dep->namelen);
 		filetype = dp->d_ops->data_get_ftype(dep);
 
@@ -474,7 +474,7 @@ xfs_dir2_leaf_getdents(
 		/*
 		 * Advance to next entry in the block.
 		 */
-		ptr += length;
+		offset += length;
 		curoff += length;
 		/* bufsize may have just been a guess; don't go negative */
 		bufsize = bufsize > length ? bufsize - length : 0;
-- 
2.20.1


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

* [PATCH 31/46] xfs: cleanup xchk_dir_rec
  2019-11-07 18:23 remove m_dirops v2 Christoph Hellwig
                   ` (29 preceding siblings ...)
  2019-11-07 18:23 ` [PATCH 30/46] xfs: cleanup xfs_dir2_leaf_getdents Christoph Hellwig
@ 2019-11-07 18:23 ` Christoph Hellwig
  2019-11-08  0:57   ` Darrick J. Wong
  2019-11-07 18:23 ` [PATCH 32/46] xfs: cleanup xchk_directory_data_bestfree Christoph Hellwig
                   ` (14 subsequent siblings)
  45 siblings, 1 reply; 73+ messages in thread
From: Christoph Hellwig @ 2019-11-07 18:23 UTC (permalink / raw)
  To: linux-xfs

Use an offset as the main means for iteration, and only do pointer
arithmetics to find the data/unused entries.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 fs/xfs/scrub/dir.c | 28 ++++++++++++++--------------
 1 file changed, 14 insertions(+), 14 deletions(-)

diff --git a/fs/xfs/scrub/dir.c b/fs/xfs/scrub/dir.c
index bb08a1cbe523..501d60c9b09a 100644
--- a/fs/xfs/scrub/dir.c
+++ b/fs/xfs/scrub/dir.c
@@ -187,7 +187,8 @@ xchk_dir_rec(
 	struct xfs_dir2_data_entry	*dent;
 	struct xfs_buf			*bp;
 	struct xfs_dir2_leaf_entry	*ent;
-	char				*p, *endp;
+	void				*endp;
+	unsigned int			offset;
 	xfs_ino_t			ino;
 	xfs_dablk_t			rec_bno;
 	xfs_dir2_db_t			db;
@@ -237,32 +238,31 @@ xchk_dir_rec(
 	if (ds->sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)
 		goto out_relse;
 
-	dent = (struct xfs_dir2_data_entry *)(((char *)bp->b_addr) + off);
+	dent = 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);
+	offset = 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);
 		goto out_relse;
 	}
-	while (p < endp) {
-		struct xfs_dir2_data_entry	*dep;
-		struct xfs_dir2_data_unused	*dup;
+	for (;;) {
+		struct xfs_dir2_data_entry	*dep = bp->b_addr + offset;
+		struct xfs_dir2_data_unused	*dup = bp->b_addr + offset;
+	
+		if (offset >= endp - bp->b_addr) {
+			xchk_fblock_set_corrupt(ds->sc, XFS_DATA_FORK, rec_bno);
+			goto out_relse;
+		}
 
-		dup = (struct xfs_dir2_data_unused *)p;
 		if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) {
-			p += be16_to_cpu(dup->length);
+			offset += be16_to_cpu(dup->length);
 			continue;
 		}
-		dep = (struct xfs_dir2_data_entry *)p;
 		if (dep == dent)
 			break;
-		p += mp->m_dir_inode_ops->data_entsize(dep->namelen);
-	}
-	if (p >= endp) {
-		xchk_fblock_set_corrupt(ds->sc, XFS_DATA_FORK, rec_bno);
-		goto out_relse;
+		offset += mp->m_dir_inode_ops->data_entsize(dep->namelen);
 	}
 
 	/* Retrieve the entry, sanity check it, and compare hashes. */
-- 
2.20.1


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

* [PATCH 32/46] xfs: cleanup xchk_directory_data_bestfree
  2019-11-07 18:23 remove m_dirops v2 Christoph Hellwig
                   ` (30 preceding siblings ...)
  2019-11-07 18:23 ` [PATCH 31/46] xfs: cleanup xchk_dir_rec Christoph Hellwig
@ 2019-11-07 18:23 ` Christoph Hellwig
  2019-11-08  0:57   ` Darrick J. Wong
  2019-11-07 18:23 ` [PATCH 33/46] xfs: cleanup xfs_dir2_block_to_sf Christoph Hellwig
                   ` (13 subsequent siblings)
  45 siblings, 1 reply; 73+ messages in thread
From: Christoph Hellwig @ 2019-11-07 18:23 UTC (permalink / raw)
  To: linux-xfs

Use an offset as the main means for iteration, and only do pointer
arithmetics to find the data/unused entries.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 fs/xfs/scrub/dir.c | 31 +++++++++++++++----------------
 1 file changed, 15 insertions(+), 16 deletions(-)

diff --git a/fs/xfs/scrub/dir.c b/fs/xfs/scrub/dir.c
index 501d60c9b09a..4cef21b9d336 100644
--- a/fs/xfs/scrub/dir.c
+++ b/fs/xfs/scrub/dir.c
@@ -327,14 +327,13 @@ xchk_directory_data_bestfree(
 	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;
 	unsigned int			nr_bestfrees = 0;
 	unsigned int			nr_frees = 0;
 	unsigned int			smallest_bestfree;
 	int				newlen;
-	int				offset;
+	unsigned int			offset;
+	unsigned int			end;
 	int				error;
 
 	d_ops = sc->ip->d_ops;
@@ -368,13 +367,13 @@ xchk_directory_data_bestfree(
 			xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk);
 			goto out_buf;
 		}
-		dup = (struct xfs_dir2_data_unused *)(bp->b_addr + offset);
+		dup = bp->b_addr + offset;
 		tag = be16_to_cpu(*xfs_dir2_data_unused_tag_p(dup));
 
 		/* bestfree doesn't match the entry it points at? */
 		if (dup->freetag != cpu_to_be16(XFS_DIR2_DATA_FREE_TAG) ||
 		    be16_to_cpu(dup->length) != be16_to_cpu(dfp->length) ||
-		    tag != ((char *)dup - (char *)bp->b_addr)) {
+		    tag != offset) {
 			xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk);
 			goto out_buf;
 		}
@@ -390,30 +389,30 @@ xchk_directory_data_bestfree(
 	}
 
 	/* Make sure the bestfrees are actually the best free spaces. */
-	ptr = (char *)d_ops->data_entry_p(bp->b_addr);
-	endptr = xfs_dir3_data_endp(mp->m_dir_geo, bp->b_addr);
+	offset = d_ops->data_entry_offset;
+	end = xfs_dir3_data_endp(mp->m_dir_geo, bp->b_addr) - bp->b_addr;
 
 	/* Iterate the entries, stopping when we hit or go past the end. */
-	while (ptr < endptr) {
-		dup = (struct xfs_dir2_data_unused *)ptr;
+	while (offset < end) {
+		dup = bp->b_addr + offset;
+
 		/* Skip real entries */
 		if (dup->freetag != cpu_to_be16(XFS_DIR2_DATA_FREE_TAG)) {
-			struct xfs_dir2_data_entry	*dep;
+			struct xfs_dir2_data_entry *dep = bp->b_addr + offset;
 
-			dep = (struct xfs_dir2_data_entry *)ptr;
 			newlen = d_ops->data_entsize(dep->namelen);
 			if (newlen <= 0) {
 				xchk_fblock_set_corrupt(sc, XFS_DATA_FORK,
 						lblk);
 				goto out_buf;
 			}
-			ptr += newlen;
+			offset += newlen;
 			continue;
 		}
 
 		/* Spot check this free entry */
 		tag = be16_to_cpu(*xfs_dir2_data_unused_tag_p(dup));
-		if (tag != ((char *)dup - (char *)bp->b_addr)) {
+		if (tag != offset) {
 			xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk);
 			goto out_buf;
 		}
@@ -432,13 +431,13 @@ xchk_directory_data_bestfree(
 			xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk);
 			goto out_buf;
 		}
-		ptr += newlen;
-		if (ptr <= endptr)
+		offset += newlen;
+		if (offset <= end)
 			nr_frees++;
 	}
 
 	/* We're required to fill all the space. */
-	if (ptr != endptr)
+	if (offset != end)
 		xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk);
 
 	/* Did we see at least as many free slots as there are bestfrees? */
-- 
2.20.1


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

* [PATCH 33/46] xfs: cleanup xfs_dir2_block_to_sf
  2019-11-07 18:23 remove m_dirops v2 Christoph Hellwig
                   ` (31 preceding siblings ...)
  2019-11-07 18:23 ` [PATCH 32/46] xfs: cleanup xchk_directory_data_bestfree Christoph Hellwig
@ 2019-11-07 18:23 ` Christoph Hellwig
  2019-11-08  0:59   ` Darrick J. Wong
  2019-11-07 18:23 ` [PATCH 34/46] xfs: cleanup xfs_dir2_data_freescan_int Christoph Hellwig
                   ` (12 subsequent siblings)
  45 siblings, 1 reply; 73+ messages in thread
From: Christoph Hellwig @ 2019-11-07 18:23 UTC (permalink / raw)
  To: linux-xfs

Use an offset as the main means for iteration, and only do pointer
arithmetics to find the data/unused entries.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 fs/xfs/libxfs/xfs_dir2_sf.c | 68 ++++++++++++++-----------------------
 1 file changed, 25 insertions(+), 43 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_dir2_sf.c b/fs/xfs/libxfs/xfs_dir2_sf.c
index 39a537c61b04..a1aed589dc8c 100644
--- a/fs/xfs/libxfs/xfs_dir2_sf.c
+++ b/fs/xfs/libxfs/xfs_dir2_sf.c
@@ -255,64 +255,48 @@ xfs_dir2_block_sfsize(
  */
 int						/* error */
 xfs_dir2_block_to_sf(
-	xfs_da_args_t		*args,		/* operation arguments */
+	struct xfs_da_args	*args,		/* operation arguments */
 	struct xfs_buf		*bp,
 	int			size,		/* shortform directory size */
-	xfs_dir2_sf_hdr_t	*sfhp)		/* shortform directory hdr */
+	struct xfs_dir2_sf_hdr	*sfhp)		/* shortform directory hdr */
 {
-	xfs_dir2_data_hdr_t	*hdr;		/* block header */
-	xfs_dir2_data_entry_t	*dep;		/* data entry pointer */
-	xfs_inode_t		*dp;		/* incore directory inode */
-	xfs_dir2_data_unused_t	*dup;		/* unused data pointer */
-	char			*endptr;	/* end of data entries */
+	struct xfs_inode	*dp = args->dp;
+	struct xfs_mount	*mp = dp->i_mount;
 	int			error;		/* error return value */
 	int			logflags;	/* inode logging flags */
-	xfs_mount_t		*mp;		/* filesystem mount point */
-	char			*ptr;		/* current data pointer */
-	xfs_dir2_sf_entry_t	*sfep;		/* shortform entry */
-	xfs_dir2_sf_hdr_t	*sfp;		/* shortform directory header */
-	xfs_dir2_sf_hdr_t	*dst;		/* temporary data buffer */
+	struct xfs_dir2_sf_entry *sfep;		/* shortform entry */
+	struct xfs_dir2_sf_hdr	*sfp;		/* shortform directory header */
+	unsigned int		offset = dp->d_ops->data_entry_offset;
+	unsigned int		end;
 
 	trace_xfs_dir2_block_to_sf(args);
 
-	dp = args->dp;
-	mp = dp->i_mount;
-
 	/*
-	 * allocate a temporary destination buffer the size of the inode
-	 * to format the data into. Once we have formatted the data, we
-	 * can free the block and copy the formatted data into the inode literal
-	 * area.
+	 * Allocate a temporary destination buffer the size of the inode to
+	 * format the data into.  Once we have formatted the data, we can free
+	 * the block and copy the formatted data into the inode literal area.
 	 */
-	dst = kmem_alloc(mp->m_sb.sb_inodesize, 0);
-	hdr = bp->b_addr;
-
-	/*
-	 * Copy the header into the newly allocate local space.
-	 */
-	sfp = (xfs_dir2_sf_hdr_t *)dst;
+	sfp = kmem_alloc(mp->m_sb.sb_inodesize, 0);
 	memcpy(sfp, sfhp, xfs_dir2_sf_hdr_size(sfhp->i8count));
 
 	/*
-	 * Set up to loop over the block's entries.
+	 * Loop over the active and unused entries.  Stop when we reach the
+	 * leaf/tail portion of the block.
 	 */
-	ptr = (char *)dp->d_ops->data_entry_p(hdr);
-	endptr = xfs_dir3_data_endp(args->geo, hdr);
+	end = xfs_dir3_data_endp(args->geo, bp->b_addr) - bp->b_addr;
 	sfep = xfs_dir2_sf_firstentry(sfp);
-	/*
-	 * Loop over the active and unused entries.
-	 * Stop when we reach the leaf/tail portion of the block.
-	 */
-	while (ptr < endptr) {
+	while (offset < end) {
+		struct xfs_dir2_data_unused	*dup = bp->b_addr + offset;
+		struct xfs_dir2_data_entry	*dep = bp->b_addr + offset;
+
 		/*
 		 * If it's unused, just skip over it.
 		 */
-		dup = (xfs_dir2_data_unused_t *)ptr;
 		if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) {
-			ptr += be16_to_cpu(dup->length);
+			offset += be16_to_cpu(dup->length);
 			continue;
 		}
-		dep = (xfs_dir2_data_entry_t *)ptr;
+
 		/*
 		 * Skip .
 		 */
@@ -330,9 +314,7 @@ xfs_dir2_block_to_sf(
 		 */
 		else {
 			sfep->namelen = dep->namelen;
-			xfs_dir2_sf_put_offset(sfep,
-				(xfs_dir2_data_aoff_t)
-				((char *)dep - (char *)hdr));
+			xfs_dir2_sf_put_offset(sfep, offset);
 			memcpy(sfep->name, dep->name, dep->namelen);
 			xfs_dir2_sf_put_ino(mp, sfp, sfep,
 					      be64_to_cpu(dep->inumber));
@@ -341,7 +323,7 @@ xfs_dir2_block_to_sf(
 
 			sfep = xfs_dir2_sf_nextentry(mp, sfp, sfep);
 		}
-		ptr += dp->d_ops->data_entsize(dep->namelen);
+		offset += dp->d_ops->data_entsize(dep->namelen);
 	}
 	ASSERT((char *)sfep - (char *)sfp == size);
 
@@ -360,7 +342,7 @@ xfs_dir2_block_to_sf(
 	 * Convert the inode to local format and copy the data in.
 	 */
 	ASSERT(dp->i_df.if_bytes == 0);
-	xfs_init_local_fork(dp, XFS_DATA_FORK, dst, size);
+	xfs_init_local_fork(dp, XFS_DATA_FORK, sfp, size);
 	dp->i_d.di_format = XFS_DINODE_FMT_LOCAL;
 	dp->i_d.di_size = size;
 
@@ -368,7 +350,7 @@ xfs_dir2_block_to_sf(
 	xfs_dir2_sf_check(args);
 out:
 	xfs_trans_log_inode(args->trans, dp, logflags);
-	kmem_free(dst);
+	kmem_free(sfp);
 	return error;
 }
 
-- 
2.20.1


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

* [PATCH 34/46] xfs: cleanup xfs_dir2_data_freescan_int
  2019-11-07 18:23 remove m_dirops v2 Christoph Hellwig
                   ` (32 preceding siblings ...)
  2019-11-07 18:23 ` [PATCH 33/46] xfs: cleanup xfs_dir2_block_to_sf Christoph Hellwig
@ 2019-11-07 18:23 ` Christoph Hellwig
  2019-11-08  1:00   ` Darrick J. Wong
  2019-11-07 18:23 ` [PATCH 35/46] xfs: cleanup __xfs_dir3_data_check Christoph Hellwig
                   ` (11 subsequent siblings)
  45 siblings, 1 reply; 73+ messages in thread
From: Christoph Hellwig @ 2019-11-07 18:23 UTC (permalink / raw)
  To: linux-xfs

Use an offset as the main means for iteration, and only do pointer
arithmetics to find the data/unused entries.

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

diff --git a/fs/xfs/libxfs/xfs_dir2_data.c b/fs/xfs/libxfs/xfs_dir2_data.c
index 3ecec8e1c5f6..50e3fa092ff9 100644
--- a/fs/xfs/libxfs/xfs_dir2_data.c
+++ b/fs/xfs/libxfs/xfs_dir2_data.c
@@ -562,16 +562,15 @@ xfs_dir2_data_freeremove(
  */
 void
 xfs_dir2_data_freescan_int(
-	struct xfs_da_geometry	*geo,
-	const struct xfs_dir_ops *ops,
-	struct xfs_dir2_data_hdr *hdr,
-	int			*loghead)
+	struct xfs_da_geometry		*geo,
+	const struct xfs_dir_ops	*ops,
+	struct xfs_dir2_data_hdr	*hdr,
+	int				*loghead)
 {
-	xfs_dir2_data_entry_t	*dep;		/* active data entry */
-	xfs_dir2_data_unused_t	*dup;		/* unused data entry */
-	struct xfs_dir2_data_free *bf;
-	char			*endp;		/* end of block's data */
-	char			*p;		/* current entry pointer */
+	struct xfs_dir2_data_free	*bf = ops->data_bestfree_p(hdr);
+	void				*addr = hdr;
+	unsigned int			offset = ops->data_entry_offset;
+	unsigned int			end;
 
 	ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) ||
 	       hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC) ||
@@ -581,37 +580,30 @@ xfs_dir2_data_freescan_int(
 	/*
 	 * Start by clearing the table.
 	 */
-	bf = ops->data_bestfree_p(hdr);
 	memset(bf, 0, sizeof(*bf) * XFS_DIR2_DATA_FD_COUNT);
 	*loghead = 1;
-	/*
-	 * Set up pointers.
-	 */
-	p = (char *)ops->data_entry_p(hdr);
-	endp = xfs_dir3_data_endp(geo, hdr);
-	/*
-	 * Loop over the block's entries.
-	 */
-	while (p < endp) {
-		dup = (xfs_dir2_data_unused_t *)p;
+
+	end = xfs_dir3_data_endp(geo, addr) - addr;
+	while (offset < end) {
+		struct xfs_dir2_data_unused	*dup = addr + offset;
+		struct xfs_dir2_data_entry	*dep = addr + offset;
+
 		/*
 		 * If it's a free entry, insert it.
 		 */
 		if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) {
-			ASSERT((char *)dup - (char *)hdr ==
+			ASSERT(offset ==
 			       be16_to_cpu(*xfs_dir2_data_unused_tag_p(dup)));
 			xfs_dir2_data_freeinsert(hdr, bf, dup, loghead);
-			p += be16_to_cpu(dup->length);
+			offset += be16_to_cpu(dup->length);
+			continue;
 		}
+
 		/*
 		 * For active entries, check their tags and skip them.
 		 */
-		else {
-			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);
-		}
+		ASSERT(offset == be16_to_cpu(*ops->data_entry_tag_p(dep)));
+		offset += ops->data_entsize(dep->namelen);
 	}
 }
 
-- 
2.20.1


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

* [PATCH 35/46] xfs: cleanup __xfs_dir3_data_check
  2019-11-07 18:23 remove m_dirops v2 Christoph Hellwig
                   ` (33 preceding siblings ...)
  2019-11-07 18:23 ` [PATCH 34/46] xfs: cleanup xfs_dir2_data_freescan_int Christoph Hellwig
@ 2019-11-07 18:23 ` Christoph Hellwig
  2019-11-08  1:01   ` Darrick J. Wong
  2019-11-07 18:24 ` [PATCH 36/46] xfs: remove the now unused ->data_entry_p method Christoph Hellwig
                   ` (10 subsequent siblings)
  45 siblings, 1 reply; 73+ messages in thread
From: Christoph Hellwig @ 2019-11-07 18:23 UTC (permalink / raw)
  To: linux-xfs

Use an offset as the main means for iteration, and only do pointer
arithmetics to find the data/unused entries.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 fs/xfs/libxfs/xfs_dir2_data.c | 59 ++++++++++++++++++++---------------
 1 file changed, 33 insertions(+), 26 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_dir2_data.c b/fs/xfs/libxfs/xfs_dir2_data.c
index 50e3fa092ff9..8c729270f9f1 100644
--- a/fs/xfs/libxfs/xfs_dir2_data.c
+++ b/fs/xfs/libxfs/xfs_dir2_data.c
@@ -23,6 +23,22 @@ static xfs_failaddr_t xfs_dir2_data_freefind_verify(
 		struct xfs_dir2_data_unused *dup,
 		struct xfs_dir2_data_free **bf_ent);
 
+/*
+ * The number of leaf entries is limited by the size of the block and the amount
+ * of space used by the data entries.  We don't know how much space is used by
+ * the data entries yet, so just ensure that the count falls somewhere inside
+ * the block right now.
+ */
+static inline unsigned int
+xfs_dir2_data_max_leaf_entries(
+	const struct xfs_dir_ops	*ops,
+	struct xfs_da_geometry		*geo)
+{
+	return (geo->blksize - sizeof(struct xfs_dir2_block_tail) -
+		ops->data_entry_offset) /
+			sizeof(struct xfs_dir2_leaf_entry);
+}
+
 /*
  * Check the consistency of the data block.
  * The input can also be a block-format directory.
@@ -38,23 +54,20 @@ __xfs_dir3_data_check(
 	xfs_dir2_block_tail_t	*btp=NULL;	/* block tail */
 	int			count;		/* count of entries found */
 	xfs_dir2_data_hdr_t	*hdr;		/* data block header */
-	xfs_dir2_data_entry_t	*dep;		/* data entry */
 	xfs_dir2_data_free_t	*dfp;		/* bestfree entry */
-	xfs_dir2_data_unused_t	*dup;		/* unused entry */
-	char			*endp;		/* end of useful data */
+	void			*endp;		/* end of useful data */
 	int			freeseen;	/* mask of bestfrees seen */
 	xfs_dahash_t		hash;		/* hash of current name */
 	int			i;		/* leaf index */
 	int			lastfree;	/* last entry was unused */
 	xfs_dir2_leaf_entry_t	*lep=NULL;	/* block leaf entries */
 	struct xfs_mount	*mp = bp->b_mount;
-	char			*p;		/* current data position */
 	int			stale;		/* count of stale leaves */
 	struct xfs_name		name;
+	unsigned int		offset;
+	unsigned int		end;
 	const struct xfs_dir_ops *ops;
-	struct xfs_da_geometry	*geo;
-
-	geo = mp->m_dir_geo;
+	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
@@ -71,7 +84,7 @@ __xfs_dir3_data_check(
 		return __this_address;
 
 	hdr = bp->b_addr;
-	p = (char *)ops->data_entry_p(hdr);
+	offset = ops->data_entry_offset;
 
 	switch (hdr->magic) {
 	case cpu_to_be32(XFS_DIR3_BLOCK_MAGIC):
@@ -79,15 +92,8 @@ __xfs_dir3_data_check(
 		btp = xfs_dir2_block_tail_p(geo, hdr);
 		lep = xfs_dir2_block_leaf_p(btp);
 
-		/*
-		 * The number of leaf entries is limited by the size of the
-		 * block and the amount of space used by the data entries.
-		 * We don't know how much space is used by the data entries yet,
-		 * so just ensure that the count falls somewhere inside the
-		 * block right now.
-		 */
 		if (be32_to_cpu(btp->count) >=
-		    ((char *)btp - p) / sizeof(struct xfs_dir2_leaf_entry))
+		    xfs_dir2_data_max_leaf_entries(ops, geo))
 			return __this_address;
 		break;
 	case cpu_to_be32(XFS_DIR3_DATA_MAGIC):
@@ -99,6 +105,7 @@ __xfs_dir3_data_check(
 	endp = xfs_dir3_data_endp(geo, hdr);
 	if (!endp)
 		return __this_address;
+	end = endp - bp->b_addr;
 
 	/*
 	 * Account for zero bestfree entries.
@@ -128,8 +135,10 @@ __xfs_dir3_data_check(
 	/*
 	 * Loop over the data/unused entries.
 	 */
-	while (p < endp) {
-		dup = (xfs_dir2_data_unused_t *)p;
+	while (offset < end) {
+		struct xfs_dir2_data_unused	*dup = bp->b_addr + offset;
+		struct xfs_dir2_data_entry	*dep = bp->b_addr + offset;
+
 		/*
 		 * If it's unused, look for the space in the bestfree table.
 		 * If we find it, account for that, else make sure it
@@ -140,10 +149,10 @@ __xfs_dir3_data_check(
 
 			if (lastfree != 0)
 				return __this_address;
-			if (endp < p + be16_to_cpu(dup->length))
+			if (offset + be16_to_cpu(dup->length) > end)
 				return __this_address;
 			if (be16_to_cpu(*xfs_dir2_data_unused_tag_p(dup)) !=
-			    (char *)dup - (char *)hdr)
+			    offset)
 				return __this_address;
 			fa = xfs_dir2_data_freefind_verify(hdr, bf, dup, &dfp);
 			if (fa)
@@ -158,7 +167,7 @@ __xfs_dir3_data_check(
 				    be16_to_cpu(bf[2].length))
 					return __this_address;
 			}
-			p += be16_to_cpu(dup->length);
+			offset += be16_to_cpu(dup->length);
 			lastfree = 1;
 			continue;
 		}
@@ -168,15 +177,13 @@ __xfs_dir3_data_check(
 		 * in the leaf section of the block.
 		 * The linear search is crude but this is DEBUG code.
 		 */
-		dep = (xfs_dir2_data_entry_t *)p;
 		if (dep->namelen == 0)
 			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 (offset + ops->data_entsize(dep->namelen) > end)
 			return __this_address;
-		if (be16_to_cpu(*ops->data_entry_tag_p(dep)) !=
-		    (char *)dep - (char *)hdr)
+		if (be16_to_cpu(*ops->data_entry_tag_p(dep)) != offset)
 			return __this_address;
 		if (ops->data_get_ftype(dep) >= XFS_DIR3_FT_MAX)
 			return __this_address;
@@ -198,7 +205,7 @@ __xfs_dir3_data_check(
 			if (i >= be32_to_cpu(btp->count))
 				return __this_address;
 		}
-		p += ops->data_entsize(dep->namelen);
+		offset += ops->data_entsize(dep->namelen);
 	}
 	/*
 	 * Need to have seen all the entries and all the bestfree slots.
-- 
2.20.1


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

* [PATCH 36/46] xfs: remove the now unused ->data_entry_p method
  2019-11-07 18:23 remove m_dirops v2 Christoph Hellwig
                   ` (34 preceding siblings ...)
  2019-11-07 18:23 ` [PATCH 35/46] xfs: cleanup __xfs_dir3_data_check Christoph Hellwig
@ 2019-11-07 18:24 ` Christoph Hellwig
  2019-11-08  1:02   ` Darrick J. Wong
  2019-11-07 18:24 ` [PATCH 37/46] xfs: replace xfs_dir3_data_endp with xfs_dir3_data_end_offset Christoph Hellwig
                   ` (9 subsequent siblings)
  45 siblings, 1 reply; 73+ messages in thread
From: Christoph Hellwig @ 2019-11-07 18:24 UTC (permalink / raw)
  To: linux-xfs

Now that all users use the data_entry_offset field this method is
unused and can be removed.

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

diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c
index 347092ec28ab..e70cc54d99e1 100644
--- a/fs/xfs/libxfs/xfs_da_format.c
+++ b/fs/xfs/libxfs/xfs_da_format.c
@@ -123,20 +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_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 const struct xfs_dir_ops xfs_dir2_ops = {
 	.data_entsize = xfs_dir2_data_entsize,
 	.data_get_ftype = xfs_dir2_data_get_ftype,
@@ -148,8 +134,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,
 };
 
 static const struct xfs_dir_ops xfs_dir2_ftype_ops = {
@@ -163,8 +147,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,
 };
 
 static const struct xfs_dir_ops xfs_dir3_ops = {
@@ -178,8 +160,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,
 };
 
 /*
diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h
index 75aec05aae10..a160f2d4ff37 100644
--- a/fs/xfs/libxfs/xfs_dir2.h
+++ b/fs/xfs/libxfs/xfs_dir2.h
@@ -42,9 +42,6 @@ struct xfs_dir_ops {
 
 	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);
 };
 
 extern const struct xfs_dir_ops *
-- 
2.20.1


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

* [PATCH 37/46] xfs: replace xfs_dir3_data_endp with xfs_dir3_data_end_offset
  2019-11-07 18:23 remove m_dirops v2 Christoph Hellwig
                   ` (35 preceding siblings ...)
  2019-11-07 18:24 ` [PATCH 36/46] xfs: remove the now unused ->data_entry_p method Christoph Hellwig
@ 2019-11-07 18:24 ` Christoph Hellwig
  2019-11-08  1:04   ` Darrick J. Wong
  2019-11-07 18:24 ` [PATCH 38/46] xfs: devirtualize ->data_entsize Christoph Hellwig
                   ` (8 subsequent siblings)
  45 siblings, 1 reply; 73+ messages in thread
From: Christoph Hellwig @ 2019-11-07 18:24 UTC (permalink / raw)
  To: linux-xfs

All the callers really want an offset into the buffer, so adopt
the helper to return that instead.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 fs/xfs/libxfs/xfs_dir2.h      |  2 +-
 fs/xfs/libxfs/xfs_dir2_data.c | 29 +++++++++++++++--------------
 fs/xfs/libxfs/xfs_dir2_sf.c   |  2 +-
 fs/xfs/scrub/dir.c            | 10 +++++-----
 fs/xfs/xfs_dir2_readdir.c     |  2 +-
 5 files changed, 23 insertions(+), 22 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h
index a160f2d4ff37..3a4b98d4973d 100644
--- a/fs/xfs/libxfs/xfs_dir2.h
+++ b/fs/xfs/libxfs/xfs_dir2.h
@@ -266,7 +266,7 @@ xfs_dir2_leaf_tail_p(struct xfs_da_geometry *geo, struct xfs_dir2_leaf *lp)
 #define XFS_READDIR_BUFSIZE	(32768)
 
 unsigned char xfs_dir3_get_dtype(struct xfs_mount *mp, uint8_t filetype);
-void *xfs_dir3_data_endp(struct xfs_da_geometry *geo,
+unsigned int xfs_dir3_data_end_offset(struct xfs_da_geometry *geo,
 		struct xfs_dir2_data_hdr *hdr);
 bool xfs_dir2_namecheck(const void *name, size_t length);
 
diff --git a/fs/xfs/libxfs/xfs_dir2_data.c b/fs/xfs/libxfs/xfs_dir2_data.c
index 8c729270f9f1..f5fa8b9187b0 100644
--- a/fs/xfs/libxfs/xfs_dir2_data.c
+++ b/fs/xfs/libxfs/xfs_dir2_data.c
@@ -55,7 +55,6 @@ __xfs_dir3_data_check(
 	int			count;		/* count of entries found */
 	xfs_dir2_data_hdr_t	*hdr;		/* data block header */
 	xfs_dir2_data_free_t	*dfp;		/* bestfree entry */
-	void			*endp;		/* end of useful data */
 	int			freeseen;	/* mask of bestfrees seen */
 	xfs_dahash_t		hash;		/* hash of current name */
 	int			i;		/* leaf index */
@@ -102,10 +101,9 @@ __xfs_dir3_data_check(
 	default:
 		return __this_address;
 	}
-	endp = xfs_dir3_data_endp(geo, hdr);
-	if (!endp)
+	end = xfs_dir3_data_end_offset(geo, hdr);
+	if (!end)
 		return __this_address;
-	end = endp - bp->b_addr;
 
 	/*
 	 * Account for zero bestfree entries.
@@ -590,7 +588,7 @@ xfs_dir2_data_freescan_int(
 	memset(bf, 0, sizeof(*bf) * XFS_DIR2_DATA_FD_COUNT);
 	*loghead = 1;
 
-	end = xfs_dir3_data_endp(geo, addr) - addr;
+	end = xfs_dir3_data_end_offset(geo, addr);
 	while (offset < end) {
 		struct xfs_dir2_data_unused	*dup = addr + offset;
 		struct xfs_dir2_data_entry	*dep = addr + offset;
@@ -784,11 +782,11 @@ xfs_dir2_data_make_free(
 {
 	xfs_dir2_data_hdr_t	*hdr;		/* data block pointer */
 	xfs_dir2_data_free_t	*dfp;		/* bestfree pointer */
-	char			*endptr;	/* end of data area */
 	int			needscan;	/* need to regen bestfree */
 	xfs_dir2_data_unused_t	*newdup;	/* new unused entry */
 	xfs_dir2_data_unused_t	*postdup;	/* unused entry after us */
 	xfs_dir2_data_unused_t	*prevdup;	/* unused entry before us */
+	unsigned int		end;
 	struct xfs_dir2_data_free *bf;
 
 	hdr = bp->b_addr;
@@ -796,8 +794,8 @@ xfs_dir2_data_make_free(
 	/*
 	 * Figure out where the end of the data area is.
 	 */
-	endptr = xfs_dir3_data_endp(args->geo, hdr);
-	ASSERT(endptr != NULL);
+	end = xfs_dir3_data_end_offset(args->geo, hdr);
+	ASSERT(end != 0);
 
 	/*
 	 * If this isn't the start of the block, then back up to
@@ -816,7 +814,7 @@ xfs_dir2_data_make_free(
 	 * If this isn't the end of the block, see if the entry after
 	 * us is free.
 	 */
-	if ((char *)hdr + offset + len < endptr) {
+	if (offset + len < end) {
 		postdup =
 			(xfs_dir2_data_unused_t *)((char *)hdr + offset + len);
 		if (be16_to_cpu(postdup->freetag) != XFS_DIR2_DATA_FREE_TAG)
@@ -1144,19 +1142,22 @@ xfs_dir2_data_use_free(
 }
 
 /* Find the end of the entry data in a data/block format dir block. */
-void *
-xfs_dir3_data_endp(
+unsigned int
+xfs_dir3_data_end_offset(
 	struct xfs_da_geometry		*geo,
 	struct xfs_dir2_data_hdr	*hdr)
 {
+	void				*p;
+
 	switch (hdr->magic) {
 	case cpu_to_be32(XFS_DIR3_BLOCK_MAGIC):
 	case cpu_to_be32(XFS_DIR2_BLOCK_MAGIC):
-		return xfs_dir2_block_leaf_p(xfs_dir2_block_tail_p(geo, hdr));
+		p = xfs_dir2_block_leaf_p(xfs_dir2_block_tail_p(geo, hdr));
+		return p - (void *)hdr;
 	case cpu_to_be32(XFS_DIR3_DATA_MAGIC):
 	case cpu_to_be32(XFS_DIR2_DATA_MAGIC):
-		return (char *)hdr + geo->blksize;
+		return geo->blksize;
 	default:
-		return NULL;
+		return 0;
 	}
 }
diff --git a/fs/xfs/libxfs/xfs_dir2_sf.c b/fs/xfs/libxfs/xfs_dir2_sf.c
index a1aed589dc8c..bb6491a3c473 100644
--- a/fs/xfs/libxfs/xfs_dir2_sf.c
+++ b/fs/xfs/libxfs/xfs_dir2_sf.c
@@ -283,7 +283,7 @@ xfs_dir2_block_to_sf(
 	 * Loop over the active and unused entries.  Stop when we reach the
 	 * leaf/tail portion of the block.
 	 */
-	end = xfs_dir3_data_endp(args->geo, bp->b_addr) - bp->b_addr;
+	end = xfs_dir3_data_end_offset(args->geo, bp->b_addr);
 	sfep = xfs_dir2_sf_firstentry(sfp);
 	while (offset < end) {
 		struct xfs_dir2_data_unused	*dup = bp->b_addr + offset;
diff --git a/fs/xfs/scrub/dir.c b/fs/xfs/scrub/dir.c
index 4cef21b9d336..7f03f0fb178a 100644
--- a/fs/xfs/scrub/dir.c
+++ b/fs/xfs/scrub/dir.c
@@ -187,7 +187,7 @@ xchk_dir_rec(
 	struct xfs_dir2_data_entry	*dent;
 	struct xfs_buf			*bp;
 	struct xfs_dir2_leaf_entry	*ent;
-	void				*endp;
+	unsigned int			end;
 	unsigned int			offset;
 	xfs_ino_t			ino;
 	xfs_dablk_t			rec_bno;
@@ -242,8 +242,8 @@ xchk_dir_rec(
 
 	/* Make sure we got a real directory entry. */
 	offset = mp->m_dir_inode_ops->data_entry_offset;
-	endp = xfs_dir3_data_endp(mp->m_dir_geo, bp->b_addr);
-	if (!endp) {
+	end = xfs_dir3_data_end_offset(mp->m_dir_geo, bp->b_addr);
+	if (!end) {
 		xchk_fblock_set_corrupt(ds->sc, XFS_DATA_FORK, rec_bno);
 		goto out_relse;
 	}
@@ -251,7 +251,7 @@ xchk_dir_rec(
 		struct xfs_dir2_data_entry	*dep = bp->b_addr + offset;
 		struct xfs_dir2_data_unused	*dup = bp->b_addr + offset;
 	
-		if (offset >= endp - bp->b_addr) {
+		if (offset >= end) {
 			xchk_fblock_set_corrupt(ds->sc, XFS_DATA_FORK, rec_bno);
 			goto out_relse;
 		}
@@ -390,7 +390,7 @@ xchk_directory_data_bestfree(
 
 	/* Make sure the bestfrees are actually the best free spaces. */
 	offset = d_ops->data_entry_offset;
-	end = xfs_dir3_data_endp(mp->m_dir_geo, bp->b_addr) - bp->b_addr;
+	end = xfs_dir3_data_end_offset(mp->m_dir_geo, bp->b_addr);
 
 	/* Iterate the entries, stopping when we hit or go past the end. */
 	while (offset < end) {
diff --git a/fs/xfs/xfs_dir2_readdir.c b/fs/xfs/xfs_dir2_readdir.c
index c4314e9e3dd8..6d229aa93d01 100644
--- a/fs/xfs/xfs_dir2_readdir.c
+++ b/fs/xfs/xfs_dir2_readdir.c
@@ -175,7 +175,7 @@ xfs_dir2_block_getdents(
 	 * Each object is a real entry (dep) or an unused one (dup).
 	 */
 	offset = dp->d_ops->data_entry_offset;
-	end = xfs_dir3_data_endp(geo, bp->b_addr) - bp->b_addr;
+	end = xfs_dir3_data_end_offset(geo, bp->b_addr);
 	while (offset < end) {
 		struct xfs_dir2_data_unused	*dup = bp->b_addr + offset;
 		struct xfs_dir2_data_entry	*dep = bp->b_addr + offset;
-- 
2.20.1


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

* [PATCH 38/46] xfs: devirtualize ->data_entsize
  2019-11-07 18:23 remove m_dirops v2 Christoph Hellwig
                   ` (36 preceding siblings ...)
  2019-11-07 18:24 ` [PATCH 37/46] xfs: replace xfs_dir3_data_endp with xfs_dir3_data_end_offset Christoph Hellwig
@ 2019-11-07 18:24 ` Christoph Hellwig
  2019-11-07 18:24 ` [PATCH 39/46] xfs: devirtualize ->data_entry_tag_p Christoph Hellwig
                   ` (7 subsequent siblings)
  45 siblings, 0 replies; 73+ messages in thread
From: Christoph Hellwig @ 2019-11-07 18:24 UTC (permalink / raw)
  To: linux-xfs; +Cc: Darrick J . Wong

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>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 fs/xfs/libxfs/xfs_da_format.c  | 22 ++++++++--------------
 fs/xfs/libxfs/xfs_dir2.h       |  3 +--
 fs/xfs/libxfs/xfs_dir2_block.c |  9 +++++----
 fs/xfs/libxfs/xfs_dir2_data.c  | 14 +++++++-------
 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      | 11 ++++++-----
 10 files changed, 45 insertions(+), 46 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c
index e70cc54d99e1..e4498bd0d6c0 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,
@@ -137,7 +133,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,
@@ -150,7 +145,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 3a4b98d4973d..f717b1cdb208 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);
@@ -85,7 +84,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 9061f378d52a..a83fcf4ac35c 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.
 	 */
@@ -1149,7 +1150,7 @@ xfs_dir2_sf_to_block(
 	xfs_dir2_data_log_entry(args, bp, dep);
 	blp[0].hashval = cpu_to_be32(xfs_dir_hash_dot);
 	blp[0].address = cpu_to_be32(xfs_dir2_byte_to_dataptr(offset));
-	offset += dp->d_ops->data_entsize(dep->namelen);
+	offset += xfs_dir2_data_entsize(mp, dep->namelen);
 
 	/*
 	 * Create entry for ..
@@ -1164,7 +1165,7 @@ xfs_dir2_sf_to_block(
 	xfs_dir2_data_log_entry(args, bp, dep);
 	blp[1].hashval = cpu_to_be32(xfs_dir_hash_dotdot);
 	blp[1].address = cpu_to_be32(xfs_dir2_byte_to_dataptr(offset));
-	offset += dp->d_ops->data_entsize(dep->namelen);
+	offset += xfs_dir2_data_entsize(mp, dep->namelen);
 
 	/*
 	 * 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 f5fa8b9187b0..830dfd9edfda 100644
--- a/fs/xfs/libxfs/xfs_dir2_data.c
+++ b/fs/xfs/libxfs/xfs_dir2_data.c
@@ -13,6 +13,7 @@
 #include "xfs_mount.h"
 #include "xfs_inode.h"
 #include "xfs_dir2.h"
+#include "xfs_dir2_priv.h"
 #include "xfs_error.h"
 #include "xfs_trans.h"
 #include "xfs_buf_item.h"
@@ -179,7 +180,7 @@ __xfs_dir3_data_check(
 			return __this_address;
 		if (xfs_dir_ino_validate(mp, be64_to_cpu(dep->inumber)))
 			return __this_address;
-		if (offset + ops->data_entsize(dep->namelen) > end)
+		if (offset + xfs_dir2_data_entsize(mp, dep->namelen) > end)
 			return __this_address;
 		if (be16_to_cpu(*ops->data_entry_tag_p(dep)) != offset)
 			return __this_address;
@@ -203,7 +204,7 @@ __xfs_dir3_data_check(
 			if (i >= be32_to_cpu(btp->count))
 				return __this_address;
 		}
-		offset += ops->data_entsize(dep->namelen);
+		offset += xfs_dir2_data_entsize(mp, dep->namelen);
 	}
 	/*
 	 * Need to have seen all the entries and all the bestfree slots.
@@ -567,7 +568,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 +589,7 @@ xfs_dir2_data_freescan_int(
 	memset(bf, 0, sizeof(*bf) * XFS_DIR2_DATA_FD_COUNT);
 	*loghead = 1;
 
-	end = xfs_dir3_data_end_offset(geo, addr);
+	end = xfs_dir3_data_end_offset(mp->m_dir_geo, addr);
 	while (offset < end) {
 		struct xfs_dir2_data_unused	*dup = addr + offset;
 		struct xfs_dir2_data_entry	*dep = addr + offset;
@@ -608,7 +609,7 @@ xfs_dir2_data_freescan_int(
 		 * For active entries, check their tags and skip them.
 		 */
 		ASSERT(offset == be16_to_cpu(*ops->data_entry_tag_p(dep)));
-		offset += ops->data_entsize(dep->namelen);
+		offset += xfs_dir2_data_entsize(mp, dep->namelen);
 	}
 }
 
@@ -618,8 +619,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 bbbd7b96678a..dd7b4bd8ed61 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
@@ -1397,7 +1397,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 7b0de42c2c77..f07ac23a2e2f 100644
--- a/fs/xfs/libxfs/xfs_dir2_node.c
+++ b/fs/xfs/libxfs/xfs_dir2_node.c
@@ -666,7 +666,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.
 	 */
@@ -1320,7 +1320,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.
@@ -1913,7 +1914,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 b49f745f1bc3..c60b8663f754 100644
--- a/fs/xfs/libxfs/xfs_dir2_priv.h
+++ b/fs/xfs/libxfs/xfs_dir2_priv.h
@@ -57,6 +57,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 bb6491a3c473..a41715c9b061 100644
--- a/fs/xfs/libxfs/xfs_dir2_sf.c
+++ b/fs/xfs/libxfs/xfs_dir2_sf.c
@@ -323,7 +323,7 @@ xfs_dir2_block_to_sf(
 
 			sfep = xfs_dir2_sf_nextentry(mp, sfp, sfep);
 		}
-		offset += dp->d_ops->data_entsize(dep->namelen);
+		offset += xfs_dir2_data_entsize(mp, dep->namelen);
 	}
 	ASSERT((char *)sfep - (char *)sfp == size);
 
@@ -540,10 +540,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);
@@ -615,7 +615,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;
@@ -628,7 +628,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);
 	}
 	/*
@@ -693,7 +693,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);
@@ -793,7 +793,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 7f03f0fb178a..11d1429a69e4 100644
--- a/fs/xfs/scrub/dir.c
+++ b/fs/xfs/scrub/dir.c
@@ -262,7 +262,7 @@ xchk_dir_rec(
 		}
 		if (dep == dent)
 			break;
-		offset += mp->m_dir_inode_ops->data_entsize(dep->namelen);
+		offset += xfs_dir2_data_entsize(mp, dep->namelen);
 	}
 
 	/* Retrieve the entry, sanity check it, and compare hashes. */
@@ -400,7 +400,7 @@ xchk_directory_data_bestfree(
 		if (dup->freetag != cpu_to_be16(XFS_DIR2_DATA_FREE_TAG)) {
 			struct xfs_dir2_data_entry *dep = bp->b_addr + offset;
 
-			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 6d229aa93d01..a52f0931b6af 100644
--- a/fs/xfs/xfs_dir2_readdir.c
+++ b/fs/xfs/xfs_dir2_readdir.c
@@ -78,7 +78,7 @@ xfs_dir2_sf_getdents(
 			dp->d_ops->data_entry_offset);
 	dotdot_offset = xfs_dir2_db_off_to_dataptr(geo, geo->datablk,
 			dp->d_ops->data_entry_offset +
-			dp->d_ops->data_entsize(sizeof(".") - 1));
+			xfs_dir2_data_entsize(mp, sizeof(".") - 1));
 
 	/*
 	 * Put . entry unless we're starting past it.
@@ -192,7 +192,7 @@ xfs_dir2_block_getdents(
 		/*
 		 * Bump pointer for the next iteration.
 		 */
-		offset += dp->d_ops->data_entsize(dep->namelen);
+		offset += xfs_dir2_data_entsize(dp->i_mount, dep->namelen);
 
 		/*
 		 * The entry is before the desired starting point, skip it.
@@ -347,6 +347,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 */
@@ -424,8 +425,8 @@ xfs_dir2_leaf_getdents(
 						continue;
 					}
 					dep = bp->b_addr + offset;
-					length =
-					   dp->d_ops->data_entsize(dep->namelen);
+					length = xfs_dir2_data_entsize(mp,
+							dep->namelen);
 					offset += length;
 				}
 				/*
@@ -456,7 +457,7 @@ xfs_dir2_leaf_getdents(
 		}
 
 		dep = bp->b_addr + offset;
-		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] 73+ messages in thread

* [PATCH 39/46] xfs: devirtualize ->data_entry_tag_p
  2019-11-07 18:23 remove m_dirops v2 Christoph Hellwig
                   ` (37 preceding siblings ...)
  2019-11-07 18:24 ` [PATCH 38/46] xfs: devirtualize ->data_entsize Christoph Hellwig
@ 2019-11-07 18:24 ` Christoph Hellwig
  2019-11-07 18:24 ` [PATCH 40/46] xfs: move the dir2 data block fixed offsets to struct xfs_da_geometry Christoph Hellwig
                   ` (6 subsequent siblings)
  45 siblings, 0 replies; 73+ messages in thread
From: Christoph Hellwig @ 2019-11-07 18:24 UTC (permalink / raw)
  To: linux-xfs; +Cc: Darrick J . Wong

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>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 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 e4498bd0d6c0..483f4ab6abb8 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_first_offset =  sizeof(struct xfs_dir2_data_hdr) +
@@ -135,7 +115,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_first_offset =  sizeof(struct xfs_dir2_data_hdr) +
@@ -147,7 +126,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_first_offset =  sizeof(struct xfs_dir3_data_hdr) +
diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h
index f717b1cdb208..3f46954e9370 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 a83fcf4ac35c..35eda4d18cd8 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.
@@ -1145,7 +1145,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(offset);
 	xfs_dir2_data_log_entry(args, bp, dep);
 	blp[0].hashval = cpu_to_be32(xfs_dir_hash_dot);
@@ -1160,7 +1160,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(offset);
 	xfs_dir2_data_log_entry(args, bp, dep);
 	blp[1].hashval = cpu_to_be32(xfs_dir_hash_dotdot);
@@ -1211,7 +1211,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(newoffset);
 		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 830dfd9edfda..3504b230ba1d 100644
--- a/fs/xfs/libxfs/xfs_dir2_data.c
+++ b/fs/xfs/libxfs/xfs_dir2_data.c
@@ -18,12 +18,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));
+}
+
 /*
  * The number of leaf entries is limited by the size of the block and the amount
  * of space used by the data entries.  We don't know how much space is used by
@@ -182,7 +195,7 @@ __xfs_dir3_data_check(
 			return __this_address;
 		if (offset + xfs_dir2_data_entsize(mp, dep->namelen) > end)
 			return __this_address;
-		if (be16_to_cpu(*ops->data_entry_tag_p(dep)) != offset)
+		if (be16_to_cpu(*xfs_dir2_data_entry_tag_p(mp, dep)) != offset)
 			return __this_address;
 		if (ops->data_get_ftype(dep) >= XFS_DIR3_FT_MAX)
 			return __this_address;
@@ -608,7 +621,8 @@ xfs_dir2_data_freescan_int(
 		/*
 		 * For active entries, check their tags and skip them.
 		 */
-		ASSERT(offset == be16_to_cpu(*ops->data_entry_tag_p(dep)));
+		ASSERT(offset ==
+		       be16_to_cpu(*xfs_dir2_data_entry_tag_p(mp, dep)));
 		offset += xfs_dir2_data_entsize(mp, dep->namelen);
 	}
 }
@@ -703,6 +717,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) ||
@@ -711,7 +726,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 dd7b4bd8ed61..4b6d590c5856 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 f07ac23a2e2f..00f3440bcd83 100644
--- a/fs/xfs/libxfs/xfs_dir2_node.c
+++ b/fs/xfs/libxfs/xfs_dir2_node.c
@@ -1972,7 +1972,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 c60b8663f754..a6c3fb3a2f7b 100644
--- a/fs/xfs/libxfs/xfs_dir2_priv.h
+++ b/fs/xfs/libxfs/xfs_dir2_priv.h
@@ -58,6 +58,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 11d1429a69e4..2b9822ead835 100644
--- a/fs/xfs/scrub/dir.c
+++ b/fs/xfs/scrub/dir.c
@@ -268,7 +268,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] 73+ messages in thread

* [PATCH 40/46] xfs: move the dir2 data block fixed offsets to struct xfs_da_geometry
  2019-11-07 18:23 remove m_dirops v2 Christoph Hellwig
                   ` (38 preceding siblings ...)
  2019-11-07 18:24 ` [PATCH 39/46] xfs: devirtualize ->data_entry_tag_p Christoph Hellwig
@ 2019-11-07 18:24 ` Christoph Hellwig
  2019-11-07 18:24 ` [PATCH 41/46] xfs: cleanup xfs_dir2_data_entsize Christoph Hellwig
                   ` (5 subsequent siblings)
  45 siblings, 0 replies; 73+ messages in thread
From: Christoph Hellwig @ 2019-11-07 18:24 UTC (permalink / raw)
  To: linux-xfs; +Cc: Darrick J . Wong

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

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 fs/xfs/libxfs/xfs_da_btree.h   |  3 +++
 fs/xfs/libxfs/xfs_da_format.c  | 15 ---------------
 fs/xfs/libxfs/xfs_dir2.c       |  8 ++++++++
 fs/xfs/libxfs/xfs_dir2.h       |  3 ---
 fs/xfs/libxfs/xfs_dir2_block.c |  5 +++--
 fs/xfs/libxfs/xfs_dir2_data.c  | 25 ++++++++++++-------------
 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             | 15 ++++++++-------
 fs/xfs/xfs_dir2_readdir.c      | 10 +++++-----
 11 files changed, 67 insertions(+), 79 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_da_btree.h b/fs/xfs/libxfs/xfs_da_btree.h
index 40110acf9f8a..4ac2cc87c28f 100644
--- a/fs/xfs/libxfs/xfs_da_btree.h
+++ b/fs/xfs/libxfs/xfs_da_btree.h
@@ -32,6 +32,9 @@ struct xfs_da_geometry {
 	unsigned 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_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 483f4ab6abb8..0e35e613fbf3 100644
--- a/fs/xfs/libxfs/xfs_da_format.c
+++ b/fs/xfs/libxfs/xfs_da_format.c
@@ -105,33 +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_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_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_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 77a297e7d91c..eccffe7a5ae0 100644
--- a/fs/xfs/libxfs/xfs_dir2.c
+++ b/fs/xfs/libxfs/xfs_dir2.c
@@ -126,16 +126,24 @@ 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 =
+				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 =
+				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_first_offset = dageo->data_entry_offset +
+			xfs_dir2_data_entsize(mp, 1) +
+			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 3f46954e9370..830c70a20761 100644
--- a/fs/xfs/libxfs/xfs_dir2.h
+++ b/fs/xfs/libxfs/xfs_dir2.h
@@ -37,9 +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_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 35eda4d18cd8..9529a000838f 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) {
@@ -1045,6 +1045,7 @@ xfs_dir2_sf_to_block(
 	struct xfs_inode	*dp = args->dp;
 	struct xfs_mount	*mp = dp->i_mount;
 	struct xfs_ifork	*ifp = XFS_IFORK_PTR(dp, XFS_DATA_FORK);
+	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 */
@@ -1059,7 +1060,7 @@ xfs_dir2_sf_to_block(
 	int			needlog;	/* need to log block header */
 	int			needscan;	/* need to scan block freespc */
 	int			newoffset;	/* offset from current entry */
-	unsigned int		offset = dp->d_ops->data_entry_offset;
+	unsigned int		offset = geo->data_entry_offset;
 	xfs_dir2_sf_entry_t	*sfep;		/* sf entry pointer */
 	xfs_dir2_sf_hdr_t	*oldsfp;	/* old shortform header  */
 	xfs_dir2_sf_hdr_t	*sfp;		/* shortform header  */
diff --git a/fs/xfs/libxfs/xfs_dir2_data.c b/fs/xfs/libxfs/xfs_dir2_data.c
index 3504b230ba1d..c1a843f6a8da 100644
--- a/fs/xfs/libxfs/xfs_dir2_data.c
+++ b/fs/xfs/libxfs/xfs_dir2_data.c
@@ -45,11 +45,10 @@ xfs_dir2_data_entry_tag_p(
  */
 static inline unsigned int
 xfs_dir2_data_max_leaf_entries(
-	const struct xfs_dir_ops	*ops,
 	struct xfs_da_geometry		*geo)
 {
 	return (geo->blksize - sizeof(struct xfs_dir2_block_tail) -
-		ops->data_entry_offset) /
+		geo->data_entry_offset) /
 			sizeof(struct xfs_dir2_leaf_entry);
 }
 
@@ -97,7 +96,7 @@ __xfs_dir3_data_check(
 		return __this_address;
 
 	hdr = bp->b_addr;
-	offset = ops->data_entry_offset;
+	offset = geo->data_entry_offset;
 
 	switch (hdr->magic) {
 	case cpu_to_be32(XFS_DIR3_BLOCK_MAGIC):
@@ -106,7 +105,7 @@ __xfs_dir3_data_check(
 		lep = xfs_dir2_block_leaf_p(btp);
 
 		if (be32_to_cpu(btp->count) >=
-		    xfs_dir2_data_max_leaf_entries(ops, geo))
+		    xfs_dir2_data_max_leaf_entries(geo))
 			return __this_address;
 		break;
 	case cpu_to_be32(XFS_DIR3_DATA_MAGIC):
@@ -586,9 +585,10 @@ xfs_dir2_data_freescan_int(
 	struct xfs_dir2_data_hdr	*hdr,
 	int				*loghead)
 {
+	struct xfs_da_geometry		*geo = mp->m_dir_geo;
 	struct xfs_dir2_data_free	*bf = ops->data_bestfree_p(hdr);
 	void				*addr = hdr;
-	unsigned int			offset = ops->data_entry_offset;
+	unsigned int			offset = geo->data_entry_offset;
 	unsigned int			end;
 
 	ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) ||
@@ -602,7 +602,7 @@ xfs_dir2_data_freescan_int(
 	memset(bf, 0, sizeof(*bf) * XFS_DIR2_DATA_FD_COUNT);
 	*loghead = 1;
 
-	end = xfs_dir3_data_end_offset(mp->m_dir_geo, addr);
+	end = xfs_dir3_data_end_offset(geo, addr);
 	while (offset < end) {
 		struct xfs_dir2_data_unused	*dup = addr + offset;
 		struct xfs_dir2_data_entry	*dep = addr + offset;
@@ -649,6 +649,7 @@ xfs_dir3_data_init(
 	struct xfs_trans		*tp = args->trans;
 	struct xfs_inode		*dp = args->dp;
 	struct xfs_mount		*mp = dp->i_mount;
+	struct xfs_da_geometry		*geo = args->geo;
 	struct xfs_buf			*bp;
 	struct xfs_dir2_data_hdr	*hdr;
 	struct xfs_dir2_data_unused	*dup;
@@ -683,9 +684,8 @@ 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].length =
-		cpu_to_be16(args->geo->blksize - dp->d_ops->data_entry_offset);
+	bf[0].offset = cpu_to_be16(geo->data_entry_offset);
+	bf[0].length = cpu_to_be16(geo->blksize - geo->data_entry_offset);
 	for (i = 1; i < XFS_DIR2_DATA_FD_COUNT; i++) {
 		bf[i].length = 0;
 		bf[i].offset = 0;
@@ -694,7 +694,7 @@ xfs_dir3_data_init(
 	/*
 	 * Set up an unused entry for the block's body.
 	 */
-	dup = bp->b_addr + dp->d_ops->data_entry_offset;
+	dup = bp->b_addr + geo->data_entry_offset;
 	dup->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG);
 	dup->length = bf[0].length;
 	*xfs_dir2_data_unused_tag_p(dup) = cpu_to_be16((char *)dup - (char *)hdr);
@@ -747,8 +747,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);
 }
 
 /*
@@ -816,7 +815,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 4b6d590c5856..2b327d1937f4 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) {
 		xfs_buf_corruption_error(lbp);
@@ -1430,8 +1431,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
@@ -1473,7 +1474,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);
@@ -1594,6 +1595,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 */
@@ -1607,13 +1609,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
 {
@@ -1623,7 +1625,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 00f3440bcd83..8c7af28cea80 100644
--- a/fs/xfs/libxfs/xfs_dir2_node.c
+++ b/fs/xfs/libxfs/xfs_dir2_node.c
@@ -1263,6 +1263,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 */
@@ -1293,9 +1294,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);
 
 	/*
@@ -1346,9 +1347,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;
@@ -1358,22 +1358,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.
 			 */
@@ -1405,9 +1403,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 a41715c9b061..b5ac27442f9a 100644
--- a/fs/xfs/libxfs/xfs_dir2_sf.c
+++ b/fs/xfs/libxfs/xfs_dir2_sf.c
@@ -266,7 +266,7 @@ xfs_dir2_block_to_sf(
 	int			logflags;	/* inode logging flags */
 	struct xfs_dir2_sf_entry *sfep;		/* shortform entry */
 	struct xfs_dir2_sf_hdr	*sfp;		/* shortform directory header */
-	unsigned int		offset = dp->d_ops->data_entry_offset;
+	unsigned int		offset = args->geo->data_entry_offset;
 	unsigned int		end;
 
 	trace_xfs_dir2_block_to_sf(args);
@@ -538,7 +538,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];
@@ -616,7 +616,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;
 	/*
@@ -681,7 +681,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;
 
@@ -714,7 +714,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;
@@ -725,11 +724,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;
@@ -750,7 +744,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 2b9822ead835..5e8599d0613c 100644
--- a/fs/xfs/scrub/dir.c
+++ b/fs/xfs/scrub/dir.c
@@ -184,6 +184,7 @@ xchk_dir_rec(
 	struct xfs_da_state_blk		*blk = &ds->state->path.blk[level];
 	struct xfs_mount		*mp = ds->state->mp;
 	struct xfs_inode		*dp = ds->dargs.dp;
+	struct xfs_da_geometry		*geo = mp->m_dir_geo;
 	struct xfs_dir2_data_entry	*dent;
 	struct xfs_buf			*bp;
 	struct xfs_dir2_leaf_entry	*ent;
@@ -217,11 +218,11 @@ xchk_dir_rec(
 		return 0;
 
 	/* Find the directory entry's location. */
-	db = xfs_dir2_dataptr_to_db(mp->m_dir_geo, ptr);
-	off = xfs_dir2_dataptr_to_off(mp->m_dir_geo, ptr);
-	rec_bno = xfs_dir2_db_to_da(mp->m_dir_geo, db);
+	db = xfs_dir2_dataptr_to_db(geo, ptr);
+	off = xfs_dir2_dataptr_to_off(geo, ptr);
+	rec_bno = xfs_dir2_db_to_da(geo, db);
 
-	if (rec_bno >= mp->m_dir_geo->leafblk) {
+	if (rec_bno >= geo->leafblk) {
 		xchk_da_set_corrupt(ds, level);
 		goto out;
 	}
@@ -241,8 +242,8 @@ xchk_dir_rec(
 	dent = bp->b_addr + off;
 
 	/* Make sure we got a real directory entry. */
-	offset = mp->m_dir_inode_ops->data_entry_offset;
-	end = xfs_dir3_data_end_offset(mp->m_dir_geo, bp->b_addr);
+	offset = geo->data_entry_offset;
+	end = xfs_dir3_data_end_offset(geo, bp->b_addr);
 	if (!end) {
 		xchk_fblock_set_corrupt(ds->sc, XFS_DATA_FORK, rec_bno);
 		goto out_relse;
@@ -389,7 +390,7 @@ xchk_directory_data_bestfree(
 	}
 
 	/* Make sure the bestfrees are actually the best free spaces. */
-	offset = d_ops->data_entry_offset;
+	offset = mp->m_dir_geo->data_entry_offset;
 	end = xfs_dir3_data_end_offset(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 a52f0931b6af..5d945219a735 100644
--- a/fs/xfs/xfs_dir2_readdir.c
+++ b/fs/xfs/xfs_dir2_readdir.c
@@ -75,9 +75,9 @@ xfs_dir2_sf_getdents(
 	 * entries for "." and "..".
 	 */
 	dot_offset = xfs_dir2_db_off_to_dataptr(geo, geo->datablk,
-			dp->d_ops->data_entry_offset);
+			geo->data_entry_offset);
 	dotdot_offset = xfs_dir2_db_off_to_dataptr(geo, geo->datablk,
-			dp->d_ops->data_entry_offset +
+			geo->data_entry_offset +
 			xfs_dir2_data_entsize(mp, sizeof(".") - 1));
 
 	/*
@@ -174,7 +174,7 @@ xfs_dir2_block_getdents(
 	 * Loop over the data portion of the block.
 	 * Each object is a real entry (dep) or an unused one (dup).
 	 */
-	offset = dp->d_ops->data_entry_offset;
+	offset = geo->data_entry_offset;
 	end = xfs_dir3_data_end_offset(geo, bp->b_addr);
 	while (offset < end) {
 		struct xfs_dir2_data_unused	*dup = bp->b_addr + offset;
@@ -403,13 +403,13 @@ xfs_dir2_leaf_getdents(
 			/*
 			 * Find our position in the block.
 			 */
-			offset = dp->d_ops->data_entry_offset;
+			offset = 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] 73+ messages in thread

* [PATCH 41/46] xfs: cleanup xfs_dir2_data_entsize
  2019-11-07 18:23 remove m_dirops v2 Christoph Hellwig
                   ` (39 preceding siblings ...)
  2019-11-07 18:24 ` [PATCH 40/46] xfs: move the dir2 data block fixed offsets to struct xfs_da_geometry Christoph Hellwig
@ 2019-11-07 18:24 ` Christoph Hellwig
  2019-11-08  1:05   ` Darrick J. Wong
  2019-11-07 18:24 ` [PATCH 42/46] xfs: devirtualize ->data_bestfree_p Christoph Hellwig
                   ` (4 subsequent siblings)
  45 siblings, 1 reply; 73+ messages in thread
From: Christoph Hellwig @ 2019-11-07 18:24 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, which now becomes so simple that
we can turn it into an inline function.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 fs/xfs/libxfs/xfs_da_format.c | 33 ---------------------------------
 fs/xfs/libxfs/xfs_dir2_priv.h | 15 ++++++++++++++-
 2 files changed, 14 insertions(+), 34 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_priv.h b/fs/xfs/libxfs/xfs_dir2_priv.h
index a6c3fb3a2f7b..54bbfdd6ad69 100644
--- a/fs/xfs/libxfs/xfs_dir2_priv.h
+++ b/fs/xfs/libxfs/xfs_dir2_priv.h
@@ -57,7 +57,6 @@ 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);
 __be16 *xfs_dir2_data_entry_tag_p(struct xfs_mount *mp,
 		struct xfs_dir2_data_entry *dep);
 
@@ -172,4 +171,18 @@ extern xfs_failaddr_t xfs_dir2_sf_verify(struct xfs_inode *ip);
 extern int xfs_readdir(struct xfs_trans *tp, struct xfs_inode *dp,
 		       struct dir_context *ctx, size_t bufsize);
 
+static inline 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);
+}
+
 #endif /* __XFS_DIR2_PRIV_H__ */
-- 
2.20.1


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

* [PATCH 42/46] xfs: devirtualize ->data_bestfree_p
  2019-11-07 18:23 remove m_dirops v2 Christoph Hellwig
                   ` (40 preceding siblings ...)
  2019-11-07 18:24 ` [PATCH 41/46] xfs: cleanup xfs_dir2_data_entsize Christoph Hellwig
@ 2019-11-07 18:24 ` Christoph Hellwig
  2019-11-07 18:24 ` [PATCH 43/46] xfs: devirtualize ->data_get_ftype and ->data_put_ftype Christoph Hellwig
                   ` (3 subsequent siblings)
  45 siblings, 0 replies; 73+ messages in thread
From: Christoph Hellwig @ 2019-11-07 18:24 UTC (permalink / raw)
  To: linux-xfs; +Cc: Darrick J . Wong

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>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 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 830c70a20761..b50273b2d970 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 9529a000838f..62b3adb01210 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.
@@ -1199,8 +1199,8 @@ xfs_dir2_sf_to_block(
 			*xfs_dir2_data_unused_tag_p(dup) = cpu_to_be16(offset);
 			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 c1a843f6a8da..6ed9396225e3 100644
--- a/fs/xfs/libxfs/xfs_dir2_data.c
+++ b/fs/xfs/libxfs/xfs_dir2_data.c
@@ -25,6 +25,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;
+}
+
 /*
  * Pointer to an entry's tag word.
  */
@@ -121,7 +131,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)
@@ -581,12 +591,11 @@ 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)
 {
 	struct xfs_da_geometry		*geo = mp->m_dir_geo;
-	struct xfs_dir2_data_free	*bf = ops->data_bestfree_p(hdr);
+	struct xfs_dir2_data_free	*bf = xfs_dir2_data_bestfree_p(mp, hdr);
 	void				*addr = hdr;
 	unsigned int			offset = geo->data_entry_offset;
 	unsigned int			end;
@@ -633,7 +642,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);
 }
 
 /*
@@ -683,7 +692,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(geo->data_entry_offset);
 	bf[0].length = cpu_to_be16(geo->blksize - geo->data_entry_offset);
 	for (i = 1; i < XFS_DIR2_DATA_FD_COUNT; i++) {
@@ -841,7 +850,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 */
 
@@ -1032,7 +1041,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 2b327d1937f4..7fa485cd0158 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.
@@ -1620,7 +1620,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 8c7af28cea80..c97217e57a27 100644
--- a/fs/xfs/libxfs/xfs_dir2_node.c
+++ b/fs/xfs/libxfs/xfs_dir2_node.c
@@ -1317,7 +1317,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,
@@ -1775,7 +1775,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;
@@ -1948,7 +1948,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 54bbfdd6ad69..99cdc31eb8c9 100644
--- a/fs/xfs/libxfs/xfs_dir2_priv.h
+++ b/fs/xfs/libxfs/xfs_dir2_priv.h
@@ -57,6 +57,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);
 __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 5e8599d0613c..f53ee6a9078a 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;
 	u16				tag;
 	unsigned int			nr_bestfrees = 0;
 	unsigned int			nr_frees = 0;
@@ -337,8 +336,6 @@ xchk_directory_data_bestfree(
 	unsigned int			end;
 	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))
@@ -358,7 +355,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);
@@ -465,7 +462,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] 73+ messages in thread

* [PATCH 43/46] xfs: devirtualize ->data_get_ftype and ->data_put_ftype
  2019-11-07 18:23 remove m_dirops v2 Christoph Hellwig
                   ` (41 preceding siblings ...)
  2019-11-07 18:24 ` [PATCH 42/46] xfs: devirtualize ->data_bestfree_p Christoph Hellwig
@ 2019-11-07 18:24 ` Christoph Hellwig
  2019-11-07 18:24 ` [PATCH 44/46] xfs: remove the now unused dir ops infrastructure Christoph Hellwig
                   ` (2 subsequent siblings)
  45 siblings, 0 replies; 73+ messages in thread
From: Christoph Hellwig @ 2019-11-07 18:24 UTC (permalink / raw)
  To: linux-xfs; +Cc: Darrick J . Wong

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>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 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  | 43 ++++++++++++++++++++++---------
 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, 51 insertions(+), 77 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 b50273b2d970..b44c64a20f67 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 62b3adb01210..0c481e55c981 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;
@@ -1145,7 +1145,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(offset);
 	xfs_dir2_data_log_entry(args, bp, dep);
@@ -1160,7 +1160,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(offset);
 	xfs_dir2_data_log_entry(args, bp, dep);
@@ -1210,7 +1210,8 @@ xfs_dir2_sf_to_block(
 		dep = bp->b_addr + 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(newoffset);
diff --git a/fs/xfs/libxfs/xfs_dir2_data.c b/fs/xfs/libxfs/xfs_dir2_data.c
index 6ed9396225e3..0aa1d165c964 100644
--- a/fs/xfs/libxfs/xfs_dir2_data.c
+++ b/fs/xfs/libxfs/xfs_dir2_data.c
@@ -47,6 +47,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;
+}
+
 /*
  * The number of leaf entries is limited by the size of the block and the amount
  * of space used by the data entries.  We don't know how much space is used by
@@ -88,21 +116,12 @@ __xfs_dir3_data_check(
 	struct xfs_name		name;
 	unsigned int		offset;
 	unsigned int		end;
-	const struct xfs_dir_ops *ops;
 	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 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;
@@ -206,7 +225,7 @@ __xfs_dir3_data_check(
 			return __this_address;
 		if (be16_to_cpu(*xfs_dir2_data_entry_tag_p(mp, dep)) != offset)
 			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 7fa485cd0158..bc301c973450 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);
@@ -1526,7 +1526,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 c97217e57a27..5551be7c29df 100644
--- a/fs/xfs/libxfs/xfs_dir2_node.c
+++ b/fs/xfs/libxfs/xfs_dir2_node.c
@@ -884,7 +884,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;
@@ -1969,7 +1969,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);
@@ -2253,7 +2253,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 99cdc31eb8c9..82764aa2a6f6 100644
--- a/fs/xfs/libxfs/xfs_dir2_priv.h
+++ b/fs/xfs/libxfs/xfs_dir2_priv.h
@@ -61,6 +61,10 @@ struct xfs_dir2_data_free *xfs_dir2_data_bestfree_p(struct xfs_mount *mp,
 		struct xfs_dir2_data_hdr *hdr);
 __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 b5ac27442f9a..db1a82972d9e 100644
--- a/fs/xfs/libxfs/xfs_dir2_sf.c
+++ b/fs/xfs/libxfs/xfs_dir2_sf.c
@@ -319,7 +319,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 5d945219a735..9540ac7f2dfe 100644
--- a/fs/xfs/xfs_dir2_readdir.c
+++ b/fs/xfs/xfs_dir2_readdir.c
@@ -203,7 +203,7 @@ xfs_dir2_block_getdents(
 		cook = xfs_dir2_db_off_to_dataptr(geo, geo->datablk, offset);
 
 		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.
 		 */
@@ -458,7 +458,7 @@ xfs_dir2_leaf_getdents(
 
 		dep = bp->b_addr + offset;
 		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] 73+ messages in thread

* [PATCH 44/46] xfs: remove the now unused dir ops infrastructure
  2019-11-07 18:23 remove m_dirops v2 Christoph Hellwig
                   ` (42 preceding siblings ...)
  2019-11-07 18:24 ` [PATCH 43/46] xfs: devirtualize ->data_get_ftype and ->data_put_ftype Christoph Hellwig
@ 2019-11-07 18:24 ` Christoph Hellwig
  2019-11-07 18:24 ` [PATCH 45/46] xfs: merge xfs_dir2_data_freescan and xfs_dir2_data_freescan_int Christoph Hellwig
  2019-11-07 18:24 ` [PATCH 46/46] xfs: always pass a valid hdr to xfs_dir3_leaf_check_int Christoph Hellwig
  45 siblings, 0 replies; 73+ messages in thread
From: Christoph Hellwig @ 2019-11-07 18:24 UTC (permalink / raw)
  To: linux-xfs; +Cc: Darrick J . Wong

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 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 4ac2cc87c28f..5af4df71e92b 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 eccffe7a5ae0..624c05e77ab4 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 b44c64a20f67..a0cd423c79dd 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 21e6d08e3e18..57e6e44123a9 100644
--- a/fs/xfs/xfs_iops.c
+++ b/fs/xfs/xfs_iops.c
@@ -1321,7 +1321,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 9719f2aa8be3..2dceb446e651 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% */
@@ -156,7 +155,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] 73+ messages in thread

* [PATCH 45/46] xfs: merge xfs_dir2_data_freescan and xfs_dir2_data_freescan_int
  2019-11-07 18:23 remove m_dirops v2 Christoph Hellwig
                   ` (43 preceding siblings ...)
  2019-11-07 18:24 ` [PATCH 44/46] xfs: remove the now unused dir ops infrastructure Christoph Hellwig
@ 2019-11-07 18:24 ` Christoph Hellwig
  2019-11-07 18:24 ` [PATCH 46/46] xfs: always pass a valid hdr to xfs_dir3_leaf_check_int Christoph Hellwig
  45 siblings, 0 replies; 73+ messages in thread
From: Christoph Hellwig @ 2019-11-07 18:24 UTC (permalink / raw)
  To: linux-xfs; +Cc: Darrick J . Wong

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>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 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 a0cd423c79dd..34e7a0b64205 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 0c481e55c981..358151ddfa75 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 0aa1d165c964..9e471a28b6c6 100644
--- a/fs/xfs/libxfs/xfs_dir2_data.c
+++ b/fs/xfs/libxfs/xfs_dir2_data.c
@@ -608,7 +608,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)
@@ -655,15 +655,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 bc301c973450..2c67a9e24bd0 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.
 	 */
@@ -1415,7 +1415,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 5551be7c29df..3f36769f15af 100644
--- a/fs/xfs/libxfs/xfs_dir2_node.c
+++ b/fs/xfs/libxfs/xfs_dir2_node.c
@@ -1328,7 +1328,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);
@@ -1976,7 +1976,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] 73+ messages in thread

* [PATCH 46/46] xfs: always pass a valid hdr to xfs_dir3_leaf_check_int
  2019-11-07 18:23 remove m_dirops v2 Christoph Hellwig
                   ` (44 preceding siblings ...)
  2019-11-07 18:24 ` [PATCH 45/46] xfs: merge xfs_dir2_data_freescan and xfs_dir2_data_freescan_int Christoph Hellwig
@ 2019-11-07 18:24 ` Christoph Hellwig
  45 siblings, 0 replies; 73+ messages in thread
From: Christoph Hellwig @ 2019-11-07 18:24 UTC (permalink / raw)
  To: linux-xfs; +Cc: Darrick J . Wong

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>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 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 2c67a9e24bd0..e2e4b2c6d6c2 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] 73+ messages in thread

* Re: [PATCH 02/46] xfs: use unsigned int for all size values in struct xfs_da_geometry
  2019-11-07 18:23 ` [PATCH 02/46] xfs: use unsigned int for all size values in struct xfs_da_geometry Christoph Hellwig
@ 2019-11-07 22:33   ` Darrick J. Wong
  0 siblings, 0 replies; 73+ messages in thread
From: Darrick J. Wong @ 2019-11-07 22:33 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-xfs

On Thu, Nov 07, 2019 at 07:23:26PM +0100, Christoph Hellwig wrote:
> None of these can ever be negative, so use unsigned types.
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>

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

--D

> ---
>  fs/xfs/libxfs/xfs_da_btree.h | 8 ++++----
>  1 file changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/fs/xfs/libxfs/xfs_da_btree.h b/fs/xfs/libxfs/xfs_da_btree.h
> index 02f7a21ab3a5..01b0bbe8b266 100644
> --- a/fs/xfs/libxfs/xfs_da_btree.h
> +++ b/fs/xfs/libxfs/xfs_da_btree.h
> @@ -18,12 +18,12 @@ struct xfs_dir_ops;
>   * structures will be attached to the xfs_mount.
>   */
>  struct xfs_da_geometry {
> -	int		blksize;	/* da block size in bytes */
> -	int		fsbcount;	/* da block size in filesystem blocks */
> +	unsigned int	blksize;	/* da block size in bytes */
> +	unsigned int	fsbcount;	/* da block size in filesystem blocks */
>  	uint8_t		fsblog;		/* log2 of _filesystem_ block size */
>  	uint8_t		blklog;		/* log2 of da block size */
> -	uint		node_ents;	/* # of entries in a danode */
> -	int		magicpct;	/* 37% of block size in bytes */
> +	unsigned int	node_ents;	/* # of entries in a danode */
> +	unsigned int	magicpct;	/* 37% of block size in bytes */
>  	xfs_dablk_t	datablk;	/* blockno of dir data v2 */
>  	xfs_dablk_t	leafblk;	/* blockno of leaf data v2 */
>  	xfs_dablk_t	freeblk;	/* blockno of free data v2 */
> -- 
> 2.20.1
> 

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

* Re: [PATCH 30/46] xfs: cleanup xfs_dir2_leaf_getdents
  2019-11-07 18:23 ` [PATCH 30/46] xfs: cleanup xfs_dir2_leaf_getdents Christoph Hellwig
@ 2019-11-07 22:41   ` Darrick J. Wong
  2019-11-08  5:26     ` Christoph Hellwig
  0 siblings, 1 reply; 73+ messages in thread
From: Darrick J. Wong @ 2019-11-07 22:41 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-xfs

On Thu, Nov 07, 2019 at 07:23:54PM +0100, Christoph Hellwig wrote:
> Use an offset as the main means for iteration, and only do pointer
> arithmetics to find the data/unused entries.
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
>  fs/xfs/xfs_dir2_readdir.c | 34 +++++++++++++++++-----------------
>  1 file changed, 17 insertions(+), 17 deletions(-)
> 
> diff --git a/fs/xfs/xfs_dir2_readdir.c b/fs/xfs/xfs_dir2_readdir.c
> index 0d234b649d65..c4314e9e3dd8 100644
> --- a/fs/xfs/xfs_dir2_readdir.c
> +++ b/fs/xfs/xfs_dir2_readdir.c
> @@ -351,13 +351,13 @@ xfs_dir2_leaf_getdents(
>  	xfs_dir2_data_hdr_t	*hdr;		/* data block header */

gcc complained about this variable being set but not used.

>  	xfs_dir2_data_entry_t	*dep;		/* data entry */
>  	xfs_dir2_data_unused_t	*dup;		/* unused entry */
> -	char			*ptr = NULL;	/* pointer to current data */
>  	struct xfs_da_geometry	*geo = args->geo;
>  	xfs_dablk_t		rablk = 0;	/* current readahead block */
>  	xfs_dir2_off_t		curoff;		/* current overall offset */
>  	int			length;		/* temporary length value */
>  	int			byteoff;	/* offset in current block */
>  	int			lock_mode;
> +	unsigned int		offset = 0;

This is the offset within the block, right?

>  	int			error = 0;	/* error return value */
>  
>  	/*
> @@ -384,7 +384,7 @@ xfs_dir2_leaf_getdents(
>  		 * If we have no buffer, or we're off the end of the
>  		 * current buffer, need to get another one.
>  		 */
> -		if (!bp || ptr >= (char *)bp->b_addr + geo->blksize) {
> +		if (!bp || offset + geo->blksize) {

                           ^^^^^^^^^^^^^^^^^^^^^

In which case, isn't this always true?  Was this supposed to be
offset >= geo->blksize?

--D

>  			if (bp) {
>  				xfs_trans_brelse(args->trans, bp);
>  				bp = NULL;
> @@ -402,7 +402,7 @@ xfs_dir2_leaf_getdents(
>  			/*
>  			 * Find our position in the block.
>  			 */
> -			ptr = (char *)dp->d_ops->data_entry_p(hdr);
> +			offset = dp->d_ops->data_entry_offset;
>  			byteoff = xfs_dir2_byte_to_off(geo, curoff);
>  			/*
>  			 * Skip past the header.
> @@ -413,20 +413,20 @@ xfs_dir2_leaf_getdents(
>  			 * Skip past entries until we reach our offset.
>  			 */
>  			else {
> -				while ((char *)ptr - (char *)hdr < byteoff) {
> -					dup = (xfs_dir2_data_unused_t *)ptr;
> +				while (offset < byteoff) {
> +					dup = bp->b_addr + offset;
>  
>  					if (be16_to_cpu(dup->freetag)
>  						  == XFS_DIR2_DATA_FREE_TAG) {
>  
>  						length = be16_to_cpu(dup->length);
> -						ptr += length;
> +						offset += length;
>  						continue;
>  					}
> -					dep = (xfs_dir2_data_entry_t *)ptr;
> +					dep = bp->b_addr + offset;
>  					length =
>  					   dp->d_ops->data_entsize(dep->namelen);
> -					ptr += length;
> +					offset += length;
>  				}
>  				/*
>  				 * Now set our real offset.
> @@ -434,28 +434,28 @@ xfs_dir2_leaf_getdents(
>  				curoff =
>  					xfs_dir2_db_off_to_byte(geo,
>  					    xfs_dir2_byte_to_db(geo, curoff),
> -					    (char *)ptr - (char *)hdr);
> -				if (ptr >= (char *)hdr + geo->blksize) {
> +					    offset);
> +				if (offset >= geo->blksize)
>  					continue;
> -				}
>  			}
>  		}
> +
>  		/*
> -		 * We have a pointer to an entry.
> -		 * Is it a live one?
> +		 * We have a pointer to an entry.  Is it a live one?
>  		 */
> -		dup = (xfs_dir2_data_unused_t *)ptr;
> +		dup = bp->b_addr + offset;
> +
>  		/*
>  		 * No, it's unused, skip over it.
>  		 */
>  		if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) {
>  			length = be16_to_cpu(dup->length);
> -			ptr += length;
> +			offset += length;
>  			curoff += length;
>  			continue;
>  		}
>  
> -		dep = (xfs_dir2_data_entry_t *)ptr;
> +		dep = bp->b_addr + offset;
>  		length = dp->d_ops->data_entsize(dep->namelen);
>  		filetype = dp->d_ops->data_get_ftype(dep);
>  
> @@ -474,7 +474,7 @@ xfs_dir2_leaf_getdents(
>  		/*
>  		 * Advance to next entry in the block.
>  		 */
> -		ptr += length;
> +		offset += length;
>  		curoff += length;
>  		/* bufsize may have just been a guess; don't go negative */
>  		bufsize = bufsize > length ? bufsize - length : 0;
> -- 
> 2.20.1
> 

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

* Re: [PATCH 03/46] xfs: refactor btree node scrubbing
  2019-11-07 18:23 ` [PATCH 03/46] xfs: refactor btree node scrubbing Christoph Hellwig
@ 2019-11-07 22:43   ` Darrick J. Wong
  2019-11-08  5:28     ` Christoph Hellwig
  0 siblings, 1 reply; 73+ messages in thread
From: Darrick J. Wong @ 2019-11-07 22:43 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-xfs

On Thu, Nov 07, 2019 at 07:23:27PM +0100, 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    | 11 +++++-----
>  fs/xfs/scrub/dabtree.c | 48 ++++++++++--------------------------------
>  fs/xfs/scrub/dabtree.h |  3 +--
>  fs/xfs/scrub/dir.c     | 12 ++++++++---
>  4 files changed, 27 insertions(+), 47 deletions(-)
> 
> diff --git a/fs/xfs/scrub/attr.c b/fs/xfs/scrub/attr.c
> index 0edc7f8eb96e..d9f0dd444b80 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,9 @@ xchk_xattr_rec(
>  	unsigned int			badflags;
>  	int				error;
>  
> -	blk = &ds->state->path.blk[level];
> +	ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC);
> +
> +	ent = xfs_attr3_leaf_entryp(blk->bp->b_addr) + blk->index;
>  
>  	/* 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);

This eliminates the only user of blks, which means the variable can be
removed.  The rest looks fine though.

--D

> +	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] 73+ messages in thread

* Re: [PATCH 06/46] xfs: add a btree entries pointer to struct xfs_da3_icnode_hdr
  2019-11-07 18:23 ` [PATCH 06/46] xfs: add a btree entries pointer to struct xfs_da3_icnode_hdr Christoph Hellwig
@ 2019-11-08  0:21   ` Darrick J. Wong
  0 siblings, 0 replies; 73+ messages in thread
From: Darrick J. Wong @ 2019-11-08  0:21 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-xfs

On Thu, Nov 07, 2019 at 07:23:30PM +0100, 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>

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

--D

> ---
>  fs/xfs/libxfs/xfs_attr_leaf.c |  6 ++--
>  fs/xfs/libxfs/xfs_da_btree.c  | 68 ++++++++++++++++-------------------
>  fs/xfs/libxfs/xfs_da_btree.h  |  6 ++++
>  fs/xfs/libxfs/xfs_da_format.c | 21 -----------
>  fs/xfs/libxfs/xfs_dir2.h      |  2 --
>  fs/xfs/scrub/dabtree.c        |  7 ++--
>  fs/xfs/xfs_attr_inactive.c    | 34 +++++++++---------
>  fs/xfs/xfs_attr_list.c        |  2 +-
>  8 files changed, 60 insertions(+), 86 deletions(-)
> 
> diff --git a/fs/xfs/libxfs/xfs_attr_leaf.c b/fs/xfs/libxfs/xfs_attr_leaf.c
> index ba1c3486fe54..13d034e8f076 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 2a0221fcad82..6ffecab08d9e 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);
>  	}
>  }
> @@ -627,7 +629,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;
>  
> @@ -687,7 +689,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);
> @@ -839,8 +841,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.
> @@ -855,8 +857,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;
>  	}
>  
> @@ -937,8 +939,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);
> @@ -971,7 +973,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);
> @@ -1131,7 +1133,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;
>  
> @@ -1155,8 +1156,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);
> @@ -1321,18 +1321,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);
>  }
>  
>  /*
> @@ -1378,7 +1374,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;
> @@ -1417,7 +1413,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);
> @@ -1467,8 +1463,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;
>  
>  	/*
> @@ -1602,7 +1598,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) {
> @@ -1739,8 +1735,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)) ||
> @@ -1937,7 +1933,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;
> @@ -1960,17 +1955,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;
>  		}
>  	}
> @@ -2021,9 +2015,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;
> @@ -2308,7 +2302,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);
>  	}
> @@ -2375,7 +2369,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;
> @@ -2425,7 +2419,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 932f3ba6a813..4955c1fb8b0d 100644
> --- a/fs/xfs/libxfs/xfs_da_btree.h
> +++ b/fs/xfs/libxfs/xfs_da_btree.h
> @@ -135,6 +135,12 @@ struct xfs_da3_icnode_hdr {
>  	uint16_t		magic;
>  	uint16_t		count;
>  	uint16_t		level;
> +
> +	/*
> +	 * Pointer to the on-disk format entries, which are behind the
> +	 * variable size (v4 vs v5) header in the on-disk block.
> +	 */
> +	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..dbcb9d932816 100644
> --- a/fs/xfs/scrub/dabtree.c
> +++ b/fs/xfs/scrub/dabtree.c
> @@ -83,11 +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) +
> -		(blk->index * sizeof(struct xfs_da_node_entry));
> +	xfs_da3_node_hdr_from_disk(ds->sc->mp, &hdr, blk->bp->b_addr);
> +	return hdr.btree + blk->index;
>  }
>  
>  /* Scrub a da btree hash (key). */
> @@ -411,7 +412,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 88bc796c83f6..a78c501f6fb1 100644
> --- a/fs/xfs/xfs_attr_inactive.c
> +++ b/fs/xfs/xfs_attr_inactive.c
> @@ -191,19 +191,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.
> @@ -214,15 +212,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 */
>  
>  	/*
> @@ -282,13 +278,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 d89b83e89387..0ec6606149a2 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] 73+ messages in thread

* Re: [PATCH 10/46] xfs: add a entries pointer to struct xfs_dir3_icleaf_hdr
  2019-11-07 18:23 ` [PATCH 10/46] xfs: add a entries pointer to struct xfs_dir3_icleaf_hdr Christoph Hellwig
@ 2019-11-08  0:28   ` Darrick J. Wong
  0 siblings, 0 replies; 73+ messages in thread
From: Darrick J. Wong @ 2019-11-08  0:28 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-xfs

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

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

--D

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

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

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

On Thu, Nov 07, 2019 at 07:23:40PM +0100, 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>

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

--D

> ---
>  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 |  6 +++
>  fs/xfs/scrub/dir.c            |  6 +--
>  6 files changed, 48 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 b435379ddaa2..bbbd7b96678a 100644
> --- a/fs/xfs/libxfs/xfs_dir2_leaf.c
> +++ b/fs/xfs/libxfs/xfs_dir2_leaf.c
> @@ -1680,7 +1680,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 */
> @@ -1749,8 +1748,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);
>  
> @@ -1784,7 +1782,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 6d67ceac48b7..e9b4667faeac 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 = from3->bests;
>  
>  		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 = from->bests;
> +
>  		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) >
> @@ -432,11 +430,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);
>  	}
>  
>  	/*
> @@ -446,7 +444,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);
>  
>  	/*
> @@ -677,7 +675,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;
>  			/*
> @@ -712,8 +710,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)
> @@ -721,7 +720,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;
>  		}
>  	}
> @@ -1168,19 +1167,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;
>  	}
>  
> @@ -1196,14 +1193,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;
>  	}
>  
> @@ -1232,7 +1229,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;
>  }
>  
> @@ -1673,11 +1670,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. */
> @@ -1733,18 +1728,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. */
> @@ -1754,14 +1745,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);
> @@ -1769,7 +1760,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;
> @@ -1786,7 +1777,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;
> @@ -1796,7 +1786,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;
>  
> @@ -1807,16 +1796,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;
>  		}
> @@ -1859,14 +1845,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;
>  			}
> @@ -1883,7 +1867,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.
> @@ -1898,7 +1881,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;
> @@ -1913,7 +1895,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,
> @@ -1984,16 +1965,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 2c3370a3c010..9128f7aae0be 100644
> --- a/fs/xfs/libxfs/xfs_dir2_priv.h
> +++ b/fs/xfs/libxfs/xfs_dir2_priv.h
> @@ -31,6 +31,12 @@ struct xfs_dir3_icfree_hdr {
>  	uint32_t		firstdb;
>  	uint32_t		nvalid;
>  	uint32_t		nused;
> +
> +	/*
> +	 * Pointer to the on-disk format entries, which are behind the
> +	 * variable size (v4 vs v5) header in the on-disk block.
> +	 */
> +	__be16			*bests;
>  };
>  
>  /* xfs_dir2.c */
> diff --git a/fs/xfs/scrub/dir.c b/fs/xfs/scrub/dir.c
> index b0af252dccb3..bb08a1cbe523 100644
> --- a/fs/xfs/scrub/dir.c
> +++ b/fs/xfs/scrub/dir.c
> @@ -580,7 +580,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;
> @@ -601,9 +600,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] 73+ messages in thread

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

On Thu, Nov 07, 2019 at 07:23:41PM +0100, Christoph Hellwig wrote:
> Move the free header size towards our structure for dir/attr geometry
> parameters.
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>

Nice and short,
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      | 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 c6ff5329e92b..e8f0b7ac051c 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 {
>  	unsigned 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 */
> +	unsigned 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 8093afb389a1..eee75ec9707f 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 e9b4667faeac..c9a52e4e515d 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] 73+ messages in thread

* Re: [PATCH 22/46] xfs: devirtualize ->sf_get_ino and ->sf_put_ino
  2019-11-07 18:23 ` [PATCH 22/46] xfs: devirtualize ->sf_get_ino and ->sf_put_ino Christoph Hellwig
@ 2019-11-08  0:36   ` Darrick J. Wong
  0 siblings, 0 replies; 73+ messages in thread
From: Darrick J. Wong @ 2019-11-08  0:36 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-xfs

On Thu, Nov 07, 2019 at 07:23:46PM +0100, Christoph Hellwig wrote:
> Replace the ->sf_get_ino and ->sf_put_ino dir ops methods with directly
> called xfs_dir2_sf_get_ino and 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 and use XFS_MAXINUMBER istead of
> opencoded constants.
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>

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

--D

> ---
>  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    | 91 +++++++++++++++++++++++++++-----
>  fs/xfs/xfs_dir2_readdir.c      |  2 +-
>  6 files changed, 82 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 a6decb4c079a..02b0344508e0 100644
> --- a/fs/xfs/libxfs/xfs_dir2_block.c
> +++ b/fs/xfs/libxfs/xfs_dir2_block.c
> @@ -1208,7 +1208,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 357b388a5be0..a194a7b57277 100644
> --- a/fs/xfs/libxfs/xfs_dir2_priv.h
> +++ b/fs/xfs/libxfs/xfs_dir2_priv.h
> @@ -145,6 +145,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 36d79ec57d55..f63fb044bd15 100644
> --- a/fs/xfs/libxfs/xfs_dir2_sf.c
> +++ b/fs/xfs/libxfs/xfs_dir2_sf.c
> @@ -62,6 +62,70 @@ xfs_dir2_sf_nextentry(
>  	return (void *)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) & XFS_MAXINUMBER;
> +}
> +
> +static 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 <= XFS_MAXINUMBER);
> +
> +	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) & XFS_MAXINUMBER;
> +}
> +
> +void
> +xfs_dir2_sf_put_parent_ino(
> +	struct xfs_dir2_sf_hdr		*hdr,
> +	xfs_ino_t			ino)
> +{
> +	ASSERT(ino <= XFS_MAXINUMBER);
> +
> +	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
> @@ -239,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));
> @@ -406,7 +470,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);
>  
>  	/*
> @@ -496,7 +560,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)
> @@ -613,7 +677,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) +
> @@ -705,7 +769,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)
> @@ -848,7 +912,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;
> @@ -901,7 +965,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;
>  		}
> @@ -1016,9 +1080,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;
>  			}
> @@ -1123,8 +1188,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));
>  	}
>  	/*
> @@ -1195,8 +1260,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] 73+ messages in thread

* Re: [PATCH 25/46] xfs: remove the data_dot_offset field in struct xfs_dir_ops
  2019-11-07 18:23 ` [PATCH 25/46] xfs: remove the data_dot_offset field in struct xfs_dir_ops Christoph Hellwig
@ 2019-11-08  0:38   ` Darrick J. Wong
  0 siblings, 0 replies; 73+ messages in thread
From: Darrick J. Wong @ 2019-11-08  0:38 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-xfs

On Thu, Nov 07, 2019 at 07:23:49PM +0100, Christoph Hellwig wrote:
> The data_dot_offset value is always equal to data_entry_offset given
> that "." is always the first entry in the directory.
> 
> 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 | 3 ---
>  fs/xfs/libxfs/xfs_dir2.h      | 1 -
>  fs/xfs/xfs_dir2_readdir.c     | 9 ++++-----
>  3 files changed, 4 insertions(+), 9 deletions(-)
> 
> diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c
> index 19343c65be91..54754eef2437 100644
> --- a/fs/xfs/libxfs/xfs_da_format.c
> +++ b/fs/xfs/libxfs/xfs_da_format.c
> @@ -204,7 +204,6 @@ static const struct xfs_dir_ops xfs_dir2_ops = {
>  	.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),
>  	.data_dotdot_offset = sizeof(struct xfs_dir2_data_hdr) +
>  				XFS_DIR2_DATA_ENTSIZE(1),
>  	.data_first_offset =  sizeof(struct xfs_dir2_data_hdr) +
> @@ -225,7 +224,6 @@ static const struct xfs_dir_ops xfs_dir2_ftype_ops = {
>  	.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),
>  	.data_dotdot_offset = sizeof(struct xfs_dir2_data_hdr) +
>  				XFS_DIR3_DATA_ENTSIZE(1),
>  	.data_first_offset =  sizeof(struct xfs_dir2_data_hdr) +
> @@ -246,7 +244,6 @@ static const struct xfs_dir_ops xfs_dir3_ops = {
>  	.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),
>  	.data_dotdot_offset = sizeof(struct xfs_dir3_data_hdr) +
>  				XFS_DIR3_DATA_ENTSIZE(1),
>  	.data_first_offset =  sizeof(struct xfs_dir3_data_hdr) +
> diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h
> index 9169da84065a..94e8c40a7d19 100644
> --- a/fs/xfs/libxfs/xfs_dir2.h
> +++ b/fs/xfs/libxfs/xfs_dir2.h
> @@ -40,7 +40,6 @@ struct xfs_dir_ops {
>  	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;
> diff --git a/fs/xfs/xfs_dir2_readdir.c b/fs/xfs/xfs_dir2_readdir.c
> index e18045465455..39985ca6ae2d 100644
> --- a/fs/xfs/xfs_dir2_readdir.c
> +++ b/fs/xfs/xfs_dir2_readdir.c
> @@ -70,13 +70,12 @@ xfs_dir2_sf_getdents(
>  		return 0;
>  
>  	/*
> -	 * Precalculate offsets for . and .. as we will always need them.
> -	 *
> -	 * XXX(hch): the second argument is sometimes 0 and sometimes
> -	 * geo->datablk
> +	 * Precalculate offsets for "." and ".." as we will always need them.
> +	 * This relies on the fact that directories always start with the
> +	 * entries for "." and "..".
>  	 */
>  	dot_offset = xfs_dir2_db_off_to_dataptr(geo, geo->datablk,
> -						dp->d_ops->data_dot_offset);
> +			dp->d_ops->data_entry_offset);
>  	dotdot_offset = xfs_dir2_db_off_to_dataptr(geo, geo->datablk,
>  						dp->d_ops->data_dotdot_offset);
>  
> -- 
> 2.20.1
> 

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

* Re: [PATCH 27/46] xfs: remove the ->data_dot_entry_p and ->data_dotdot_entry_p methods
  2019-11-07 18:23 ` [PATCH 27/46] xfs: remove the ->data_dot_entry_p and ->data_dotdot_entry_p methods Christoph Hellwig
@ 2019-11-08  0:49   ` Darrick J. Wong
  0 siblings, 0 replies; 73+ messages in thread
From: Darrick J. Wong @ 2019-11-08  0:49 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-xfs

On Thu, Nov 07, 2019 at 07:23:51PM +0100, Christoph Hellwig wrote:
> The only user of the ->data_dot_entry_p and ->data_dotdot_entry_p
> methods is the xfs_dir2_sf_to_block function that builds block format
> directorys from a short form directory.  It already uses pointer
> arithmetics with a offset variable to do so for the real entries in
> the directory, so switch the generation of the . and .. entries to
> the same scheme, and clean up some of the later pointer arithmetics
> to use bp->b_addr directly as well and avoid some casts.
> 
> 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 | 54 ++++++++++++++++------------------
>  3 files changed, 26 insertions(+), 84 deletions(-)
> 
> diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c
> index 7b783b11790d..711faff4aea2 100644
> --- a/fs/xfs/libxfs/xfs_da_format.c
> +++ b/fs/xfs/libxfs/xfs_da_format.c
> @@ -111,52 +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_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_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_free *
>  xfs_dir2_data_bestfree_p(struct xfs_dir2_data_hdr *hdr)
>  {
> @@ -209,8 +163,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_entry_p = xfs_dir2_data_entry_p,
>  	.data_unused_p = xfs_dir2_data_unused_p,
>  };
> @@ -227,8 +179,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_entry_p = xfs_dir2_data_entry_p,
>  	.data_unused_p = xfs_dir2_data_unused_p,
>  };
> @@ -245,8 +195,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_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 8b937993263d..8bfcf4c1b9c4 100644
> --- a/fs/xfs/libxfs/xfs_dir2.h
> +++ b/fs/xfs/libxfs/xfs_dir2.h
> @@ -43,10 +43,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_entry_p)(struct xfs_dir2_data_hdr *hdr);
>  	struct xfs_dir2_data_unused *
> diff --git a/fs/xfs/libxfs/xfs_dir2_block.c b/fs/xfs/libxfs/xfs_dir2_block.c
> index 6bc82a02b228..e7719356829d 100644
> --- a/fs/xfs/libxfs/xfs_dir2_block.c
> +++ b/fs/xfs/libxfs/xfs_dir2_block.c
> @@ -1038,39 +1038,35 @@ xfs_dir2_leaf_to_block(
>   */
>  int						/* error */
>  xfs_dir2_sf_to_block(
> -	xfs_da_args_t		*args)		/* operation arguments */
> +	struct xfs_da_args	*args)
>  {
> +	struct xfs_trans	*tp = args->trans;
> +	struct xfs_inode	*dp = args->dp;
> +	struct xfs_mount	*mp = dp->i_mount;
> +	struct xfs_ifork	*ifp = XFS_IFORK_PTR(dp, XFS_DATA_FORK);
>  	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 */
>  	struct xfs_buf		*bp;		/* block buffer */
>  	xfs_dir2_block_tail_t	*btp;		/* block tail pointer */
>  	xfs_dir2_data_entry_t	*dep;		/* data entry pointer */
> -	xfs_inode_t		*dp;		/* incore directory inode */
>  	int			dummy;		/* trash */
>  	xfs_dir2_data_unused_t	*dup;		/* unused entry pointer */
>  	int			endoffset;	/* end of data objects */
>  	int			error;		/* error return value */
>  	int			i;		/* index */
> -	xfs_mount_t		*mp;		/* filesystem mount point */
>  	int			needlog;	/* need to log block header */
>  	int			needscan;	/* need to scan block freespc */
>  	int			newoffset;	/* offset from current entry */
> -	int			offset;		/* target block offset */
> +	unsigned int		offset = dp->d_ops->data_entry_offset;
>  	xfs_dir2_sf_entry_t	*sfep;		/* sf entry pointer */
>  	xfs_dir2_sf_hdr_t	*oldsfp;	/* old shortform header  */
>  	xfs_dir2_sf_hdr_t	*sfp;		/* shortform header  */
>  	__be16			*tagp;		/* end of data entry */
> -	xfs_trans_t		*tp;		/* transaction pointer */
>  	struct xfs_name		name;
> -	struct xfs_ifork	*ifp;
>  
>  	trace_xfs_dir2_sf_to_block(args);
>  
> -	dp = args->dp;
> -	tp = args->trans;
> -	mp = dp->i_mount;
> -	ifp = XFS_IFORK_PTR(dp, XFS_DATA_FORK);
>  	ASSERT(ifp->if_flags & XFS_IFINLINE);
>  	ASSERT(dp->i_d.di_size >= offsetof(struct xfs_dir2_sf_hdr, parent));
>  
> @@ -1139,35 +1135,37 @@ xfs_dir2_sf_to_block(
>  			be16_to_cpu(dup->length), &needlog, &needscan);
>  	if (error)
>  		goto out_free;
> +
>  	/*
>  	 * Create entry for .
>  	 */
> -	dep = dp->d_ops->data_dot_entry_p(hdr);
> +	dep = bp->b_addr + offset;
>  	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);
>  	tagp = dp->d_ops->data_entry_tag_p(dep);
> -	*tagp = cpu_to_be16((char *)dep - (char *)hdr);
> +	*tagp = cpu_to_be16(offset);
>  	xfs_dir2_data_log_entry(args, bp, dep);
>  	blp[0].hashval = cpu_to_be32(xfs_dir_hash_dot);
> -	blp[0].address = cpu_to_be32(xfs_dir2_byte_to_dataptr(
> -				(char *)dep - (char *)hdr));
> +	blp[0].address = cpu_to_be32(xfs_dir2_byte_to_dataptr(offset));
> +	offset += dp->d_ops->data_entsize(dep->namelen);
> +
>  	/*
>  	 * Create entry for ..
>  	 */
> -	dep = dp->d_ops->data_dotdot_entry_p(hdr);
> +	dep = bp->b_addr + offset;

This is kind of a lot of open-coded void pointer arithmetic for my
tastes, but OTOH I guess there's not much of a way around that for
variable length records...

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

--D

>  	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);
>  	tagp = dp->d_ops->data_entry_tag_p(dep);
> -	*tagp = cpu_to_be16((char *)dep - (char *)hdr);
> +	*tagp = cpu_to_be16(offset);
>  	xfs_dir2_data_log_entry(args, bp, dep);
>  	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;
> +	blp[1].address = cpu_to_be32(xfs_dir2_byte_to_dataptr(offset));
> +	offset += dp->d_ops->data_entsize(dep->namelen);
> +
>  	/*
>  	 * Loop over existing entries, stuff them in.
>  	 */
> @@ -1176,6 +1174,7 @@ xfs_dir2_sf_to_block(
>  		sfep = NULL;
>  	else
>  		sfep = xfs_dir2_sf_firstentry(sfp);
> +
>  	/*
>  	 * Need to preserve the existing offset values in the sf directory.
>  	 * Insert holes (unused entries) where necessary.
> @@ -1192,11 +1191,10 @@ xfs_dir2_sf_to_block(
>  		 * There should be a hole here, make one.
>  		 */
>  		if (offset < newoffset) {
> -			dup = (xfs_dir2_data_unused_t *)((char *)hdr + offset);
> +			dup = bp->b_addr + offset;
>  			dup->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG);
>  			dup->length = cpu_to_be16(newoffset - offset);
> -			*xfs_dir2_data_unused_tag_p(dup) = cpu_to_be16(
> -				((char *)dup - (char *)hdr));
> +			*xfs_dir2_data_unused_tag_p(dup) = cpu_to_be16(offset);
>  			xfs_dir2_data_log_unused(args, bp, dup);
>  			xfs_dir2_data_freeinsert(hdr,
>  						 dp->d_ops->data_bestfree_p(hdr),
> @@ -1207,20 +1205,20 @@ xfs_dir2_sf_to_block(
>  		/*
>  		 * Copy a real entry.
>  		 */
> -		dep = (xfs_dir2_data_entry_t *)((char *)hdr + newoffset);
> +		dep = bp->b_addr + 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));
>  		memcpy(dep->name, sfep->name, dep->namelen);
>  		tagp = dp->d_ops->data_entry_tag_p(dep);
> -		*tagp = cpu_to_be16((char *)dep - (char *)hdr);
> +		*tagp = cpu_to_be16(newoffset);
>  		xfs_dir2_data_log_entry(args, bp, dep);
>  		name.name = sfep->name;
>  		name.len = sfep->namelen;
> -		blp[2 + i].hashval = cpu_to_be32(mp->m_dirnameops->
> -							hashname(&name));
> -		blp[2 + i].address = cpu_to_be32(xfs_dir2_byte_to_dataptr(
> -						 (char *)dep - (char *)hdr));
> +		blp[2 + i].hashval =
> +			cpu_to_be32(mp->m_dirnameops->hashname(&name));
> +		blp[2 + i].address =
> +			cpu_to_be32(xfs_dir2_byte_to_dataptr(newoffset));
>  		offset = (int)((char *)(tagp + 1) - (char *)hdr);
>  		if (++i == sfp->count)
>  			sfep = NULL;
> -- 
> 2.20.1
> 

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

* Re: [PATCH 26/46] xfs: remove the data_dotdot_offset field in struct xfs_dir_ops
  2019-11-07 18:23 ` [PATCH 26/46] xfs: remove the data_dotdot_offset " Christoph Hellwig
@ 2019-11-08  0:50   ` Darrick J. Wong
  0 siblings, 0 replies; 73+ messages in thread
From: Darrick J. Wong @ 2019-11-08  0:50 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-xfs

On Thu, Nov 07, 2019 at 07:23:50PM +0100, Christoph Hellwig wrote:
> The data_dotdot_offset value is always equal to data_entry_offset plus
> the fixed size of the "." entry.  Right now calculating that fixed size
> requires an indirect call, but by the end of this series it will be
> an inline function that can be constant folded.
> 
> 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 | 6 ------
>  fs/xfs/libxfs/xfs_dir2.h      | 1 -
>  fs/xfs/xfs_dir2_readdir.c     | 3 ++-
>  3 files changed, 2 insertions(+), 8 deletions(-)
> 
> diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c
> index 54754eef2437..7b783b11790d 100644
> --- a/fs/xfs/libxfs/xfs_da_format.c
> +++ b/fs/xfs/libxfs/xfs_da_format.c
> @@ -204,8 +204,6 @@ static const struct xfs_dir_ops xfs_dir2_ops = {
>  	.data_entry_tag_p = xfs_dir2_data_entry_tag_p,
>  	.data_bestfree_p = xfs_dir2_data_bestfree_p,
>  
> -	.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),
> @@ -224,8 +222,6 @@ static const struct xfs_dir_ops xfs_dir2_ftype_ops = {
>  	.data_entry_tag_p = xfs_dir3_data_entry_tag_p,
>  	.data_bestfree_p = xfs_dir2_data_bestfree_p,
>  
> -	.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),
> @@ -244,8 +240,6 @@ static const struct xfs_dir_ops xfs_dir3_ops = {
>  	.data_entry_tag_p = xfs_dir3_data_entry_tag_p,
>  	.data_bestfree_p = xfs_dir3_data_bestfree_p,
>  
> -	.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),
> diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h
> index 94e8c40a7d19..8b937993263d 100644
> --- a/fs/xfs/libxfs/xfs_dir2.h
> +++ b/fs/xfs/libxfs/xfs_dir2.h
> @@ -40,7 +40,6 @@ struct xfs_dir_ops {
>  	struct xfs_dir2_data_free *
>  		(*data_bestfree_p)(struct xfs_dir2_data_hdr *hdr);
>  
> -	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/xfs_dir2_readdir.c b/fs/xfs/xfs_dir2_readdir.c
> index 39985ca6ae2d..187bb51875c2 100644
> --- a/fs/xfs/xfs_dir2_readdir.c
> +++ b/fs/xfs/xfs_dir2_readdir.c
> @@ -77,7 +77,8 @@ xfs_dir2_sf_getdents(
>  	dot_offset = xfs_dir2_db_off_to_dataptr(geo, geo->datablk,
>  			dp->d_ops->data_entry_offset);
>  	dotdot_offset = xfs_dir2_db_off_to_dataptr(geo, geo->datablk,
> -						dp->d_ops->data_dotdot_offset);
> +			dp->d_ops->data_entry_offset +
> +			dp->d_ops->data_entsize(sizeof(".") - 1));
>  
>  	/*
>  	 * Put . entry unless we're starting past it.
> -- 
> 2.20.1
> 

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

* Re: [PATCH 28/46] xfs: remove the ->data_unused_p method
  2019-11-07 18:23 ` [PATCH 28/46] xfs: remove the ->data_unused_p method Christoph Hellwig
@ 2019-11-08  0:51   ` Darrick J. Wong
  0 siblings, 0 replies; 73+ messages in thread
From: Darrick J. Wong @ 2019-11-08  0:51 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-xfs

On Thu, Nov 07, 2019 at 07:23:52PM +0100, Christoph Hellwig wrote:
> Replace the two users of the ->data_unused_p dir ops method with a
> direct calculation using ->data_entry_offset, and clean them up a bit.
> xfs_dir2_sf_to_block already had an offset variable containing the
> value of ->data_entry_offset, which we are now reusing to make it
> clear that the initial freespace entry is at the same place that
> we later fill in the 1 entry, and in xfs_dir3_data_init the function
> is cleaned up a bit to keep the initialization of fields of a given
> structure close to each other, and to avoid a local variable.
> 
> 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  | 17 ---------------
>  fs/xfs/libxfs/xfs_dir2.h       |  2 --
>  fs/xfs/libxfs/xfs_dir2_block.c |  2 +-
>  fs/xfs/libxfs/xfs_dir2_data.c  | 40 +++++++++++++++-------------------
>  4 files changed, 19 insertions(+), 42 deletions(-)
> 
> diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c
> index 711faff4aea2..347092ec28ab 100644
> --- a/fs/xfs/libxfs/xfs_da_format.c
> +++ b/fs/xfs/libxfs/xfs_da_format.c
> @@ -130,13 +130,6 @@ xfs_dir2_data_entry_p(struct xfs_dir2_data_hdr *hdr)
>  		((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)
>  {
> @@ -144,13 +137,6 @@ xfs_dir3_data_entry_p(struct xfs_dir2_data_hdr *hdr)
>  		((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,
> @@ -164,7 +150,6 @@ static const struct xfs_dir_ops xfs_dir2_ops = {
>  	.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 = {
> @@ -180,7 +165,6 @@ static const struct xfs_dir_ops xfs_dir2_ftype_ops = {
>  	.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 = {
> @@ -196,7 +180,6 @@ static const struct xfs_dir_ops xfs_dir3_ops = {
>  	.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 8bfcf4c1b9c4..75aec05aae10 100644
> --- a/fs/xfs/libxfs/xfs_dir2.h
> +++ b/fs/xfs/libxfs/xfs_dir2.h
> @@ -45,8 +45,6 @@ struct xfs_dir_ops {
>  
>  	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 e7719356829d..9061f378d52a 100644
> --- a/fs/xfs/libxfs/xfs_dir2_block.c
> +++ b/fs/xfs/libxfs/xfs_dir2_block.c
> @@ -1112,7 +1112,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 = bp->b_addr + 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..3ecec8e1c5f6 100644
> --- a/fs/xfs/libxfs/xfs_dir2_data.c
> +++ b/fs/xfs/libxfs/xfs_dir2_data.c
> @@ -631,24 +631,20 @@ xfs_dir2_data_freescan(
>   */
>  int						/* error */
>  xfs_dir3_data_init(
> -	xfs_da_args_t		*args,		/* directory operation args */
> -	xfs_dir2_db_t		blkno,		/* logical dir block number */
> -	struct xfs_buf		**bpp)		/* output block buffer */
> +	struct xfs_da_args		*args,	/* directory operation args */
> +	xfs_dir2_db_t			blkno,	/* logical dir block number */
> +	struct xfs_buf			**bpp)	/* output block buffer */
>  {
> -	struct xfs_buf		*bp;		/* block buffer */
> -	xfs_dir2_data_hdr_t	*hdr;		/* data block header */
> -	xfs_inode_t		*dp;		/* incore directory inode */
> -	xfs_dir2_data_unused_t	*dup;		/* unused entry pointer */
> -	struct xfs_dir2_data_free *bf;
> -	int			error;		/* error return value */
> -	int			i;		/* bestfree index */
> -	xfs_mount_t		*mp;		/* filesystem mount point */
> -	xfs_trans_t		*tp;		/* transaction pointer */
> -	int                     t;              /* temp */
> -
> -	dp = args->dp;
> -	mp = dp->i_mount;
> -	tp = args->trans;
> +	struct xfs_trans		*tp = args->trans;
> +	struct xfs_inode		*dp = args->dp;
> +	struct xfs_mount		*mp = dp->i_mount;
> +	struct xfs_buf			*bp;
> +	struct xfs_dir2_data_hdr	*hdr;
> +	struct xfs_dir2_data_unused	*dup;
> +	struct xfs_dir2_data_free 	*bf;
> +	int				error;
> +	int				i;
> +
>  	/*
>  	 * Get the buffer set up for the block.
>  	 */
> @@ -677,6 +673,8 @@ xfs_dir3_data_init(
>  
>  	bf = dp->d_ops->data_bestfree_p(hdr);
>  	bf[0].offset = cpu_to_be16(dp->d_ops->data_entry_offset);
> +	bf[0].length =
> +		cpu_to_be16(args->geo->blksize - dp->d_ops->data_entry_offset);
>  	for (i = 1; i < XFS_DIR2_DATA_FD_COUNT; i++) {
>  		bf[i].length = 0;
>  		bf[i].offset = 0;
> @@ -685,13 +683,11 @@ xfs_dir3_data_init(
>  	/*
>  	 * Set up an unused entry for the block's body.
>  	 */
> -	dup = dp->d_ops->data_unused_p(hdr);
> +	dup = bp->b_addr + 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;
> -	bf[0].length = cpu_to_be16(t);
> -	dup->length = cpu_to_be16(t);
> +	dup->length = bf[0].length;
>  	*xfs_dir2_data_unused_tag_p(dup) = cpu_to_be16((char *)dup - (char *)hdr);
> +
>  	/*
>  	 * Log it and return it.
>  	 */
> -- 
> 2.20.1
> 

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

* Re: [PATCH 29/46] xfs: cleanup xfs_dir2_block_getdents
  2019-11-07 18:23 ` [PATCH 29/46] xfs: cleanup xfs_dir2_block_getdents Christoph Hellwig
@ 2019-11-08  0:52   ` Darrick J. Wong
  0 siblings, 0 replies; 73+ messages in thread
From: Darrick J. Wong @ 2019-11-08  0:52 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-xfs

On Thu, Nov 07, 2019 at 07:23:53PM +0100, Christoph Hellwig wrote:
> Use an offset as the main means for iteration, and only do pointer
> arithmetics to find the data/unused entries.
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>

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

--D

> ---
>  fs/xfs/xfs_dir2_readdir.c | 32 ++++++++++++--------------------
>  1 file changed, 12 insertions(+), 20 deletions(-)
> 
> diff --git a/fs/xfs/xfs_dir2_readdir.c b/fs/xfs/xfs_dir2_readdir.c
> index 187bb51875c2..0d234b649d65 100644
> --- a/fs/xfs/xfs_dir2_readdir.c
> +++ b/fs/xfs/xfs_dir2_readdir.c
> @@ -142,17 +142,14 @@ xfs_dir2_block_getdents(
>  	struct dir_context	*ctx)
>  {
>  	struct xfs_inode	*dp = args->dp;	/* incore directory inode */
> -	xfs_dir2_data_hdr_t	*hdr;		/* block header */
>  	struct xfs_buf		*bp;		/* buffer for block */
> -	xfs_dir2_data_entry_t	*dep;		/* block data entry */
> -	xfs_dir2_data_unused_t	*dup;		/* block unused entry */
> -	char			*endptr;	/* end of the data entries */
>  	int			error;		/* error return value */
> -	char			*ptr;		/* current data entry */
>  	int			wantoff;	/* starting block offset */
>  	xfs_off_t		cook;
>  	struct xfs_da_geometry	*geo = args->geo;
>  	int			lock_mode;
> +	unsigned int		offset;
> +	unsigned int		end;
>  
>  	/*
>  	 * If the block number in the offset is out of range, we're done.
> @@ -171,44 +168,39 @@ xfs_dir2_block_getdents(
>  	 * We'll skip entries before this.
>  	 */
>  	wantoff = xfs_dir2_dataptr_to_off(geo, ctx->pos);
> -	hdr = bp->b_addr;
>  	xfs_dir3_data_check(dp, bp);
> -	/*
> -	 * Set up values for the loop.
> -	 */
> -	ptr = (char *)dp->d_ops->data_entry_p(hdr);
> -	endptr = xfs_dir3_data_endp(geo, hdr);
>  
>  	/*
>  	 * Loop over the data portion of the block.
>  	 * Each object is a real entry (dep) or an unused one (dup).
>  	 */
> -	while (ptr < endptr) {
> +	offset = dp->d_ops->data_entry_offset;
> +	end = xfs_dir3_data_endp(geo, bp->b_addr) - bp->b_addr;
> +	while (offset < end) {
> +		struct xfs_dir2_data_unused	*dup = bp->b_addr + offset;
> +		struct xfs_dir2_data_entry	*dep = bp->b_addr + offset;
>  		uint8_t filetype;
>  
> -		dup = (xfs_dir2_data_unused_t *)ptr;
>  		/*
>  		 * Unused, skip it.
>  		 */
>  		if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) {
> -			ptr += be16_to_cpu(dup->length);
> +			offset += be16_to_cpu(dup->length);
>  			continue;
>  		}
>  
> -		dep = (xfs_dir2_data_entry_t *)ptr;
> -
>  		/*
>  		 * Bump pointer for the next iteration.
>  		 */
> -		ptr += dp->d_ops->data_entsize(dep->namelen);
> +		offset += dp->d_ops->data_entsize(dep->namelen);
> +
>  		/*
>  		 * The entry is before the desired starting point, skip it.
>  		 */
> -		if ((char *)dep - (char *)hdr < wantoff)
> +		if (offset < wantoff)
>  			continue;
>  
> -		cook = xfs_dir2_db_off_to_dataptr(geo, geo->datablk,
> -					    (char *)dep - (char *)hdr);
> +		cook = xfs_dir2_db_off_to_dataptr(geo, geo->datablk, offset);
>  
>  		ctx->pos = cook & 0x7fffffff;
>  		filetype = dp->d_ops->data_get_ftype(dep);
> -- 
> 2.20.1
> 

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

* Re: [PATCH 31/46] xfs: cleanup xchk_dir_rec
  2019-11-07 18:23 ` [PATCH 31/46] xfs: cleanup xchk_dir_rec Christoph Hellwig
@ 2019-11-08  0:57   ` Darrick J. Wong
  2019-11-08  5:38     ` Christoph Hellwig
  0 siblings, 1 reply; 73+ messages in thread
From: Darrick J. Wong @ 2019-11-08  0:57 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-xfs

On Thu, Nov 07, 2019 at 07:23:55PM +0100, Christoph Hellwig wrote:
> Use an offset as the main means for iteration, and only do pointer
> arithmetics to find the data/unused entries.
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
>  fs/xfs/scrub/dir.c | 28 ++++++++++++++--------------
>  1 file changed, 14 insertions(+), 14 deletions(-)
> 
> diff --git a/fs/xfs/scrub/dir.c b/fs/xfs/scrub/dir.c
> index bb08a1cbe523..501d60c9b09a 100644
> --- a/fs/xfs/scrub/dir.c
> +++ b/fs/xfs/scrub/dir.c
> @@ -187,7 +187,8 @@ xchk_dir_rec(
>  	struct xfs_dir2_data_entry	*dent;
>  	struct xfs_buf			*bp;
>  	struct xfs_dir2_leaf_entry	*ent;
> -	char				*p, *endp;
> +	void				*endp;
> +	unsigned int			offset;

Can this be named iter_off or something?  There's already an @off variable
which is the offset-within-block that wa calculated from the entry pointer.

>  	xfs_ino_t			ino;
>  	xfs_dablk_t			rec_bno;
>  	xfs_dir2_db_t			db;
> @@ -237,32 +238,31 @@ xchk_dir_rec(
>  	if (ds->sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)
>  		goto out_relse;
>  
> -	dent = (struct xfs_dir2_data_entry *)(((char *)bp->b_addr) + off);
> +	dent = 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);
> +	offset = 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);
>  		goto out_relse;
>  	}
> -	while (p < endp) {
> -		struct xfs_dir2_data_entry	*dep;
> -		struct xfs_dir2_data_unused	*dup;
> +	for (;;) {
> +		struct xfs_dir2_data_entry	*dep = bp->b_addr + offset;
> +		struct xfs_dir2_data_unused	*dup = bp->b_addr + offset;
> +	

Extra whitespace.

--D

> +		if (offset >= endp - bp->b_addr) {
> +			xchk_fblock_set_corrupt(ds->sc, XFS_DATA_FORK, rec_bno);
> +			goto out_relse;
> +		}
>  
> -		dup = (struct xfs_dir2_data_unused *)p;
>  		if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) {
> -			p += be16_to_cpu(dup->length);
> +			offset += be16_to_cpu(dup->length);
>  			continue;
>  		}
> -		dep = (struct xfs_dir2_data_entry *)p;
>  		if (dep == dent)
>  			break;
> -		p += mp->m_dir_inode_ops->data_entsize(dep->namelen);
> -	}
> -	if (p >= endp) {
> -		xchk_fblock_set_corrupt(ds->sc, XFS_DATA_FORK, rec_bno);
> -		goto out_relse;
> +		offset += mp->m_dir_inode_ops->data_entsize(dep->namelen);
>  	}
>  
>  	/* Retrieve the entry, sanity check it, and compare hashes. */
> -- 
> 2.20.1
> 

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

* Re: [PATCH 32/46] xfs: cleanup xchk_directory_data_bestfree
  2019-11-07 18:23 ` [PATCH 32/46] xfs: cleanup xchk_directory_data_bestfree Christoph Hellwig
@ 2019-11-08  0:57   ` Darrick J. Wong
  0 siblings, 0 replies; 73+ messages in thread
From: Darrick J. Wong @ 2019-11-08  0:57 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-xfs

On Thu, Nov 07, 2019 at 07:23:56PM +0100, Christoph Hellwig wrote:
> Use an offset as the main means for iteration, and only do pointer
> arithmetics to find the data/unused entries.
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>

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

--D

> ---
>  fs/xfs/scrub/dir.c | 31 +++++++++++++++----------------
>  1 file changed, 15 insertions(+), 16 deletions(-)
> 
> diff --git a/fs/xfs/scrub/dir.c b/fs/xfs/scrub/dir.c
> index 501d60c9b09a..4cef21b9d336 100644
> --- a/fs/xfs/scrub/dir.c
> +++ b/fs/xfs/scrub/dir.c
> @@ -327,14 +327,13 @@ xchk_directory_data_bestfree(
>  	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;
>  	unsigned int			nr_bestfrees = 0;
>  	unsigned int			nr_frees = 0;
>  	unsigned int			smallest_bestfree;
>  	int				newlen;
> -	int				offset;
> +	unsigned int			offset;
> +	unsigned int			end;
>  	int				error;
>  
>  	d_ops = sc->ip->d_ops;
> @@ -368,13 +367,13 @@ xchk_directory_data_bestfree(
>  			xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk);
>  			goto out_buf;
>  		}
> -		dup = (struct xfs_dir2_data_unused *)(bp->b_addr + offset);
> +		dup = bp->b_addr + offset;
>  		tag = be16_to_cpu(*xfs_dir2_data_unused_tag_p(dup));
>  
>  		/* bestfree doesn't match the entry it points at? */
>  		if (dup->freetag != cpu_to_be16(XFS_DIR2_DATA_FREE_TAG) ||
>  		    be16_to_cpu(dup->length) != be16_to_cpu(dfp->length) ||
> -		    tag != ((char *)dup - (char *)bp->b_addr)) {
> +		    tag != offset) {
>  			xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk);
>  			goto out_buf;
>  		}
> @@ -390,30 +389,30 @@ xchk_directory_data_bestfree(
>  	}
>  
>  	/* Make sure the bestfrees are actually the best free spaces. */
> -	ptr = (char *)d_ops->data_entry_p(bp->b_addr);
> -	endptr = xfs_dir3_data_endp(mp->m_dir_geo, bp->b_addr);
> +	offset = d_ops->data_entry_offset;
> +	end = xfs_dir3_data_endp(mp->m_dir_geo, bp->b_addr) - bp->b_addr;
>  
>  	/* Iterate the entries, stopping when we hit or go past the end. */
> -	while (ptr < endptr) {
> -		dup = (struct xfs_dir2_data_unused *)ptr;
> +	while (offset < end) {
> +		dup = bp->b_addr + offset;
> +
>  		/* Skip real entries */
>  		if (dup->freetag != cpu_to_be16(XFS_DIR2_DATA_FREE_TAG)) {
> -			struct xfs_dir2_data_entry	*dep;
> +			struct xfs_dir2_data_entry *dep = bp->b_addr + offset;
>  
> -			dep = (struct xfs_dir2_data_entry *)ptr;
>  			newlen = d_ops->data_entsize(dep->namelen);
>  			if (newlen <= 0) {
>  				xchk_fblock_set_corrupt(sc, XFS_DATA_FORK,
>  						lblk);
>  				goto out_buf;
>  			}
> -			ptr += newlen;
> +			offset += newlen;
>  			continue;
>  		}
>  
>  		/* Spot check this free entry */
>  		tag = be16_to_cpu(*xfs_dir2_data_unused_tag_p(dup));
> -		if (tag != ((char *)dup - (char *)bp->b_addr)) {
> +		if (tag != offset) {
>  			xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk);
>  			goto out_buf;
>  		}
> @@ -432,13 +431,13 @@ xchk_directory_data_bestfree(
>  			xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk);
>  			goto out_buf;
>  		}
> -		ptr += newlen;
> -		if (ptr <= endptr)
> +		offset += newlen;
> +		if (offset <= end)
>  			nr_frees++;
>  	}
>  
>  	/* We're required to fill all the space. */
> -	if (ptr != endptr)
> +	if (offset != end)
>  		xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk);
>  
>  	/* Did we see at least as many free slots as there are bestfrees? */
> -- 
> 2.20.1
> 

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

* Re: [PATCH 33/46] xfs: cleanup xfs_dir2_block_to_sf
  2019-11-07 18:23 ` [PATCH 33/46] xfs: cleanup xfs_dir2_block_to_sf Christoph Hellwig
@ 2019-11-08  0:59   ` Darrick J. Wong
  0 siblings, 0 replies; 73+ messages in thread
From: Darrick J. Wong @ 2019-11-08  0:59 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-xfs

On Thu, Nov 07, 2019 at 07:23:57PM +0100, Christoph Hellwig wrote:
> Use an offset as the main means for iteration, and only do pointer
> arithmetics to find the data/unused entries.
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>

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

--D

> ---
>  fs/xfs/libxfs/xfs_dir2_sf.c | 68 ++++++++++++++-----------------------
>  1 file changed, 25 insertions(+), 43 deletions(-)
> 
> diff --git a/fs/xfs/libxfs/xfs_dir2_sf.c b/fs/xfs/libxfs/xfs_dir2_sf.c
> index 39a537c61b04..a1aed589dc8c 100644
> --- a/fs/xfs/libxfs/xfs_dir2_sf.c
> +++ b/fs/xfs/libxfs/xfs_dir2_sf.c
> @@ -255,64 +255,48 @@ xfs_dir2_block_sfsize(
>   */
>  int						/* error */
>  xfs_dir2_block_to_sf(
> -	xfs_da_args_t		*args,		/* operation arguments */
> +	struct xfs_da_args	*args,		/* operation arguments */
>  	struct xfs_buf		*bp,
>  	int			size,		/* shortform directory size */
> -	xfs_dir2_sf_hdr_t	*sfhp)		/* shortform directory hdr */
> +	struct xfs_dir2_sf_hdr	*sfhp)		/* shortform directory hdr */
>  {
> -	xfs_dir2_data_hdr_t	*hdr;		/* block header */
> -	xfs_dir2_data_entry_t	*dep;		/* data entry pointer */
> -	xfs_inode_t		*dp;		/* incore directory inode */
> -	xfs_dir2_data_unused_t	*dup;		/* unused data pointer */
> -	char			*endptr;	/* end of data entries */
> +	struct xfs_inode	*dp = args->dp;
> +	struct xfs_mount	*mp = dp->i_mount;
>  	int			error;		/* error return value */
>  	int			logflags;	/* inode logging flags */
> -	xfs_mount_t		*mp;		/* filesystem mount point */
> -	char			*ptr;		/* current data pointer */
> -	xfs_dir2_sf_entry_t	*sfep;		/* shortform entry */
> -	xfs_dir2_sf_hdr_t	*sfp;		/* shortform directory header */
> -	xfs_dir2_sf_hdr_t	*dst;		/* temporary data buffer */
> +	struct xfs_dir2_sf_entry *sfep;		/* shortform entry */
> +	struct xfs_dir2_sf_hdr	*sfp;		/* shortform directory header */
> +	unsigned int		offset = dp->d_ops->data_entry_offset;
> +	unsigned int		end;
>  
>  	trace_xfs_dir2_block_to_sf(args);
>  
> -	dp = args->dp;
> -	mp = dp->i_mount;
> -
>  	/*
> -	 * allocate a temporary destination buffer the size of the inode
> -	 * to format the data into. Once we have formatted the data, we
> -	 * can free the block and copy the formatted data into the inode literal
> -	 * area.
> +	 * Allocate a temporary destination buffer the size of the inode to
> +	 * format the data into.  Once we have formatted the data, we can free
> +	 * the block and copy the formatted data into the inode literal area.
>  	 */
> -	dst = kmem_alloc(mp->m_sb.sb_inodesize, 0);
> -	hdr = bp->b_addr;
> -
> -	/*
> -	 * Copy the header into the newly allocate local space.
> -	 */
> -	sfp = (xfs_dir2_sf_hdr_t *)dst;
> +	sfp = kmem_alloc(mp->m_sb.sb_inodesize, 0);
>  	memcpy(sfp, sfhp, xfs_dir2_sf_hdr_size(sfhp->i8count));
>  
>  	/*
> -	 * Set up to loop over the block's entries.
> +	 * Loop over the active and unused entries.  Stop when we reach the
> +	 * leaf/tail portion of the block.
>  	 */
> -	ptr = (char *)dp->d_ops->data_entry_p(hdr);
> -	endptr = xfs_dir3_data_endp(args->geo, hdr);
> +	end = xfs_dir3_data_endp(args->geo, bp->b_addr) - bp->b_addr;
>  	sfep = xfs_dir2_sf_firstentry(sfp);
> -	/*
> -	 * Loop over the active and unused entries.
> -	 * Stop when we reach the leaf/tail portion of the block.
> -	 */
> -	while (ptr < endptr) {
> +	while (offset < end) {
> +		struct xfs_dir2_data_unused	*dup = bp->b_addr + offset;
> +		struct xfs_dir2_data_entry	*dep = bp->b_addr + offset;
> +
>  		/*
>  		 * If it's unused, just skip over it.
>  		 */
> -		dup = (xfs_dir2_data_unused_t *)ptr;
>  		if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) {
> -			ptr += be16_to_cpu(dup->length);
> +			offset += be16_to_cpu(dup->length);
>  			continue;
>  		}
> -		dep = (xfs_dir2_data_entry_t *)ptr;
> +
>  		/*
>  		 * Skip .
>  		 */
> @@ -330,9 +314,7 @@ xfs_dir2_block_to_sf(
>  		 */
>  		else {
>  			sfep->namelen = dep->namelen;
> -			xfs_dir2_sf_put_offset(sfep,
> -				(xfs_dir2_data_aoff_t)
> -				((char *)dep - (char *)hdr));
> +			xfs_dir2_sf_put_offset(sfep, offset);
>  			memcpy(sfep->name, dep->name, dep->namelen);
>  			xfs_dir2_sf_put_ino(mp, sfp, sfep,
>  					      be64_to_cpu(dep->inumber));
> @@ -341,7 +323,7 @@ xfs_dir2_block_to_sf(
>  
>  			sfep = xfs_dir2_sf_nextentry(mp, sfp, sfep);
>  		}
> -		ptr += dp->d_ops->data_entsize(dep->namelen);
> +		offset += dp->d_ops->data_entsize(dep->namelen);
>  	}
>  	ASSERT((char *)sfep - (char *)sfp == size);
>  
> @@ -360,7 +342,7 @@ xfs_dir2_block_to_sf(
>  	 * Convert the inode to local format and copy the data in.
>  	 */
>  	ASSERT(dp->i_df.if_bytes == 0);
> -	xfs_init_local_fork(dp, XFS_DATA_FORK, dst, size);
> +	xfs_init_local_fork(dp, XFS_DATA_FORK, sfp, size);
>  	dp->i_d.di_format = XFS_DINODE_FMT_LOCAL;
>  	dp->i_d.di_size = size;
>  
> @@ -368,7 +350,7 @@ xfs_dir2_block_to_sf(
>  	xfs_dir2_sf_check(args);
>  out:
>  	xfs_trans_log_inode(args->trans, dp, logflags);
> -	kmem_free(dst);
> +	kmem_free(sfp);
>  	return error;
>  }
>  
> -- 
> 2.20.1
> 

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

* Re: [PATCH 34/46] xfs: cleanup xfs_dir2_data_freescan_int
  2019-11-07 18:23 ` [PATCH 34/46] xfs: cleanup xfs_dir2_data_freescan_int Christoph Hellwig
@ 2019-11-08  1:00   ` Darrick J. Wong
  0 siblings, 0 replies; 73+ messages in thread
From: Darrick J. Wong @ 2019-11-08  1:00 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-xfs

On Thu, Nov 07, 2019 at 07:23:58PM +0100, Christoph Hellwig wrote:
> Use an offset as the main means for iteration, and only do pointer
> arithmetics to find the data/unused entries.
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>

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

--D

> ---
>  fs/xfs/libxfs/xfs_dir2_data.c | 48 +++++++++++++++--------------------
>  1 file changed, 20 insertions(+), 28 deletions(-)
> 
> diff --git a/fs/xfs/libxfs/xfs_dir2_data.c b/fs/xfs/libxfs/xfs_dir2_data.c
> index 3ecec8e1c5f6..50e3fa092ff9 100644
> --- a/fs/xfs/libxfs/xfs_dir2_data.c
> +++ b/fs/xfs/libxfs/xfs_dir2_data.c
> @@ -562,16 +562,15 @@ xfs_dir2_data_freeremove(
>   */
>  void
>  xfs_dir2_data_freescan_int(
> -	struct xfs_da_geometry	*geo,
> -	const struct xfs_dir_ops *ops,
> -	struct xfs_dir2_data_hdr *hdr,
> -	int			*loghead)
> +	struct xfs_da_geometry		*geo,
> +	const struct xfs_dir_ops	*ops,
> +	struct xfs_dir2_data_hdr	*hdr,
> +	int				*loghead)
>  {
> -	xfs_dir2_data_entry_t	*dep;		/* active data entry */
> -	xfs_dir2_data_unused_t	*dup;		/* unused data entry */
> -	struct xfs_dir2_data_free *bf;
> -	char			*endp;		/* end of block's data */
> -	char			*p;		/* current entry pointer */
> +	struct xfs_dir2_data_free	*bf = ops->data_bestfree_p(hdr);
> +	void				*addr = hdr;
> +	unsigned int			offset = ops->data_entry_offset;
> +	unsigned int			end;
>  
>  	ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) ||
>  	       hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC) ||
> @@ -581,37 +580,30 @@ xfs_dir2_data_freescan_int(
>  	/*
>  	 * Start by clearing the table.
>  	 */
> -	bf = ops->data_bestfree_p(hdr);
>  	memset(bf, 0, sizeof(*bf) * XFS_DIR2_DATA_FD_COUNT);
>  	*loghead = 1;
> -	/*
> -	 * Set up pointers.
> -	 */
> -	p = (char *)ops->data_entry_p(hdr);
> -	endp = xfs_dir3_data_endp(geo, hdr);
> -	/*
> -	 * Loop over the block's entries.
> -	 */
> -	while (p < endp) {
> -		dup = (xfs_dir2_data_unused_t *)p;
> +
> +	end = xfs_dir3_data_endp(geo, addr) - addr;
> +	while (offset < end) {
> +		struct xfs_dir2_data_unused	*dup = addr + offset;
> +		struct xfs_dir2_data_entry	*dep = addr + offset;
> +
>  		/*
>  		 * If it's a free entry, insert it.
>  		 */
>  		if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) {
> -			ASSERT((char *)dup - (char *)hdr ==
> +			ASSERT(offset ==
>  			       be16_to_cpu(*xfs_dir2_data_unused_tag_p(dup)));
>  			xfs_dir2_data_freeinsert(hdr, bf, dup, loghead);
> -			p += be16_to_cpu(dup->length);
> +			offset += be16_to_cpu(dup->length);
> +			continue;
>  		}
> +
>  		/*
>  		 * For active entries, check their tags and skip them.
>  		 */
> -		else {
> -			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);
> -		}
> +		ASSERT(offset == be16_to_cpu(*ops->data_entry_tag_p(dep)));
> +		offset += ops->data_entsize(dep->namelen);
>  	}
>  }
>  
> -- 
> 2.20.1
> 

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

* Re: [PATCH 35/46] xfs: cleanup __xfs_dir3_data_check
  2019-11-07 18:23 ` [PATCH 35/46] xfs: cleanup __xfs_dir3_data_check Christoph Hellwig
@ 2019-11-08  1:01   ` Darrick J. Wong
  0 siblings, 0 replies; 73+ messages in thread
From: Darrick J. Wong @ 2019-11-08  1:01 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-xfs

On Thu, Nov 07, 2019 at 07:23:59PM +0100, Christoph Hellwig wrote:
> Use an offset as the main means for iteration, and only do pointer
> arithmetics to find the data/unused entries.
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>

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

--D

> ---
>  fs/xfs/libxfs/xfs_dir2_data.c | 59 ++++++++++++++++++++---------------
>  1 file changed, 33 insertions(+), 26 deletions(-)
> 
> diff --git a/fs/xfs/libxfs/xfs_dir2_data.c b/fs/xfs/libxfs/xfs_dir2_data.c
> index 50e3fa092ff9..8c729270f9f1 100644
> --- a/fs/xfs/libxfs/xfs_dir2_data.c
> +++ b/fs/xfs/libxfs/xfs_dir2_data.c
> @@ -23,6 +23,22 @@ static xfs_failaddr_t xfs_dir2_data_freefind_verify(
>  		struct xfs_dir2_data_unused *dup,
>  		struct xfs_dir2_data_free **bf_ent);
>  
> +/*
> + * The number of leaf entries is limited by the size of the block and the amount
> + * of space used by the data entries.  We don't know how much space is used by
> + * the data entries yet, so just ensure that the count falls somewhere inside
> + * the block right now.
> + */
> +static inline unsigned int
> +xfs_dir2_data_max_leaf_entries(
> +	const struct xfs_dir_ops	*ops,
> +	struct xfs_da_geometry		*geo)
> +{
> +	return (geo->blksize - sizeof(struct xfs_dir2_block_tail) -
> +		ops->data_entry_offset) /
> +			sizeof(struct xfs_dir2_leaf_entry);
> +}
> +
>  /*
>   * Check the consistency of the data block.
>   * The input can also be a block-format directory.
> @@ -38,23 +54,20 @@ __xfs_dir3_data_check(
>  	xfs_dir2_block_tail_t	*btp=NULL;	/* block tail */
>  	int			count;		/* count of entries found */
>  	xfs_dir2_data_hdr_t	*hdr;		/* data block header */
> -	xfs_dir2_data_entry_t	*dep;		/* data entry */
>  	xfs_dir2_data_free_t	*dfp;		/* bestfree entry */
> -	xfs_dir2_data_unused_t	*dup;		/* unused entry */
> -	char			*endp;		/* end of useful data */
> +	void			*endp;		/* end of useful data */
>  	int			freeseen;	/* mask of bestfrees seen */
>  	xfs_dahash_t		hash;		/* hash of current name */
>  	int			i;		/* leaf index */
>  	int			lastfree;	/* last entry was unused */
>  	xfs_dir2_leaf_entry_t	*lep=NULL;	/* block leaf entries */
>  	struct xfs_mount	*mp = bp->b_mount;
> -	char			*p;		/* current data position */
>  	int			stale;		/* count of stale leaves */
>  	struct xfs_name		name;
> +	unsigned int		offset;
> +	unsigned int		end;
>  	const struct xfs_dir_ops *ops;
> -	struct xfs_da_geometry	*geo;
> -
> -	geo = mp->m_dir_geo;
> +	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
> @@ -71,7 +84,7 @@ __xfs_dir3_data_check(
>  		return __this_address;
>  
>  	hdr = bp->b_addr;
> -	p = (char *)ops->data_entry_p(hdr);
> +	offset = ops->data_entry_offset;
>  
>  	switch (hdr->magic) {
>  	case cpu_to_be32(XFS_DIR3_BLOCK_MAGIC):
> @@ -79,15 +92,8 @@ __xfs_dir3_data_check(
>  		btp = xfs_dir2_block_tail_p(geo, hdr);
>  		lep = xfs_dir2_block_leaf_p(btp);
>  
> -		/*
> -		 * The number of leaf entries is limited by the size of the
> -		 * block and the amount of space used by the data entries.
> -		 * We don't know how much space is used by the data entries yet,
> -		 * so just ensure that the count falls somewhere inside the
> -		 * block right now.
> -		 */
>  		if (be32_to_cpu(btp->count) >=
> -		    ((char *)btp - p) / sizeof(struct xfs_dir2_leaf_entry))
> +		    xfs_dir2_data_max_leaf_entries(ops, geo))
>  			return __this_address;
>  		break;
>  	case cpu_to_be32(XFS_DIR3_DATA_MAGIC):
> @@ -99,6 +105,7 @@ __xfs_dir3_data_check(
>  	endp = xfs_dir3_data_endp(geo, hdr);
>  	if (!endp)
>  		return __this_address;
> +	end = endp - bp->b_addr;
>  
>  	/*
>  	 * Account for zero bestfree entries.
> @@ -128,8 +135,10 @@ __xfs_dir3_data_check(
>  	/*
>  	 * Loop over the data/unused entries.
>  	 */
> -	while (p < endp) {
> -		dup = (xfs_dir2_data_unused_t *)p;
> +	while (offset < end) {
> +		struct xfs_dir2_data_unused	*dup = bp->b_addr + offset;
> +		struct xfs_dir2_data_entry	*dep = bp->b_addr + offset;
> +
>  		/*
>  		 * If it's unused, look for the space in the bestfree table.
>  		 * If we find it, account for that, else make sure it
> @@ -140,10 +149,10 @@ __xfs_dir3_data_check(
>  
>  			if (lastfree != 0)
>  				return __this_address;
> -			if (endp < p + be16_to_cpu(dup->length))
> +			if (offset + be16_to_cpu(dup->length) > end)
>  				return __this_address;
>  			if (be16_to_cpu(*xfs_dir2_data_unused_tag_p(dup)) !=
> -			    (char *)dup - (char *)hdr)
> +			    offset)
>  				return __this_address;
>  			fa = xfs_dir2_data_freefind_verify(hdr, bf, dup, &dfp);
>  			if (fa)
> @@ -158,7 +167,7 @@ __xfs_dir3_data_check(
>  				    be16_to_cpu(bf[2].length))
>  					return __this_address;
>  			}
> -			p += be16_to_cpu(dup->length);
> +			offset += be16_to_cpu(dup->length);
>  			lastfree = 1;
>  			continue;
>  		}
> @@ -168,15 +177,13 @@ __xfs_dir3_data_check(
>  		 * in the leaf section of the block.
>  		 * The linear search is crude but this is DEBUG code.
>  		 */
> -		dep = (xfs_dir2_data_entry_t *)p;
>  		if (dep->namelen == 0)
>  			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 (offset + ops->data_entsize(dep->namelen) > end)
>  			return __this_address;
> -		if (be16_to_cpu(*ops->data_entry_tag_p(dep)) !=
> -		    (char *)dep - (char *)hdr)
> +		if (be16_to_cpu(*ops->data_entry_tag_p(dep)) != offset)
>  			return __this_address;
>  		if (ops->data_get_ftype(dep) >= XFS_DIR3_FT_MAX)
>  			return __this_address;
> @@ -198,7 +205,7 @@ __xfs_dir3_data_check(
>  			if (i >= be32_to_cpu(btp->count))
>  				return __this_address;
>  		}
> -		p += ops->data_entsize(dep->namelen);
> +		offset += ops->data_entsize(dep->namelen);
>  	}
>  	/*
>  	 * Need to have seen all the entries and all the bestfree slots.
> -- 
> 2.20.1
> 

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

* Re: [PATCH 36/46] xfs: remove the now unused ->data_entry_p method
  2019-11-07 18:24 ` [PATCH 36/46] xfs: remove the now unused ->data_entry_p method Christoph Hellwig
@ 2019-11-08  1:02   ` Darrick J. Wong
  0 siblings, 0 replies; 73+ messages in thread
From: Darrick J. Wong @ 2019-11-08  1:02 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-xfs

On Thu, Nov 07, 2019 at 07:24:00PM +0100, Christoph Hellwig wrote:
> Now that all users use the data_entry_offset field this method is
> unused and can be removed.
> 
> 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 | 20 --------------------
>  fs/xfs/libxfs/xfs_dir2.h      |  3 ---
>  2 files changed, 23 deletions(-)
> 
> diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c
> index 347092ec28ab..e70cc54d99e1 100644
> --- a/fs/xfs/libxfs/xfs_da_format.c
> +++ b/fs/xfs/libxfs/xfs_da_format.c
> @@ -123,20 +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_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 const struct xfs_dir_ops xfs_dir2_ops = {
>  	.data_entsize = xfs_dir2_data_entsize,
>  	.data_get_ftype = xfs_dir2_data_get_ftype,
> @@ -148,8 +134,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,
>  };
>  
>  static const struct xfs_dir_ops xfs_dir2_ftype_ops = {
> @@ -163,8 +147,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,
>  };
>  
>  static const struct xfs_dir_ops xfs_dir3_ops = {
> @@ -178,8 +160,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,
>  };
>  
>  /*
> diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h
> index 75aec05aae10..a160f2d4ff37 100644
> --- a/fs/xfs/libxfs/xfs_dir2.h
> +++ b/fs/xfs/libxfs/xfs_dir2.h
> @@ -42,9 +42,6 @@ struct xfs_dir_ops {
>  
>  	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);
>  };
>  
>  extern const struct xfs_dir_ops *
> -- 
> 2.20.1
> 

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

* Re: [PATCH 37/46] xfs: replace xfs_dir3_data_endp with xfs_dir3_data_end_offset
  2019-11-07 18:24 ` [PATCH 37/46] xfs: replace xfs_dir3_data_endp with xfs_dir3_data_end_offset Christoph Hellwig
@ 2019-11-08  1:04   ` Darrick J. Wong
  0 siblings, 0 replies; 73+ messages in thread
From: Darrick J. Wong @ 2019-11-08  1:04 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-xfs

On Thu, Nov 07, 2019 at 07:24:01PM +0100, Christoph Hellwig wrote:
> All the callers really want an offset into the buffer, so adopt
> the helper to return that instead.
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>

/me feels like he's been walked down the dirent^Wgarden path...

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

--D

> ---
>  fs/xfs/libxfs/xfs_dir2.h      |  2 +-
>  fs/xfs/libxfs/xfs_dir2_data.c | 29 +++++++++++++++--------------
>  fs/xfs/libxfs/xfs_dir2_sf.c   |  2 +-
>  fs/xfs/scrub/dir.c            | 10 +++++-----
>  fs/xfs/xfs_dir2_readdir.c     |  2 +-
>  5 files changed, 23 insertions(+), 22 deletions(-)
> 
> diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h
> index a160f2d4ff37..3a4b98d4973d 100644
> --- a/fs/xfs/libxfs/xfs_dir2.h
> +++ b/fs/xfs/libxfs/xfs_dir2.h
> @@ -266,7 +266,7 @@ xfs_dir2_leaf_tail_p(struct xfs_da_geometry *geo, struct xfs_dir2_leaf *lp)
>  #define XFS_READDIR_BUFSIZE	(32768)
>  
>  unsigned char xfs_dir3_get_dtype(struct xfs_mount *mp, uint8_t filetype);
> -void *xfs_dir3_data_endp(struct xfs_da_geometry *geo,
> +unsigned int xfs_dir3_data_end_offset(struct xfs_da_geometry *geo,
>  		struct xfs_dir2_data_hdr *hdr);
>  bool xfs_dir2_namecheck(const void *name, size_t length);
>  
> diff --git a/fs/xfs/libxfs/xfs_dir2_data.c b/fs/xfs/libxfs/xfs_dir2_data.c
> index 8c729270f9f1..f5fa8b9187b0 100644
> --- a/fs/xfs/libxfs/xfs_dir2_data.c
> +++ b/fs/xfs/libxfs/xfs_dir2_data.c
> @@ -55,7 +55,6 @@ __xfs_dir3_data_check(
>  	int			count;		/* count of entries found */
>  	xfs_dir2_data_hdr_t	*hdr;		/* data block header */
>  	xfs_dir2_data_free_t	*dfp;		/* bestfree entry */
> -	void			*endp;		/* end of useful data */
>  	int			freeseen;	/* mask of bestfrees seen */
>  	xfs_dahash_t		hash;		/* hash of current name */
>  	int			i;		/* leaf index */
> @@ -102,10 +101,9 @@ __xfs_dir3_data_check(
>  	default:
>  		return __this_address;
>  	}
> -	endp = xfs_dir3_data_endp(geo, hdr);
> -	if (!endp)
> +	end = xfs_dir3_data_end_offset(geo, hdr);
> +	if (!end)
>  		return __this_address;
> -	end = endp - bp->b_addr;
>  
>  	/*
>  	 * Account for zero bestfree entries.
> @@ -590,7 +588,7 @@ xfs_dir2_data_freescan_int(
>  	memset(bf, 0, sizeof(*bf) * XFS_DIR2_DATA_FD_COUNT);
>  	*loghead = 1;
>  
> -	end = xfs_dir3_data_endp(geo, addr) - addr;
> +	end = xfs_dir3_data_end_offset(geo, addr);
>  	while (offset < end) {
>  		struct xfs_dir2_data_unused	*dup = addr + offset;
>  		struct xfs_dir2_data_entry	*dep = addr + offset;
> @@ -784,11 +782,11 @@ xfs_dir2_data_make_free(
>  {
>  	xfs_dir2_data_hdr_t	*hdr;		/* data block pointer */
>  	xfs_dir2_data_free_t	*dfp;		/* bestfree pointer */
> -	char			*endptr;	/* end of data area */
>  	int			needscan;	/* need to regen bestfree */
>  	xfs_dir2_data_unused_t	*newdup;	/* new unused entry */
>  	xfs_dir2_data_unused_t	*postdup;	/* unused entry after us */
>  	xfs_dir2_data_unused_t	*prevdup;	/* unused entry before us */
> +	unsigned int		end;
>  	struct xfs_dir2_data_free *bf;
>  
>  	hdr = bp->b_addr;
> @@ -796,8 +794,8 @@ xfs_dir2_data_make_free(
>  	/*
>  	 * Figure out where the end of the data area is.
>  	 */
> -	endptr = xfs_dir3_data_endp(args->geo, hdr);
> -	ASSERT(endptr != NULL);
> +	end = xfs_dir3_data_end_offset(args->geo, hdr);
> +	ASSERT(end != 0);
>  
>  	/*
>  	 * If this isn't the start of the block, then back up to
> @@ -816,7 +814,7 @@ xfs_dir2_data_make_free(
>  	 * If this isn't the end of the block, see if the entry after
>  	 * us is free.
>  	 */
> -	if ((char *)hdr + offset + len < endptr) {
> +	if (offset + len < end) {
>  		postdup =
>  			(xfs_dir2_data_unused_t *)((char *)hdr + offset + len);
>  		if (be16_to_cpu(postdup->freetag) != XFS_DIR2_DATA_FREE_TAG)
> @@ -1144,19 +1142,22 @@ xfs_dir2_data_use_free(
>  }
>  
>  /* Find the end of the entry data in a data/block format dir block. */
> -void *
> -xfs_dir3_data_endp(
> +unsigned int
> +xfs_dir3_data_end_offset(
>  	struct xfs_da_geometry		*geo,
>  	struct xfs_dir2_data_hdr	*hdr)
>  {
> +	void				*p;
> +
>  	switch (hdr->magic) {
>  	case cpu_to_be32(XFS_DIR3_BLOCK_MAGIC):
>  	case cpu_to_be32(XFS_DIR2_BLOCK_MAGIC):
> -		return xfs_dir2_block_leaf_p(xfs_dir2_block_tail_p(geo, hdr));
> +		p = xfs_dir2_block_leaf_p(xfs_dir2_block_tail_p(geo, hdr));
> +		return p - (void *)hdr;
>  	case cpu_to_be32(XFS_DIR3_DATA_MAGIC):
>  	case cpu_to_be32(XFS_DIR2_DATA_MAGIC):
> -		return (char *)hdr + geo->blksize;
> +		return geo->blksize;
>  	default:
> -		return NULL;
> +		return 0;
>  	}
>  }
> diff --git a/fs/xfs/libxfs/xfs_dir2_sf.c b/fs/xfs/libxfs/xfs_dir2_sf.c
> index a1aed589dc8c..bb6491a3c473 100644
> --- a/fs/xfs/libxfs/xfs_dir2_sf.c
> +++ b/fs/xfs/libxfs/xfs_dir2_sf.c
> @@ -283,7 +283,7 @@ xfs_dir2_block_to_sf(
>  	 * Loop over the active and unused entries.  Stop when we reach the
>  	 * leaf/tail portion of the block.
>  	 */
> -	end = xfs_dir3_data_endp(args->geo, bp->b_addr) - bp->b_addr;
> +	end = xfs_dir3_data_end_offset(args->geo, bp->b_addr);
>  	sfep = xfs_dir2_sf_firstentry(sfp);
>  	while (offset < end) {
>  		struct xfs_dir2_data_unused	*dup = bp->b_addr + offset;
> diff --git a/fs/xfs/scrub/dir.c b/fs/xfs/scrub/dir.c
> index 4cef21b9d336..7f03f0fb178a 100644
> --- a/fs/xfs/scrub/dir.c
> +++ b/fs/xfs/scrub/dir.c
> @@ -187,7 +187,7 @@ xchk_dir_rec(
>  	struct xfs_dir2_data_entry	*dent;
>  	struct xfs_buf			*bp;
>  	struct xfs_dir2_leaf_entry	*ent;
> -	void				*endp;
> +	unsigned int			end;
>  	unsigned int			offset;
>  	xfs_ino_t			ino;
>  	xfs_dablk_t			rec_bno;
> @@ -242,8 +242,8 @@ xchk_dir_rec(
>  
>  	/* Make sure we got a real directory entry. */
>  	offset = mp->m_dir_inode_ops->data_entry_offset;
> -	endp = xfs_dir3_data_endp(mp->m_dir_geo, bp->b_addr);
> -	if (!endp) {
> +	end = xfs_dir3_data_end_offset(mp->m_dir_geo, bp->b_addr);
> +	if (!end) {
>  		xchk_fblock_set_corrupt(ds->sc, XFS_DATA_FORK, rec_bno);
>  		goto out_relse;
>  	}
> @@ -251,7 +251,7 @@ xchk_dir_rec(
>  		struct xfs_dir2_data_entry	*dep = bp->b_addr + offset;
>  		struct xfs_dir2_data_unused	*dup = bp->b_addr + offset;
>  	
> -		if (offset >= endp - bp->b_addr) {
> +		if (offset >= end) {
>  			xchk_fblock_set_corrupt(ds->sc, XFS_DATA_FORK, rec_bno);
>  			goto out_relse;
>  		}
> @@ -390,7 +390,7 @@ xchk_directory_data_bestfree(
>  
>  	/* Make sure the bestfrees are actually the best free spaces. */
>  	offset = d_ops->data_entry_offset;
> -	end = xfs_dir3_data_endp(mp->m_dir_geo, bp->b_addr) - bp->b_addr;
> +	end = xfs_dir3_data_end_offset(mp->m_dir_geo, bp->b_addr);
>  
>  	/* Iterate the entries, stopping when we hit or go past the end. */
>  	while (offset < end) {
> diff --git a/fs/xfs/xfs_dir2_readdir.c b/fs/xfs/xfs_dir2_readdir.c
> index c4314e9e3dd8..6d229aa93d01 100644
> --- a/fs/xfs/xfs_dir2_readdir.c
> +++ b/fs/xfs/xfs_dir2_readdir.c
> @@ -175,7 +175,7 @@ xfs_dir2_block_getdents(
>  	 * Each object is a real entry (dep) or an unused one (dup).
>  	 */
>  	offset = dp->d_ops->data_entry_offset;
> -	end = xfs_dir3_data_endp(geo, bp->b_addr) - bp->b_addr;
> +	end = xfs_dir3_data_end_offset(geo, bp->b_addr);
>  	while (offset < end) {
>  		struct xfs_dir2_data_unused	*dup = bp->b_addr + offset;
>  		struct xfs_dir2_data_entry	*dep = bp->b_addr + offset;
> -- 
> 2.20.1
> 

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

* Re: [PATCH 41/46] xfs: cleanup xfs_dir2_data_entsize
  2019-11-07 18:24 ` [PATCH 41/46] xfs: cleanup xfs_dir2_data_entsize Christoph Hellwig
@ 2019-11-08  1:05   ` Darrick J. Wong
  2019-11-08  5:43     ` Christoph Hellwig
  0 siblings, 1 reply; 73+ messages in thread
From: Darrick J. Wong @ 2019-11-08  1:05 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-xfs

On Thu, Nov 07, 2019 at 07:24:05PM +0100, Christoph Hellwig wrote:
> Remove the XFS_DIR2_DATA_ENTSIZE and XFS_DIR3_DATA_ENTSIZE and open
> code them in their only caller, which now becomes so simple that
> we can turn it into an inline function.
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
>  fs/xfs/libxfs/xfs_da_format.c | 33 ---------------------------------
>  fs/xfs/libxfs/xfs_dir2_priv.h | 15 ++++++++++++++-
>  2 files changed, 14 insertions(+), 34 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_priv.h b/fs/xfs/libxfs/xfs_dir2_priv.h
> index a6c3fb3a2f7b..54bbfdd6ad69 100644
> --- a/fs/xfs/libxfs/xfs_dir2_priv.h
> +++ b/fs/xfs/libxfs/xfs_dir2_priv.h
> @@ -57,7 +57,6 @@ 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);
>  __be16 *xfs_dir2_data_entry_tag_p(struct xfs_mount *mp,
>  		struct xfs_dir2_data_entry *dep);
>  
> @@ -172,4 +171,18 @@ extern xfs_failaddr_t xfs_dir2_sf_verify(struct xfs_inode *ip);
>  extern int xfs_readdir(struct xfs_trans *tp, struct xfs_inode *dp,
>  		       struct dir_context *ctx, size_t bufsize);
>  
> +static inline int
> +xfs_dir2_data_entsize(
> +	struct xfs_mount	*mp,
> +	int			namelen)

Why not unsigned int here?  Neither names nor entries can have negative
length.  Other than that, looks fine...

--D

> +{
> +	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);
> +}
> +
>  #endif /* __XFS_DIR2_PRIV_H__ */
> -- 
> 2.20.1
> 

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

* Re: [PATCH 15/46] xfs: make the xfs_dir3_icfree_hdr available to xfs_dir2_node_addname_int
  2019-11-07 18:23 ` [PATCH 15/46] xfs: make the xfs_dir3_icfree_hdr available to xfs_dir2_node_addname_int Christoph Hellwig
@ 2019-11-08  1:06   ` Darrick J. Wong
  0 siblings, 0 replies; 73+ messages in thread
From: Darrick J. Wong @ 2019-11-08  1:06 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-xfs

On Thu, Nov 07, 2019 at 07:23:39PM +0100, 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 where we'll use the ichdr in xfs_dir3_icfree_hdr
> to avoid extra operations to find the bests pointers.
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>

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

--D

> ---
>  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 4e49ac64a2ff..6d67ceac48b7 100644
> --- a/fs/xfs/libxfs/xfs_dir2_node.c
> +++ b/fs/xfs/libxfs/xfs_dir2_node.c
> @@ -1666,14 +1666,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;
> @@ -1736,25 +1735,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);
>  	}
>  
> @@ -1763,14 +1762,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;
> @@ -1784,10 +1782,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;
> @@ -1814,13 +1812,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;
>  		}
>  
> @@ -1864,13 +1861,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;
>  			}
>  		}
> @@ -1904,6 +1901,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;
> @@ -1918,8 +1916,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;
>  
> @@ -1941,7 +1939,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] 73+ messages in thread

* Re: [PATCH 30/46] xfs: cleanup xfs_dir2_leaf_getdents
  2019-11-07 22:41   ` Darrick J. Wong
@ 2019-11-08  5:26     ` Christoph Hellwig
  0 siblings, 0 replies; 73+ messages in thread
From: Christoph Hellwig @ 2019-11-08  5:26 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: Christoph Hellwig, linux-xfs

On Thu, Nov 07, 2019 at 02:41:57PM -0800, Darrick J. Wong wrote:
> On Thu, Nov 07, 2019 at 07:23:54PM +0100, Christoph Hellwig wrote:
> > Use an offset as the main means for iteration, and only do pointer
> > arithmetics to find the data/unused entries.
> > 
> > Signed-off-by: Christoph Hellwig <hch@lst.de>
> > ---
> >  fs/xfs/xfs_dir2_readdir.c | 34 +++++++++++++++++-----------------
> >  1 file changed, 17 insertions(+), 17 deletions(-)
> > 
> > diff --git a/fs/xfs/xfs_dir2_readdir.c b/fs/xfs/xfs_dir2_readdir.c
> > index 0d234b649d65..c4314e9e3dd8 100644
> > --- a/fs/xfs/xfs_dir2_readdir.c
> > +++ b/fs/xfs/xfs_dir2_readdir.c
> > @@ -351,13 +351,13 @@ xfs_dir2_leaf_getdents(
> >  	xfs_dir2_data_hdr_t	*hdr;		/* data block header */
> 
> gcc complained about this variable being set but not used.

Your gcc is obviously smarted than mine, because it is unused.

> 
> >  	xfs_dir2_data_entry_t	*dep;		/* data entry */
> >  	xfs_dir2_data_unused_t	*dup;		/* unused entry */
> > -	char			*ptr = NULL;	/* pointer to current data */
> >  	struct xfs_da_geometry	*geo = args->geo;
> >  	xfs_dablk_t		rablk = 0;	/* current readahead block */
> >  	xfs_dir2_off_t		curoff;		/* current overall offset */
> >  	int			length;		/* temporary length value */
> >  	int			byteoff;	/* offset in current block */
> >  	int			lock_mode;
> > +	unsigned int		offset = 0;
> 
> This is the offset within the block, right?

Yes.

> 
> >  	int			error = 0;	/* error return value */
> >  
> >  	/*
> > @@ -384,7 +384,7 @@ xfs_dir2_leaf_getdents(
> >  		 * If we have no buffer, or we're off the end of the
> >  		 * current buffer, need to get another one.
> >  		 */
> > -		if (!bp || ptr >= (char *)bp->b_addr + geo->blksize) {
> > +		if (!bp || offset + geo->blksize) {
> 
>                            ^^^^^^^^^^^^^^^^^^^^^
> 
> In which case, isn't this always true?  Was this supposed to be
> offset >= geo->blksize?

Yes, fixed up now.

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

* Re: [PATCH 03/46] xfs: refactor btree node scrubbing
  2019-11-07 22:43   ` Darrick J. Wong
@ 2019-11-08  5:28     ` Christoph Hellwig
  0 siblings, 0 replies; 73+ messages in thread
From: Christoph Hellwig @ 2019-11-08  5:28 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: Christoph Hellwig, linux-xfs

> >  /* 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);
> 
> This eliminates the only user of blks, which means the variable can be
> removed.  The rest looks fine though.

Fixed.

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

* Re: [PATCH 31/46] xfs: cleanup xchk_dir_rec
  2019-11-08  0:57   ` Darrick J. Wong
@ 2019-11-08  5:38     ` Christoph Hellwig
  0 siblings, 0 replies; 73+ messages in thread
From: Christoph Hellwig @ 2019-11-08  5:38 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: Christoph Hellwig, linux-xfs

On Thu, Nov 07, 2019 at 04:57:00PM -0800, Darrick J. Wong wrote:
> >  	struct xfs_dir2_data_entry	*dent;
> >  	struct xfs_buf			*bp;
> >  	struct xfs_dir2_leaf_entry	*ent;
> > -	char				*p, *endp;
> > +	void				*endp;
> > +	unsigned int			offset;
> 
> Can this be named iter_off or something?  There's already an @off variable
> which is the offset-within-block that wa calculated from the entry pointer.

Ok.

> > +		struct xfs_dir2_data_entry	*dep = bp->b_addr + offset;
> > +		struct xfs_dir2_data_unused	*dup = bp->b_addr + offset;
> > +	
> 
> Extra whitespace.

Fixed.

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

* Re: [PATCH 41/46] xfs: cleanup xfs_dir2_data_entsize
  2019-11-08  1:05   ` Darrick J. Wong
@ 2019-11-08  5:43     ` Christoph Hellwig
  0 siblings, 0 replies; 73+ messages in thread
From: Christoph Hellwig @ 2019-11-08  5:43 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: Christoph Hellwig, linux-xfs

On Thu, Nov 07, 2019 at 05:05:58PM -0800, Darrick J. Wong wrote:
> > +static inline int
> > +xfs_dir2_data_entsize(
> > +	struct xfs_mount	*mp,
> > +	int			namelen)
> 
> Why not unsigned int here?  Neither names nor entries can have negative
> length.  Other than that, looks fine...

Ok, updated.

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

end of thread, other threads:[~2019-11-08  5:43 UTC | newest]

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

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.