xfs: hoist recovered extent-free intent checks out of xfs_efi_item_recover
authorDarrick J. Wong <darrick.wong@oracle.com>
Mon, 30 Nov 2020 00:33:38 +0000 (16:33 -0800)
committerDarrick J. Wong <darrick.wong@oracle.com>
Wed, 9 Dec 2020 17:49:38 +0000 (09:49 -0800)
When we recover a extent-free intent from the log, we need to validate
its contents before we try to replay them.  Hoist the checking code into
a separate function in preparation to refactor this code to use
validation helpers.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Brian Foster <bfoster@redhat.com>
fs/xfs/xfs_extfree_item.c

index 6c11bfc3d452a66f99d56fd8f90d8b58a346c8e0..f86c8a7c9c4ee742125b2d471b24c61cb5a18c48 100644 (file)
@@ -578,6 +578,25 @@ const struct xfs_defer_op_type xfs_agfl_free_defer_type = {
        .cancel_item    = xfs_extent_free_cancel_item,
 };
 
+/* Is this recovered EFI ok? */
+static inline bool
+xfs_efi_validate_ext(
+       struct xfs_mount                *mp,
+       struct xfs_extent               *extp)
+{
+       xfs_fsblock_t                   startblock_fsb;
+
+       startblock_fsb = XFS_BB_TO_FSB(mp,
+                          XFS_FSB_TO_DADDR(mp, extp->ext_start));
+       if (startblock_fsb == 0 ||
+           extp->ext_len == 0 ||
+           startblock_fsb >= mp->m_sb.sb_dblocks ||
+           extp->ext_len >= mp->m_sb.sb_agblocks)
+               return false;
+
+       return true;
+}
+
 /*
  * Process an extent free intent item that was recovered from
  * the log.  We need to free the extents that it describes.
@@ -592,7 +611,6 @@ xfs_efi_item_recover(
        struct xfs_efd_log_item         *efdp;
        struct xfs_trans                *tp;
        struct xfs_extent               *extp;
-       xfs_fsblock_t                   startblock_fsb;
        int                             i;
        int                             error = 0;
 
@@ -602,14 +620,13 @@ xfs_efi_item_recover(
         * just toss the EFI.
         */
        for (i = 0; i < efip->efi_format.efi_nextents; i++) {
-               extp = &efip->efi_format.efi_extents[i];
-               startblock_fsb = XFS_BB_TO_FSB(mp,
-                                  XFS_FSB_TO_DADDR(mp, extp->ext_start));
-               if (startblock_fsb == 0 ||
-                   extp->ext_len == 0 ||
-                   startblock_fsb >= mp->m_sb.sb_dblocks ||
-                   extp->ext_len >= mp->m_sb.sb_agblocks)
+               if (!xfs_efi_validate_ext(mp,
+                                       &efip->efi_format.efi_extents[i])) {
+                       XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp,
+                                       &efip->efi_format,
+                                       sizeof(efip->efi_format));
                        return -EFSCORRUPTED;
+               }
        }
 
        error = xfs_trans_alloc(mp, &M_RES(mp)->tr_itruncate, 0, 0, 0, &tp);