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>
/*
* 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.