diff options
author | Christoph Hellwig <hch@lst.de> | 2020-05-14 14:01:31 -0700 |
---|---|---|
committer | Darrick J. Wong <darrick.wong@oracle.com> | 2020-05-19 09:40:58 -0700 |
commit | 0f45a1b20cd8f9cfc985a1f91a1e7a86e5e14dd6 (patch) | |
tree | c3ab5331914a34625abf757520b6c8a61fad6662 | |
parent | 7c7ba2186305d6bee5eb5b8fb95a61d8de14de4f (diff) |
xfs: improve local fork verification
Call the data/attr local fork verifiers as soon as we are ready for them.
This keeps them close to the code setting up the forks, and avoids a
few branches later on. Also open code xfs_inode_verify_forks in the
only remaining caller.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Brian Foster <bfoster@redhat.com>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
-rw-r--r-- | fs/xfs/libxfs/xfs_inode_fork.c | 8 | ||||
-rw-r--r-- | fs/xfs/xfs_icache.c | 6 | ||||
-rw-r--r-- | fs/xfs/xfs_inode.c | 28 | ||||
-rw-r--r-- | fs/xfs/xfs_inode.h | 2 | ||||
-rw-r--r-- | fs/xfs/xfs_inode_item_recover.c | 5 |
5 files changed, 16 insertions, 33 deletions
diff --git a/fs/xfs/libxfs/xfs_inode_fork.c b/fs/xfs/libxfs/xfs_inode_fork.c index 2d424ab9d734..6c24c27f5f44 100644 --- a/fs/xfs/libxfs/xfs_inode_fork.c +++ b/fs/xfs/libxfs/xfs_inode_fork.c @@ -227,6 +227,7 @@ xfs_iformat_data_fork( struct xfs_dinode *dip) { struct inode *inode = VFS_I(ip); + int error; switch (inode->i_mode & S_IFMT) { case S_IFIFO: @@ -241,8 +242,11 @@ xfs_iformat_data_fork( case S_IFDIR: switch (dip->di_format) { case XFS_DINODE_FMT_LOCAL: - return xfs_iformat_local(ip, dip, XFS_DATA_FORK, + error = xfs_iformat_local(ip, dip, XFS_DATA_FORK, be64_to_cpu(dip->di_size)); + if (!error) + error = xfs_ifork_verify_local_data(ip); + return error; case XFS_DINODE_FMT_EXTENTS: return xfs_iformat_extents(ip, dip, XFS_DATA_FORK); case XFS_DINODE_FMT_BTREE: @@ -282,6 +286,8 @@ xfs_iformat_attr_fork( case XFS_DINODE_FMT_LOCAL: error = xfs_iformat_local(ip, dip, XFS_ATTR_FORK, xfs_dfork_attr_shortform_size(dip)); + if (!error) + error = xfs_ifork_verify_local_attr(ip); break; case XFS_DINODE_FMT_EXTENTS: error = xfs_iformat_extents(ip, dip, XFS_ATTR_FORK); diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c index af5748f5d927..5a3a520b9528 100644 --- a/fs/xfs/xfs_icache.c +++ b/fs/xfs/xfs_icache.c @@ -543,14 +543,8 @@ xfs_iget_cache_miss( goto out_destroy; } - if (!xfs_inode_verify_forks(ip)) { - error = -EFSCORRUPTED; - goto out_destroy; - } - trace_xfs_iget_miss(ip); - /* * Check the inode free state is valid. This also detects lookup * racing with unlinks. diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index c8abdefe0037..549ff468b7b6 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -3707,23 +3707,6 @@ shutdown: 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) -{ - if (ip->i_d.di_format == XFS_DINODE_FMT_LOCAL && - xfs_ifork_verify_local_data(ip)) - return false; - if (ip->i_d.di_aformat == XFS_DINODE_FMT_LOCAL && - xfs_ifork_verify_local_attr(ip)) - return false; - return true; -} - STATIC int xfs_iflush_int( struct xfs_inode *ip, @@ -3808,8 +3791,15 @@ xfs_iflush_int( if (!xfs_sb_version_has_v3inode(&mp->m_sb)) ip->i_d.di_flushiter++; - /* Check the inline fork data before we write out. */ - if (!xfs_inode_verify_forks(ip)) + /* + * If there are inline format data / attr forks attached to this inode, + * make sure they are not corrupt. + */ + if (ip->i_d.di_format == XFS_DINODE_FMT_LOCAL && + xfs_ifork_verify_local_data(ip)) + goto flush_out; + if (ip->i_d.di_aformat == XFS_DINODE_FMT_LOCAL && + xfs_ifork_verify_local_attr(ip)) goto flush_out; /* diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h index 83073c883fbf..ff846197941e 100644 --- a/fs/xfs/xfs_inode.h +++ b/fs/xfs/xfs_inode.h @@ -498,8 +498,6 @@ extern struct kmem_zone *xfs_inode_zone; /* The default CoW extent size hint. */ #define XFS_DEFAULT_COWEXTSZ_HINT 32 -bool xfs_inode_verify_forks(struct xfs_inode *ip); - int xfs_iunlink_init(struct xfs_perag *pag); void xfs_iunlink_destroy(struct xfs_perag *pag); diff --git a/fs/xfs/xfs_inode_item_recover.c b/fs/xfs/xfs_inode_item_recover.c index 82ca5ce312c5..dc3e26ff16c9 100644 --- a/fs/xfs/xfs_inode_item_recover.c +++ b/fs/xfs/xfs_inode_item_recover.c @@ -94,11 +94,6 @@ xfs_recover_inode_owner_change( if (error) goto out_free_ip; - if (!xfs_inode_verify_forks(ip)) { - error = -EFSCORRUPTED; - goto out_free_ip; - } - if (in_f->ilf_fields & XFS_ILOG_DOWNER) { ASSERT(in_f->ilf_fields & XFS_ILOG_DBROOT); error = xfs_bmbt_change_owner(NULL, ip, XFS_DATA_FORK, |