mirror of
https://github.com/torvalds/linux.git
synced 2024-11-21 19:41:42 +00:00
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 <djwong@kernel.org> Reviewed-by: Christoph Hellwig <hch@lst.de>
This commit is contained in:
parent
b3c03efa59
commit
87b7c205da
@ -1638,6 +1638,7 @@ xrep_dir_swap(
|
||||
struct xrep_dir *rd)
|
||||
{
|
||||
struct xfs_scrub *sc = rd->sc;
|
||||
xfs_ino_t ino;
|
||||
bool ip_local, temp_local;
|
||||
int error = 0;
|
||||
|
||||
@ -1655,14 +1656,17 @@ xrep_dir_swap(
|
||||
|
||||
/*
|
||||
* Reset the temporary directory's '..' entry to point to the parent
|
||||
* that we found. The temporary directory was created with the root
|
||||
* directory as the parent, so we can skip this if repairing a
|
||||
* subdirectory of the root.
|
||||
* that we found. The dirent replace code asserts if the dirent
|
||||
* already points at the new inumber, so we look it up here.
|
||||
*
|
||||
* It's also possible that this replacement could also expand a sf
|
||||
* tempdir into block format.
|
||||
*/
|
||||
if (rd->pscan.parent_ino != sc->mp->m_rootip->i_ino) {
|
||||
error = xchk_dir_lookup(sc, rd->sc->tempip, &xfs_name_dotdot, &ino);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
if (rd->pscan.parent_ino != ino) {
|
||||
error = xrep_dir_replace(rd, rd->sc->tempip, &xfs_name_dotdot,
|
||||
rd->pscan.parent_ino, rd->tx.req.resblks);
|
||||
if (error)
|
||||
|
Loading…
Reference in New Issue
Block a user