summaryrefslogtreecommitdiff
path: root/fs/xfs/xfs_inode.c
diff options
context:
space:
mode:
authorDarrick J. Wong <darrick.wong@oracle.com>2018-01-08 21:51:06 +0300
committerDarrick J. Wong <darrick.wong@oracle.com>2018-01-08 21:54:47 +0300
commit9cfb9b47479e237d217dbcfafe034cbf98f45909 (patch)
treed25f11d0b4b7a622b2f26c06f47ddc6f1a3b6521 /fs/xfs/xfs_inode.c
parentdc042c2d8ff629dd411e9a60bce9c379e2f8aaf8 (diff)
downloadlinux-9cfb9b47479e237d217dbcfafe034cbf98f45909.tar.xz
xfs: provide a centralized method for verifying inline fork data
Replace the current haphazard dir2 shortform verifier callsites with a centralized verifier function that can be called either with the default verifier functions or with a custom set. This helps us strengthen integrity checking while providing us with flexibility for repair tools. xfs_repair wants this to be able to supply its own verifier functions when trying to fix possibly corrupt metadata. Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> Reviewed-by: Dave Chinner <dchinner@redhat.com>
Diffstat (limited to 'fs/xfs/xfs_inode.c')
-rw-r--r--fs/xfs/xfs_inode.c34
1 files changed, 30 insertions, 4 deletions
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index 6f95bdb408ce..663b546f2bcd 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -3479,6 +3479,34 @@ abort_out:
return error;
}
+/*
+ * If there are inline format data / attr forks attached to this inode,
+ * make sure they're not corrupt.
+ */
+bool
+xfs_inode_verify_forks(
+ struct xfs_inode *ip)
+{
+ xfs_failaddr_t fa;
+
+ fa = xfs_ifork_verify_data(ip, &xfs_default_ifork_ops);
+ if (fa) {
+ xfs_alert(ip->i_mount,
+ "%s: bad inode %llu inline data fork at %pF",
+ __func__, ip->i_ino, fa);
+ return false;
+ }
+
+ fa = xfs_ifork_verify_attr(ip, &xfs_default_ifork_ops);
+ if (fa) {
+ xfs_alert(ip->i_mount,
+ "%s: bad inode %llu inline attr fork at %pF",
+ __func__, ip->i_ino, fa);
+ return false;
+ }
+ return true;
+}
+
STATIC int
xfs_iflush_int(
struct xfs_inode *ip,
@@ -3557,10 +3585,8 @@ xfs_iflush_int(
if (ip->i_d.di_version < 3)
ip->i_d.di_flushiter++;
- /* Check the inline directory data. */
- if (S_ISDIR(VFS_I(ip)->i_mode) &&
- ip->i_d.di_format == XFS_DINODE_FMT_LOCAL &&
- xfs_dir2_sf_verify(ip))
+ /* Check the inline fork data before we write out. */
+ if (!xfs_inode_verify_forks(ip))
goto corrupt_out;
/*