mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-07-09 16:12:21 +00:00
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
This commit is contained in:
parent
c02ed2e75e
commit
005c5db8fd
5 changed files with 66 additions and 56 deletions
|
@ -50,6 +50,7 @@
|
|||
#include "xfs_log.h"
|
||||
#include "xfs_bmap_btree.h"
|
||||
#include "xfs_reflink.h"
|
||||
#include "xfs_dir2_priv.h"
|
||||
|
||||
kmem_zone_t *xfs_inode_zone;
|
||||
|
||||
|
@ -3475,7 +3476,6 @@ xfs_iflush_int(
|
|||
struct xfs_inode_log_item *iip = ip->i_itemp;
|
||||
struct xfs_dinode *dip;
|
||||
struct xfs_mount *mp = ip->i_mount;
|
||||
int error;
|
||||
|
||||
ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_ILOCK_SHARED));
|
||||
ASSERT(xfs_isiflocked(ip));
|
||||
|
@ -3547,6 +3547,12 @@ 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))
|
||||
goto corrupt_out;
|
||||
|
||||
/*
|
||||
* Copy the dirty parts of the inode into the on-disk inode. We always
|
||||
* copy out the core of the inode, because if the inode is dirty at all
|
||||
|
@ -3558,14 +3564,9 @@ xfs_iflush_int(
|
|||
if (ip->i_d.di_flushiter == DI_MAX_FLUSH)
|
||||
ip->i_d.di_flushiter = 0;
|
||||
|
||||
error = xfs_iflush_fork(ip, dip, iip, XFS_DATA_FORK);
|
||||
if (error)
|
||||
return error;
|
||||
if (XFS_IFORK_Q(ip)) {
|
||||
error = xfs_iflush_fork(ip, dip, iip, XFS_ATTR_FORK);
|
||||
if (error)
|
||||
return error;
|
||||
}
|
||||
xfs_iflush_fork(ip, dip, iip, XFS_DATA_FORK);
|
||||
if (XFS_IFORK_Q(ip))
|
||||
xfs_iflush_fork(ip, dip, iip, XFS_ATTR_FORK);
|
||||
xfs_inobp_check(mp, bp);
|
||||
|
||||
/*
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue