Skip to content

Commit 87b7c20

Browse files
author
Darrick J. Wong
committed
xfs: confirm dotdot target before replacing it during a repair
xfs_dir_replace trips an assertion if you tell it to change a dirent to point to an inumber that it already points at. Look up the dotdot entry directly to confirm that we need to make a change. Signed-off-by: Darrick J. Wong <[email protected]> Reviewed-by: Christoph Hellwig <[email protected]>
1 parent b3c03ef commit 87b7c20

File tree

1 file changed

+8
-4
lines changed

1 file changed

+8
-4
lines changed

fs/xfs/scrub/dir_repair.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1638,6 +1638,7 @@ xrep_dir_swap(
16381638
struct xrep_dir *rd)
16391639
{
16401640
struct xfs_scrub *sc = rd->sc;
1641+
xfs_ino_t ino;
16411642
bool ip_local, temp_local;
16421643
int error = 0;
16431644

@@ -1655,14 +1656,17 @@ xrep_dir_swap(
16551656

16561657
/*
16571658
* Reset the temporary directory's '..' entry to point to the parent
1658-
* that we found. The temporary directory was created with the root
1659-
* directory as the parent, so we can skip this if repairing a
1660-
* subdirectory of the root.
1659+
* that we found. The dirent replace code asserts if the dirent
1660+
* already points at the new inumber, so we look it up here.
16611661
*
16621662
* It's also possible that this replacement could also expand a sf
16631663
* tempdir into block format.
16641664
*/
1665-
if (rd->pscan.parent_ino != sc->mp->m_rootip->i_ino) {
1665+
error = xchk_dir_lookup(sc, rd->sc->tempip, &xfs_name_dotdot, &ino);
1666+
if (error)
1667+
return error;
1668+
1669+
if (rd->pscan.parent_ino != ino) {
16661670
error = xrep_dir_replace(rd, rd->sc->tempip, &xfs_name_dotdot,
16671671
rd->pscan.parent_ino, rd->tx.req.resblks);
16681672
if (error)

0 commit comments

Comments
 (0)