]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
xfs: improve local fork verification
authorChristoph Hellwig <hch@lst.de>
Mon, 10 Aug 2020 20:32:06 +0000 (16:32 -0400)
committerEric Sandeen <sandeen@sandeen.net>
Mon, 10 Aug 2020 20:32:06 +0000 (16:32 -0400)
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 <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>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
include/xfs_inode.h
libxfs/rdwr.c
libxfs/util.c
libxfs/xfs_inode_fork.c

index b49921da4850c395a61384f8d0858560d2eded9c..588d8c7258f4b4ee4c5d451402a397ca5be0c861 100644 (file)
@@ -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);
index 745bd3a7465374814b156de2da72d6cd592ece8b..bcab3713ba86c2fed9979076553e6eabaf5b0aed 100644 (file)
@@ -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;
 
index dce8e1a8ed8445a9f90f0e5f1433780b66d67208..f97ddd29c01e16511535058ea65bd8b269f5d959 100644 (file)
@@ -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;
 
        /*
index f171df2d6eef8e0205d5755337cc4147b4129c7b..188b89b4af189da635a4ad274efe5ab67177e030 100644 (file)
@@ -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);