All of lore.kernel.org
 help / color / mirror / Atom feed
From: Christoph Hellwig <hch@lst.de>
To: "Darrick J. Wong" <darrick.wong@oracle.com>
Cc: Brian Foster <bfoster@redhat.com>, Christoph Hellwig <hch@lst.de>,
	linux-xfs@vger.kernel.org
Subject: Re: [PATCH 08/12] xfs: remove xfs_ifork_ops
Date: Fri, 1 May 2020 18:38:09 +0200	[thread overview]
Message-ID: <20200501163809.GA18426@lst.de> (raw)
In-Reply-To: <20200501160809.GT6742@magnolia>

On Fri, May 01, 2020 at 09:08:09AM -0700, Darrick J. Wong wrote:
> > I'm not sure the cleanup is worth the kludge of including repair code in
> > the kernel like this. It might be better to reduce or replace ifork_ops
> > to a single directory function pointer until there's a reason for this
> > to become common. I dunno, maybe others have thoughts...

The whole point is trying to avoid calling function pointers and
keeping that cruft around.

> 
> One of the online repair gaps I haven't figured out how to close yet is
> what to do when there's a short format directory that fails validation
> (such that iget fails).  The inode repairer gets stuck with the job of
> fixing the sf dir, but the (future) directory repair code will have all
> the expertise in fixing directories.  Regrettably, it also requires a
> working xfs_inode.
> 
> So I could just set the sf parent to some obviously garbage value (like
> repair does) to make the verifiers pass and then trip the directory
> repair, and then this hunk would be useful to have in the kernel.  OTOH
> that means more special case flags and other junk, just to end up with
> this kludge that sucks even for xfs_repair.

That being said my approach here was a little too dumb.  Once we are
all in the same code base we can stop the stupid patching of the
parent and just handle the case directly.  Something like this
incremental diff on top of the sent out version (not actually tested).

Total diffstate with the original patch is:

 4 files changed, 37 insertions(+), 35 deletions(-)

and this should also help with online repair while killing a horrible
kludge.


diff --git a/fs/xfs/libxfs/xfs_dir2_sf.c b/fs/xfs/libxfs/xfs_dir2_sf.c
index 1f6c30b68917c..b4195fafe2172 100644
--- a/fs/xfs/libxfs/xfs_dir2_sf.c
+++ b/fs/xfs/libxfs/xfs_dir2_sf.c
@@ -704,9 +704,17 @@ xfs_dir2_sf_check(
 }
 #endif	/* DEBUG */
 
+/*
+ * Allow xfs_repair to enable the parent bypass mode.  For now this is entirely
+ * unused in the kernel, but might come in useful for online repair eventually.
+ */
+#ifndef xfs_inode_parent_bypass
+#define xfs_inode_parent_bypass(ip)	0
+#endif
+
 /* Verify the consistency of an inline directory. */
-static xfs_failaddr_t
-__xfs_dir2_sf_verify(
+xfs_failaddr_t
+xfs_dir2_sf_verify(
 	struct xfs_inode		*ip)
 {
 	struct xfs_mount		*mp = ip->i_mount;
@@ -738,12 +746,26 @@ __xfs_dir2_sf_verify(
 
 	endp = (char *)sfp + size;
 
-	/* Check .. entry */
-	ino = xfs_dir2_sf_get_parent_ino(sfp);
-	i8count = ino > XFS_DIR2_MAX_SHORT_INUM;
-	error = xfs_dir_ino_validate(mp, ino);
-	if (error)
-		return __this_address;
+	/*
+	 * Check the .. entry.
+	 *
+	 * If we are running a repair, phase4 may have set the parent inode to
+	 * zero to indicate that it must be fixed.  Skip validating the parent
+	 * in that case.
+	 */
+	if (likely(!xfs_inode_parent_bypass(ip))) {
+		ino = xfs_dir2_sf_get_parent_ino(sfp);
+		i8count = ino > XFS_DIR2_MAX_SHORT_INUM;
+		error = xfs_dir_ino_validate(mp, ino);
+		if (error)
+			return __this_address;
+	} else {
+		/*
+		 * Ensure we account the missing parent as in the right format.
+		 */
+		if (sfp->i8count)
+			i8count++;
+	}
 	offset = mp->m_dir_geo->data_first_offset;
 
 	/* Check all reported entries */
@@ -804,66 +826,6 @@ __xfs_dir2_sf_verify(
 	return NULL;
 }
 
-/*
- * When we're checking directory inodes, we're allowed to set a directory's
- * dotdot entry to zero to signal that the parent needs to be reconnected
- * during xfs_repair phase 6.  If we're handling a shortform directory the ifork
- * verifiers will fail, so temporarily patch out this canary so that we can
- * verify the rest of the fork and move on to fixing the dir.
- */
-static xfs_failaddr_t
-xfs_dir2_sf_verify_dir_check(
-	struct xfs_inode		*ip)
-{
-	struct xfs_mount		*mp = ip->i_mount;
-	struct xfs_ifork		*ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK);
-	struct xfs_dir2_sf_hdr		*sfp =
-		(struct xfs_dir2_sf_hdr *)ifp->if_u1.if_data;
-	int				size = ifp->if_bytes;
-	bool				parent_bypass = false;
-	xfs_ino_t			old_parent;
-	xfs_failaddr_t			fa;
-
-	/*
-	 * If this is a shortform directory, phase4 in xfs_repair may have set
-	 * the parent inode to zero to indicate that it must be fixed.
-	 * Temporarily set a valid parent so that the directory verifier will
-	 * pass.
-	 */
-	if (size > offsetof(struct xfs_dir2_sf_hdr, parent) &&
-	    size >= xfs_dir2_sf_hdr_size(sfp->i8count)) {
-		old_parent = xfs_dir2_sf_get_parent_ino(sfp);
-		if (!old_parent) {
-			xfs_dir2_sf_put_parent_ino(sfp, mp->m_sb.sb_rootino);
-			parent_bypass = true;
-		}
-	}
-
-	fa = __xfs_dir2_sf_verify(ip);
-
-	/* Put it back. */
-	if (parent_bypass)
-		xfs_dir2_sf_put_parent_ino(sfp, old_parent);
-	return fa;
-}
-
-/*
- * Allow xfs_repair to enable the parent bypass mode.  For now this is entirely
- * unused in the kernel, but might come in useful for online repair eventually.
- */
-#ifndef xfs_inode_parent_bypass
-#define xfs_inode_parent_bypass(ip)	0
-#endif
-
-xfs_failaddr_t
-xfs_dir2_sf_verify(
-	struct xfs_inode		*ip)
-{
-	if (xfs_inode_parent_bypass(ip))
-		return xfs_dir2_sf_verify_dir_check(ip);
-	return __xfs_dir2_sf_verify(ip);
-}
-
 /*
  * Create a new (shortform) directory.
  */

  reply	other threads:[~2020-05-01 16:38 UTC|newest]

Thread overview: 46+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-05-01  8:14 dinode reading cleanups Christoph Hellwig
2020-05-01  8:14 ` [PATCH 01/12] xfs: xfs_bmapi_read doesn't take a fork id as the last argument Christoph Hellwig
2020-05-01 13:33   ` Brian Foster
2020-05-01  8:14 ` [PATCH 02/12] xfs: call xfs_iformat_fork from xfs_inode_from_disk Christoph Hellwig
2020-05-01 13:33   ` Brian Foster
2020-05-01  8:14 ` [PATCH 03/12] xfs: split xfs_iformat_fork Christoph Hellwig
2020-05-01 13:34   ` Brian Foster
2020-05-07 12:27     ` Christoph Hellwig
2020-05-07 13:40       ` Brian Foster
2020-05-07 13:42         ` Christoph Hellwig
2020-05-01  8:14 ` [PATCH 04/12] xfs: handle unallocated inodes in xfs_inode_from_disk Christoph Hellwig
2020-05-01 13:34   ` Brian Foster
2020-05-01  8:14 ` [PATCH 05/12] xfs: call xfs_dinode_verify from xfs_inode_from_disk Christoph Hellwig
2020-05-01 13:34   ` Brian Foster
2020-05-01  8:14 ` [PATCH 06/12] xfs: don't reset i_delayed_blks in xfs_iread Christoph Hellwig
2020-05-01 13:34   ` Brian Foster
2020-05-01  8:14 ` [PATCH 07/12] xfs: remove xfs_iread Christoph Hellwig
2020-05-01 15:56   ` Brian Foster
2020-05-01  8:14 ` [PATCH 08/12] xfs: remove xfs_ifork_ops Christoph Hellwig
2020-05-01 15:56   ` Brian Foster
2020-05-01 16:08     ` Darrick J. Wong
2020-05-01 16:38       ` Christoph Hellwig [this message]
2020-05-01 16:50         ` Christoph Hellwig
2020-05-01 18:23           ` Brian Foster
2020-05-07 12:34             ` Christoph Hellwig
2020-05-07 13:43               ` Brian Foster
2020-05-07 16:28                 ` Brian Foster
2020-05-07 17:18                   ` Christoph Hellwig
2020-05-12 23:50                     ` Darrick J. Wong
2020-05-01  8:14 ` [PATCH 09/12] xfs: refactor xfs_inode_verify_forks Christoph Hellwig
2020-05-01 15:57   ` Brian Foster
2020-05-01 16:40     ` Christoph Hellwig
2020-05-01 17:02       ` Brian Foster
2020-05-01 17:08         ` Christoph Hellwig
2020-05-01  8:14 ` [PATCH 10/12] xfs: improve local fork verification Christoph Hellwig
2020-05-01  8:14 ` [PATCH 11/12] xfs: remove the special COW fork handling in xfs_bmapi_read Christoph Hellwig
2020-05-01 15:57   ` Brian Foster
2020-05-01  8:14 ` [PATCH 12/12] xfs: remove the NULL " Christoph Hellwig
2020-05-01 15:58   ` Brian Foster
2020-05-08  6:34 dinode reading cleanups v2 Christoph Hellwig
2020-05-08  6:34 ` [PATCH 08/12] xfs: remove xfs_ifork_ops Christoph Hellwig
2020-05-08 15:05   ` Brian Foster
2020-05-09  8:17     ` Christoph Hellwig
2020-05-09 11:13       ` Brian Foster
2020-05-16 17:48         ` Darrick J. Wong
2020-05-18 13:35           ` Brian Foster
2020-05-18 16:07             ` Darrick J. Wong

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200501163809.GA18426@lst.de \
    --to=hch@lst.de \
    --cc=bfoster@redhat.com \
    --cc=darrick.wong@oracle.com \
    --cc=linux-xfs@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.