[2/3] xfs_repair: never zero a shortform '..' entry
diff mbox series

Message ID 159476320951.3156851.9608086404704132538.stgit@magnolia
State New
Headers show
Series
  • xfs: preparation for syncing with 5.8
Related show

Commit Message

Darrick J. Wong July 14, 2020, 9:46 p.m. UTC
From: Darrick J. Wong <darrick.wong@oracle.com>

Repair has this strange behavior during phase 4 where it will zero the
parent pointer entry of a shortform directory if the pointer is
obviously invalid.  Unfortunately, this causes the inode fork verifiers
to fail, so change it to reset bad pointers (ondisk) to the root
directory.  If repair crashes, a subsequent run will notice the
incorrect parent pointer and either fix the dir or move it to
lost+found.

Note that we maintain the practice of setting the *incore* parent to
NULLFSINO so that phase 7 knows that it has to fix the directory.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 repair/dir2.c |   13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

Comments

Christoph Hellwig July 15, 2020, 6:44 p.m. UTC | #1
On Tue, Jul 14, 2020 at 02:46:49PM -0700, Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
> 
> Repair has this strange behavior during phase 4 where it will zero the
> parent pointer entry of a shortform directory if the pointer is
> obviously invalid.  Unfortunately, this causes the inode fork verifiers
> to fail, so change it to reset bad pointers (ondisk) to the root
> directory.  If repair crashes, a subsequent run will notice the
> incorrect parent pointer and either fix the dir or move it to
> lost+found.
> 
> Note that we maintain the practice of setting the *incore* parent to
> NULLFSINO so that phase 7 knows that it has to fix the directory.

I think we probably want to take Brians series instead, which does
a few more things in the area.

Patch
diff mbox series

diff --git a/repair/dir2.c b/repair/dir2.c
index b374bc7b..61e1aaaf 100644
--- a/repair/dir2.c
+++ b/repair/dir2.c
@@ -165,7 +165,6 @@  process_sf_dir2(
 	int			tmp_elen;
 	int			tmp_len;
 	xfs_dir2_sf_entry_t	*tmp_sfep;
-	xfs_ino_t		zero = 0;
 
 	sfp = (struct xfs_dir2_sf_hdr *)XFS_DFORK_DPTR(dip);
 	max_size = XFS_DFORK_DSIZE(dip, mp);
@@ -494,7 +493,11 @@  _("bogus .. inode number (%" PRIu64 ") in directory inode %" PRIu64 ", "),
 		if (!no_modify)  {
 			do_warn(_("clearing inode number\n"));
 
-			libxfs_dir2_sf_put_parent_ino(sfp, zero);
+			/*
+			 * Set the ondisk parent to the root inode so that we
+			 * never write garbage parent pointers to disk.
+			 */
+			libxfs_dir2_sf_put_parent_ino(sfp, mp->m_sb.sb_rootino);
 			*dino_dirty = 1;
 			*repair = 1;
 		} else  {
@@ -529,7 +532,11 @@  _("bad .. entry in directory inode %" PRIu64 ", points to self, "),
 		if (!no_modify)  {
 			do_warn(_("clearing inode number\n"));
 
-			libxfs_dir2_sf_put_parent_ino(sfp, zero);
+			/*
+			 * Set the ondisk parent to the root inode so that we
+			 * never write garbage parent pointers to disk.
+			 */
+			libxfs_dir2_sf_put_parent_ino(sfp, mp->m_sb.sb_rootino);
 			*dino_dirty = 1;
 			*repair = 1;
 		} else  {