]> git-server-git.apps.pok.os.sepia.ceph.com Git - xfsprogs-dev.git/commitdiff
xfs: validate the realtime geometry in xfs_validate_sb_common libxfs-5.7-sync_2020-04-28
authorDarrick J. Wong <darrick.wong@oracle.com>
Mon, 6 Apr 2020 19:04:25 +0000 (12:04 -0700)
committerDarrick J. Wong <darrick.wong@oracle.com>
Tue, 21 Apr 2020 19:53:14 +0000 (12:53 -0700)
Source kernel commit: f8e566c0f5e1fd8de33ccec6eb1ff815cd4b0dc3

Validate the geometry of the realtime geometry when we mount the
filesystem, so that we don't abruptly shut down the filesystem later on.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
libxfs/libxfs_priv.h
libxfs/xfs_sb.c

index 97e1e32bf28efbb70097f13b64bd8ac5205a82ec..885282c826c46eac2451468457c8e2851687d1d0 100644 (file)
@@ -268,6 +268,18 @@ div64_u64_rem(
        return dividend / divisor;
 }
 
+static inline uint64_t
+div_u64(uint64_t dividend, uint32_t divisor)
+{
+       return dividend / divisor;
+}
+
+static inline uint64_t
+howmany_64(uint64_t dividend, uint32_t divisor)
+{
+       return div_u64(dividend + divisor - 1, divisor);
+}
+
 #define min_t(type,x,y) \
        ({ type __x = (x); type __y = (y); __x < __y ? __x: __y; })
 #define max_t(type,x,y) \
index e26b901667c98251ffa50ad3d747896a9282e5e8..d37d60b39a52df90afe24a1d8d1e9f1cdda2a8ee 100644 (file)
@@ -325,6 +325,38 @@ xfs_validate_sb_common(
                return -EFSCORRUPTED;
        }
 
+       /* Validate the realtime geometry; stolen from xfs_repair */
+       if (sbp->sb_rextsize * sbp->sb_blocksize > XFS_MAX_RTEXTSIZE ||
+           sbp->sb_rextsize * sbp->sb_blocksize < XFS_MIN_RTEXTSIZE) {
+               xfs_notice(mp,
+                       "realtime extent sanity check failed");
+               return -EFSCORRUPTED;
+       }
+
+       if (sbp->sb_rblocks == 0) {
+               if (sbp->sb_rextents != 0 || sbp->sb_rbmblocks != 0 ||
+                   sbp->sb_rextslog != 0 || sbp->sb_frextents != 0) {
+                       xfs_notice(mp,
+                               "realtime zeroed geometry check failed");
+                       return -EFSCORRUPTED;
+               }
+       } else {
+               uint64_t        rexts;
+               uint64_t        rbmblocks;
+
+               rexts = div_u64(sbp->sb_rblocks, sbp->sb_rextsize);
+               rbmblocks = howmany_64(sbp->sb_rextents,
+                                      NBBY * sbp->sb_blocksize);
+
+               if (sbp->sb_rextents != rexts ||
+                   sbp->sb_rextslog != xfs_highbit32(sbp->sb_rextents) ||
+                   sbp->sb_rbmblocks != rbmblocks) {
+                       xfs_notice(mp,
+                               "realtime geometry sanity check failed");
+                       return -EFSCORRUPTED;
+               }
+       }
+
        if (sbp->sb_unit) {
                if (!xfs_sb_version_hasdalign(sbp) ||
                    sbp->sb_unit > sbp->sb_width ||