From: Christoph Hellwig Date: Mon, 10 Aug 2020 20:32:06 +0000 (-0400) Subject: xfs: improve local fork verification X-Git-Tag: v5.8.0-rc0~10 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=0815f7ab52e7b3073f5a8ea94957016668d93cd5;p=thirdparty%2Fxfsprogs-dev.git xfs: improve local fork verification Source kernel commit: 0f45a1b20cd8f9cfc985a1f91a1e7a86e5e14dd6 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 Reviewed-by: Brian Foster Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong Signed-off-by: Eric Sandeen --- diff --git a/include/xfs_inode.h b/include/xfs_inode.h index b49921da4..588d8c725 100644 --- a/include/xfs_inode.h +++ b/include/xfs_inode.h @@ -158,7 +158,6 @@ extern int libxfs_iflush_int (struct xfs_inode *, struct xfs_buf *); extern struct timespec64 current_time(struct inode *inode); /* Inode Cache Interfaces */ -extern bool libxfs_inode_verify_forks(struct xfs_inode *ip); extern int libxfs_iget(struct xfs_mount *, struct xfs_trans *, xfs_ino_t, uint, struct xfs_inode **); extern void libxfs_irele(struct xfs_inode *ip); diff --git a/libxfs/rdwr.c b/libxfs/rdwr.c index 745bd3a74..bcab3713b 100644 --- a/libxfs/rdwr.c +++ b/libxfs/rdwr.c @@ -1223,24 +1223,6 @@ xfs_verify_magic16( kmem_zone_t *xfs_inode_zone; extern kmem_zone_t *xfs_ili_zone; -/* - * If there are inline format data / attr forks attached to this inode, - * make sure they're not corrupt. - */ -bool -libxfs_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; -} - int libxfs_iget( struct xfs_mount *mp, @@ -1276,11 +1258,6 @@ libxfs_iget( if (error) goto out_destroy; - if (!libxfs_inode_verify_forks(ip)) { - libxfs_irele(ip); - return -EFSCORRUPTED; - } - *ipp = ip; return 0; diff --git a/libxfs/util.c b/libxfs/util.c index dce8e1a8e..f97ddd29c 100644 --- a/libxfs/util.c +++ b/libxfs/util.c @@ -383,8 +383,15 @@ libxfs_iflush_int( if (xfs_sb_version_has_v3inode(&mp->m_sb)) VFS_I(ip)->i_version++; - /* Check the inline fork data before we write out. */ - if (!libxfs_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)) + return -EFSCORRUPTED; + if (ip->i_d.di_aformat == XFS_DINODE_FMT_LOCAL && + xfs_ifork_verify_local_attr(ip)) return -EFSCORRUPTED; /* diff --git a/libxfs/xfs_inode_fork.c b/libxfs/xfs_inode_fork.c index f171df2d6..188b89b4a 100644 --- a/libxfs/xfs_inode_fork.c +++ b/libxfs/xfs_inode_fork.c @@ -225,6 +225,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: @@ -239,8 +240,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: @@ -280,6 +284,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);