Retain the ifork ops used to validate the inode so that we can use the
same one to iflush it. xfs_repair phase 6 can use multiple transactions
to fix various inode problems, which means that the inode might not be
fully fixed when each transaction commits.
This can be a particular problem if there's a shortform directory with
both invalid directory entries and incorrect i8count. Phase 3 will set
the parent inode to "0" to signal to phase 6 that it needs to reset the
parent and i8count, but phase 6 starts a transaction to junk the bad
entries which fail to commit because the parent is invalid:
fixing i8count in inode
69022994673
Invalid inode number 0x0
xfs_dir_ino_validate: XFS_ERROR_REPORT
Metadata corruption detected at 0x464eb0, inode 0x10121750f1 data fork
xfs_repair: warning - iflush_int failed (-117)
And thus the inode fixes never get written out.
Reported-by: Arkadiusz Miskiewicz <arekm@maven.pl>
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Bill O'Donnell <billodo@redhat.com>
Reviewed-by: Eric Sandeen <sandeen@redhat.com>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
xfs_fsize_t i_size; /* in-memory size */
const struct xfs_dir_ops *d_ops; /* directory ops vector */
+ struct xfs_ifork_ops *i_fork_ops; /* fork verifiers */
struct inode i_vnode;
} xfs_inode_t;
return error;
}
+ ip->i_fork_ops = ifork_ops;
if (!libxfs_inode_verify_forks(ip, ifork_ops)) {
libxfs_irele(ip);
return -EFSCORRUPTED;
VFS_I(ip)->i_version++;
/* Check the inline fork data before we write out. */
- if (!libxfs_inode_verify_forks(ip, &xfs_default_ifork_ops))
+ if (!libxfs_inode_verify_forks(ip, ip->i_fork_ops))
return -EFSCORRUPTED;
/*