From 6bd73d163462f5c0ca78197ec2d8d6f7392974d1 Mon Sep 17 00:00:00 2001 From: Eric Sandeen Date: Thu, 27 Feb 2020 14:21:45 -0500 Subject: [PATCH] xfs_repair: fix bad next_unlinked field As of xfsprogs-4.17 we started testing whether the di_next_unlinked field on an inode is valid in the inode verifiers. However, this field is never tested or repaired during inode processing. So if, for example, we had a completely zeroed-out inode, we'd detect and fix the broken magic and version, but the invalid di_next_unlinked field would not be touched, fail the write verifier, and prevent the inode from being properly repaired or even written out. Fix this by checking the di_next_unlinked inode field for validity and clearing it if it is invalid. Reported-by: John Jore Fixes: 2949b4677 ("xfs: don't accept inode buffers with suspicious unlinked chains") Signed-off-by: Eric Sandeen Reviewed-by: Darrick J. Wong Signed-off-by: Eric Sandeen --- repair/dinode.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/repair/dinode.c b/repair/dinode.c index 8af2cb259..929ec8170 100644 --- a/repair/dinode.c +++ b/repair/dinode.c @@ -2272,6 +2272,7 @@ process_dinode_int(xfs_mount_t *mp, const int is_free = 0; const int is_used = 1; blkmap_t *dblkmap = NULL; + xfs_agino_t unlinked_ino; *dirty = *isa_dir = 0; *used = is_used; @@ -2351,6 +2352,23 @@ process_dinode_int(xfs_mount_t *mp, } } + unlinked_ino = be32_to_cpu(dino->di_next_unlinked); + if (!xfs_verify_agino_or_null(mp, agno, unlinked_ino)) { + retval = 1; + if (!uncertain) + do_warn(_("bad next_unlinked 0x%x on inode %" PRIu64 "%c"), + be32_to_cpu(dino->di_next_unlinked), lino, + verify_mode ? '\n' : ','); + if (!verify_mode) { + if (!no_modify) { + do_warn(_(" resetting next_unlinked\n")); + clear_dinode_unlinked(mp, dino); + *dirty = 1; + } else + do_warn(_(" would reset next_unlinked\n")); + } + } + /* * We don't bother checking the CRC here - we cannot guarantee that when * we are called here that the inode has not already been modified in -- 2.47.2