diff options
author | Darrick J. Wong <darrick.wong@oracle.com> | 2017-03-28 17:51:10 -0400 |
---|---|---|
committer | Darrick J. Wong <darrick.wong@oracle.com> | 2017-03-28 17:51:10 -0400 |
commit | 005c5db8fd7b2c9fc0b8055fa824ecaa7b15d1bf (patch) | |
tree | 79ba07b0a639b449e5ea8579be794c4569d3e162 /fs/xfs/xfs_inode.c | |
parent | c02ed2e75ef4c74e41e421acb4ef1494671585e8 (diff) |
xfs: rework the inline directory verifiers
The inline directory verifiers should be called on the inode fork data,
which means after iformat_local on the read side, and prior to
ifork_flush on the write side. This makes the fork verifier more
consistent with the way buffer verifiers work -- i.e. they will operate
on the memory buffer that the code will be reading and writing directly.
Furthermore, revise the verifier function to return -EFSCORRUPTED so
that we don't flood the logs with corruption messages and assert
notices. This has been a particular problem with xfs/348, which
triggers the XFS_WANT_CORRUPTED_RETURN assertions, which halts the
kernel when CONFIG_XFS_DEBUG=y. Disk corruption isn't supposed to do
that, at least not in a verifier.
Reviewed-by: Brian Foster <bfoster@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
v2: get the inode d_ops the proper way
v3: describe the bug that this patch fixes; no code changes
Diffstat (limited to 'fs/xfs/xfs_inode.c')
-rw-r--r-- | fs/xfs/xfs_inode.c | 19 |
1 files changed, 10 insertions, 9 deletions
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index c7fe2c2123ab..7605d8396596 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c | |||
@@ -50,6 +50,7 @@ | |||
50 | #include "xfs_log.h" | 50 | #include "xfs_log.h" |
51 | #include "xfs_bmap_btree.h" | 51 | #include "xfs_bmap_btree.h" |
52 | #include "xfs_reflink.h" | 52 | #include "xfs_reflink.h" |
53 | #include "xfs_dir2_priv.h" | ||
53 | 54 | ||
54 | kmem_zone_t *xfs_inode_zone; | 55 | kmem_zone_t *xfs_inode_zone; |
55 | 56 | ||
@@ -3475,7 +3476,6 @@ xfs_iflush_int( | |||
3475 | struct xfs_inode_log_item *iip = ip->i_itemp; | 3476 | struct xfs_inode_log_item *iip = ip->i_itemp; |
3476 | struct xfs_dinode *dip; | 3477 | struct xfs_dinode *dip; |
3477 | struct xfs_mount *mp = ip->i_mount; | 3478 | struct xfs_mount *mp = ip->i_mount; |
3478 | int error; | ||
3479 | 3479 | ||
3480 | ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_ILOCK_SHARED)); | 3480 | ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_ILOCK_SHARED)); |
3481 | ASSERT(xfs_isiflocked(ip)); | 3481 | ASSERT(xfs_isiflocked(ip)); |
@@ -3547,6 +3547,12 @@ xfs_iflush_int( | |||
3547 | if (ip->i_d.di_version < 3) | 3547 | if (ip->i_d.di_version < 3) |
3548 | ip->i_d.di_flushiter++; | 3548 | ip->i_d.di_flushiter++; |
3549 | 3549 | ||
3550 | /* Check the inline directory data. */ | ||
3551 | if (S_ISDIR(VFS_I(ip)->i_mode) && | ||
3552 | ip->i_d.di_format == XFS_DINODE_FMT_LOCAL && | ||
3553 | xfs_dir2_sf_verify(ip)) | ||
3554 | goto corrupt_out; | ||
3555 | |||
3550 | /* | 3556 | /* |
3551 | * Copy the dirty parts of the inode into the on-disk inode. We always | 3557 | * Copy the dirty parts of the inode into the on-disk inode. We always |
3552 | * copy out the core of the inode, because if the inode is dirty at all | 3558 | * copy out the core of the inode, because if the inode is dirty at all |
@@ -3558,14 +3564,9 @@ xfs_iflush_int( | |||
3558 | if (ip->i_d.di_flushiter == DI_MAX_FLUSH) | 3564 | if (ip->i_d.di_flushiter == DI_MAX_FLUSH) |
3559 | ip->i_d.di_flushiter = 0; | 3565 | ip->i_d.di_flushiter = 0; |
3560 | 3566 | ||
3561 | error = xfs_iflush_fork(ip, dip, iip, XFS_DATA_FORK); | 3567 | xfs_iflush_fork(ip, dip, iip, XFS_DATA_FORK); |
3562 | if (error) | 3568 | if (XFS_IFORK_Q(ip)) |
3563 | return error; | 3569 | xfs_iflush_fork(ip, dip, iip, XFS_ATTR_FORK); |
3564 | if (XFS_IFORK_Q(ip)) { | ||
3565 | error = xfs_iflush_fork(ip, dip, iip, XFS_ATTR_FORK); | ||
3566 | if (error) | ||
3567 | return error; | ||
3568 | } | ||
3569 | xfs_inobp_check(mp, bp); | 3570 | xfs_inobp_check(mp, bp); |
3570 | 3571 | ||
3571 | /* | 3572 | /* |