File xfsprogs-xfs_repair-rebuild-directory-when-non-root-leafn-blo.patch of Package xfsprogs.21555

From 3d2195e4ae45c142be8ec4600d44f23e31cf0cf2 Mon Sep 17 00:00:00 2001
From: "Darrick J. Wong" <darrick.wong@oracle.com>
Date: Wed, 12 Dec 2018 11:42:40 -0600
Subject: [PATCH] xfs_repair: rebuild directory when non-root leafn blocks
 claim block 0
Git-commit: 3d2195e4ae45c142be8ec4600d44f23e31cf0cf2
Patch-mainline: v4.20.0-rc1
References: bsc#1181309

As explained in

71a6af8 Revert "xfs_repair: treat zero da btree pointers as corruption"

a single root LEAFN block can exist in a directory until it grows
further.

This is why, normally, we skip directories with a root marked
XFS_DIR2_LEAFN_MAGIC, as detected by the left-most leaf block being
found at file block 0.

However, if we traversed any level of a btree to get here (as
indicated by da_cursor.active > 0), then a leaf block claiming block
0 indicates corruption, and we should handle it as such, and rebuild
the directory.

This was found by repair repeatedly rebuilding a directory containing a
single leafn block (xfs/495).

Fixes: 67a79e2cc932 ("xfs_repair: treat zero da btree pointers as corruption")
Reported-by: Dave Chinner <david@fromorbit.com>
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
[sandeen: clarify commit log, refer to revert commit]
Reviewed-by: Eric Sandeen <sandeen@redhat.com>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
Acked-by: Anthony Iliopoulos <ailiop@suse.com>

---
 repair/dir2.c | 15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/repair/dir2.c b/repair/dir2.c
index ba5763ed3d26..e67ec590c091 100644
--- a/repair/dir2.c
+++ b/repair/dir2.c
@@ -1243,10 +1243,21 @@ process_node_dir2(

 	/*
 	 * Skip directories with a root marked XFS_DIR2_LEAFN_MAGIC
+	 *
+	 * Be careful here: If any level of the da cursor was filled out then
+	 * the directory has a da btree containing an invalid before pointer to
+	 * dblock 0, and we should move on to rebuilding the directory.  If no
+	 * levels in the da cursor got filled out, then we just have a single
+	 * leafn block and we're done.
 	 */
 	if (bno == 0) {
-		release_da_cursor(mp, &da_cursor, 0);
-		return 0;
+		if (da_cursor.active > 0) {
+			err_release_da_cursor(mp, &da_cursor, 0);
+			return 1;
+		} else {
+			release_da_cursor(mp, &da_cursor, 0);
+			return 0;
+		}
 	} else {
 		/*
 		 * Now pass cursor and bno into leaf-block processing routine.
--
2.30.0
openSUSE Build Service is sponsored by