From: Darrick J. Wong Date: Mon, 29 Jul 2024 23:23:26 +0000 (-0700) Subject: xfs_repair: junk duplicate hashtab entries when processing sf dirents X-Git-Tag: v6.10.0~6^2~7 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=27e6390054c4f250728b687421e3afd99e0695e5;p=thirdparty%2Fxfsprogs-dev.git xfs_repair: junk duplicate hashtab entries when processing sf dirents dir_hash_add() adds the passed-in dirent to the directory hashtab even if there's already a duplicate. Therefore, if we detect a duplicate or a garbage entry while processing the a shortform directory's entries, we need to junk the newly added entry, just like we do when processing directory data blocks. This will become particularly relevant in the next patch, where we generate a master index of parent pointers from the non-junked hashtab entries of each directory that phase6 scans. Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig --- diff --git a/repair/phase6.c b/repair/phase6.c index 791f7d36..9d41aad7 100644 --- a/repair/phase6.c +++ b/repair/phase6.c @@ -2562,6 +2562,7 @@ shortform_dir2_entry_check( struct xfs_dir2_sf_entry *next_sfep; struct xfs_ifork *ifp; struct ino_tree_node *irec; + xfs_dir2_dataptr_t diroffset; int max_size; int ino_offset; int i; @@ -2739,8 +2740,9 @@ shortform_dir2_entry_check( /* * check for duplicate names in directory. */ - dup_inum = dir_hash_add(mp, hashtab, (xfs_dir2_dataptr_t) - (sfep - xfs_dir2_sf_firstentry(sfp)), + diroffset = xfs_dir2_byte_to_dataptr( + xfs_dir2_sf_get_offset(sfep)); + dup_inum = dir_hash_add(mp, hashtab, diroffset, lino, sfep->namelen, sfep->name, libxfs_dir2_sf_get_ftype(mp, sfep)); if (dup_inum != NULLFSINO) { @@ -2775,6 +2777,7 @@ _("entry \"%s\" (ino %" PRIu64 ") in dir %" PRIu64 " already points to ino %" PR next_sfep = shortform_dir2_junk(mp, sfp, sfep, lino, &max_size, &i, &bytes_deleted, ino_dirty); + dir_hash_junkit(hashtab, diroffset); continue; } else if (parent == ino) { add_inode_reached(irec, ino_offset); @@ -2799,6 +2802,7 @@ _("entry \"%s\" (ino %" PRIu64 ") in dir %" PRIu64 " already points to ino %" PR next_sfep = shortform_dir2_junk(mp, sfp, sfep, lino, &max_size, &i, &bytes_deleted, ino_dirty); + dir_hash_junkit(hashtab, diroffset); continue; } }