Skip to content

Commit 327ed70

Browse files
author
Darrick J. Wong
committed
xfs: inode repair should ensure there's an attr fork to store parent pointers
The runtime parent pointer update code expects that any file being moved around the directory tree already has an attr fork. However, if we had to rebuild an inode core record, there's a chance that we zeroed forkoff as part of the inode to pass the iget verifiers. Therefore, if we performed any repairs on an inode core, ensure that the inode has a nonzero forkoff before unlocking the inode. Signed-off-by: Darrick J. Wong <[email protected]> Reviewed-by: Christoph Hellwig <[email protected]>
1 parent 3f50ddb commit 327ed70

File tree

1 file changed

+41
-0
lines changed

1 file changed

+41
-0
lines changed

fs/xfs/scrub/inode_repair.c

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1736,6 +1736,44 @@ xrep_inode_extsize(
17361736
}
17371737
}
17381738

1739+
/* Ensure this file has an attr fork if it needs to hold a parent pointer. */
1740+
STATIC int
1741+
xrep_inode_pptr(
1742+
struct xfs_scrub *sc)
1743+
{
1744+
struct xfs_mount *mp = sc->mp;
1745+
struct xfs_inode *ip = sc->ip;
1746+
struct inode *inode = VFS_I(ip);
1747+
1748+
if (!xfs_has_parent(mp))
1749+
return 0;
1750+
1751+
/*
1752+
* Unlinked inodes that cannot be added to the directory tree will not
1753+
* have a parent pointer.
1754+
*/
1755+
if (inode->i_nlink == 0 && !(inode->i_state & I_LINKABLE))
1756+
return 0;
1757+
1758+
/* The root directory doesn't have a parent pointer. */
1759+
if (ip == mp->m_rootip)
1760+
return 0;
1761+
1762+
/*
1763+
* Metadata inodes are rooted in the superblock and do not have any
1764+
* parents.
1765+
*/
1766+
if (xfs_is_metadata_inode(ip))
1767+
return 0;
1768+
1769+
/* Inode already has an attr fork; no further work possible here. */
1770+
if (xfs_inode_has_attr_fork(ip))
1771+
return 0;
1772+
1773+
return xfs_bmap_add_attrfork(sc->tp, ip,
1774+
sizeof(struct xfs_attr_sf_hdr), true);
1775+
}
1776+
17391777
/* Fix any irregularities in an inode that the verifiers don't catch. */
17401778
STATIC int
17411779
xrep_inode_problems(
@@ -1744,6 +1782,9 @@ xrep_inode_problems(
17441782
int error;
17451783

17461784
error = xrep_inode_blockcounts(sc);
1785+
if (error)
1786+
return error;
1787+
error = xrep_inode_pptr(sc);
17471788
if (error)
17481789
return error;
17491790
xrep_inode_timestamps(sc->ip);

0 commit comments

Comments
 (0)