xfs: don't spin forever on zero-length dirents when salvaging them

LOLLM noticed that xrep_dir_recover_data can spin forever if it
encounters an unused dirent that claims to have length zero.  Fix that,
and prevent the same thing from happening with a zero-length entry.

Cc: stable@vger.kernel.org # v6.10
Fixes: b1991ee3e7 ("xfs: online repair of directories")
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Assisted-by: LOLLM # finding obvious bugs
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
This commit is contained in:
Darrick J. Wong 2026-08-26 22:31:10 -07:00 committed by Carlos Maiolino
parent 0fe77e5758
commit 9f84792b40

View File

@ -484,18 +484,24 @@ xrep_dir_recover_data(
while (offset < end) {
struct xfs_dir2_data_unused *dup = bp->b_addr + offset;
struct xfs_dir2_data_entry *dep = bp->b_addr + offset;
unsigned int advance;
if (xchk_should_terminate(rd->sc, &error))
return error;
/* Skip unused entries. */
if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) {
if (!dup->length)
break;
offset += be16_to_cpu(dup->length);
continue;
}
/* Don't walk off the end of the block. */
offset += xfs_dir2_data_entsize(rd->sc->mp, dep->namelen);
advance = xfs_dir2_data_entsize(rd->sc->mp, dep->namelen);
if (!advance)
break;
offset += advance;
if (offset > end)
break;