LCOV - code coverage report
Current view: top level - fs/xfs/scrub - rtbitmap.c (source / functions) Hit Total Coverage
Test: fstests of 6.5.0-rc3-achx @ Mon Jul 31 20:08:12 PDT 2023 Lines: 67 75 89.3 %
Date: 2023-07-31 20:08:12 Functions: 5 5 100.0 %

          Line data    Source code
       1             : // SPDX-License-Identifier: GPL-2.0-or-later
       2             : /*
       3             :  * Copyright (C) 2017-2023 Oracle.  All Rights Reserved.
       4             :  * Author: Darrick J. Wong <djwong@kernel.org>
       5             :  */
       6             : #include "xfs.h"
       7             : #include "xfs_fs.h"
       8             : #include "xfs_shared.h"
       9             : #include "xfs_format.h"
      10             : #include "xfs_trans_resv.h"
      11             : #include "xfs_mount.h"
      12             : #include "xfs_log_format.h"
      13             : #include "xfs_trans.h"
      14             : #include "xfs_rtalloc.h"
      15             : #include "xfs_inode.h"
      16             : #include "xfs_bmap.h"
      17             : #include "scrub/scrub.h"
      18             : #include "scrub/common.h"
      19             : #include "scrub/repair.h"
      20             : 
      21             : /* Set us up with the realtime metadata locked. */
      22             : int
      23       40108 : xchk_setup_rtbitmap(
      24             :         struct xfs_scrub        *sc)
      25             : {
      26       40108 :         unsigned int            resblks = 0;
      27       40108 :         int                     error;
      28             : 
      29       80216 :         if (xchk_could_repair(sc)) {
      30        1760 :                 error = xrep_setup_rtbitmap(sc, &resblks);
      31        1760 :                 if (error)
      32             :                         return error;
      33             :         }
      34             : 
      35       40108 :         error = xchk_trans_alloc(sc, resblks);
      36       40108 :         if (error)
      37             :                 return error;
      38             : 
      39       40105 :         error = xchk_install_live_inode(sc, sc->mp->m_rbmip);
      40       40105 :         if (error)
      41             :                 return error;
      42             : 
      43       40105 :         error = xchk_ino_dqattach(sc);
      44       40105 :         if (error)
      45             :                 return error;
      46             : 
      47       40105 :         xchk_ilock(sc, XFS_ILOCK_EXCL | XFS_ILOCK_RTBITMAP);
      48       40105 :         return 0;
      49             : }
      50             : 
      51             : /* Realtime bitmap. */
      52             : 
      53             : /* Scrub a free extent record from the realtime bitmap. */
      54             : STATIC int
      55    20512533 : xchk_rtbitmap_rec(
      56             :         struct xfs_mount        *mp,
      57             :         struct xfs_trans        *tp,
      58             :         const struct xfs_rtalloc_rec *rec,
      59             :         void                    *priv)
      60             : {
      61    20512533 :         struct xfs_scrub        *sc = priv;
      62    20512533 :         xfs_rtblock_t           startblock;
      63    20512533 :         xfs_rtblock_t           blockcount;
      64             : 
      65    20512533 :         startblock = rec->ar_startext * mp->m_sb.sb_rextsize;
      66    20512533 :         blockcount = rec->ar_extcount * mp->m_sb.sb_rextsize;
      67             : 
      68    20512533 :         if (!xfs_verify_rtext(mp, startblock, blockcount))
      69           0 :                 xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, 0);
      70    20512533 :         return 0;
      71             : }
      72             : 
      73             : /* Make sure the entire rtbitmap file is mapped with written extents. */
      74             : STATIC int
      75       40105 : xchk_rtbitmap_check_extents(
      76             :         struct xfs_scrub        *sc)
      77             : {
      78       40105 :         struct xfs_mount        *mp = sc->mp;
      79       40105 :         struct xfs_bmbt_irec    map;
      80       40105 :         xfs_rtblock_t           off;
      81       40105 :         int                     nmap;
      82       40105 :         int                     error = 0;
      83             : 
      84       80226 :         for (off = 0; off < mp->m_sb.sb_rbmblocks;) {
      85       40122 :                 if (xchk_should_terminate(sc, &error) ||
      86       40121 :                     (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT))
      87             :                         break;
      88             : 
      89             :                 /* Make sure we have a written extent. */
      90       40121 :                 nmap = 1;
      91       80242 :                 error = xfs_bmapi_read(mp->m_rbmip, off,
      92       40121 :                                 mp->m_sb.sb_rbmblocks - off, &map, &nmap,
      93             :                                 XFS_DATA_FORK);
      94       40121 :                 if (!xchk_fblock_process_error(sc, XFS_DATA_FORK, off, &error))
      95             :                         break;
      96             : 
      97       40121 :                 if (nmap != 1 || !xfs_bmap_is_written_extent(&map)) {
      98           0 :                         xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, off);
      99           0 :                         break;
     100             :                 }
     101             : 
     102       40121 :                 off += map.br_blockcount;
     103             :         }
     104             : 
     105       40105 :         return error;
     106             : }
     107             : 
     108             : /* Scrub the realtime bitmap. */
     109             : int
     110       40105 : xchk_rtbitmap(
     111             :         struct xfs_scrub        *sc)
     112             : {
     113       40105 :         int                     error;
     114             : 
     115             :         /* Is the size of the rtbitmap correct? */
     116       80210 :         if (sc->mp->m_rbmip->i_disk_size !=
     117       40105 :             XFS_FSB_TO_B(sc->mp, sc->mp->m_sb.sb_rbmblocks)) {
     118           0 :                 xchk_ino_set_corrupt(sc, sc->mp->m_rbmip->i_ino);
     119           0 :                 return 0;
     120             :         }
     121             : 
     122             :         /* Invoke the fork scrubber. */
     123       40105 :         error = xchk_metadata_inode_forks(sc);
     124       40105 :         if (error || (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT))
     125             :                 return error;
     126             : 
     127       40105 :         error = xchk_rtbitmap_check_extents(sc);
     128       40105 :         if (error || (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT))
     129             :                 return error;
     130             : 
     131       40104 :         error = xfs_rtalloc_query_all(sc->mp, sc->tp, xchk_rtbitmap_rec, sc);
     132       40104 :         if (!xchk_fblock_process_error(sc, XFS_DATA_FORK, 0, &error))
     133             :                 goto out;
     134             : 
     135             : out:
     136       40104 :         return error;
     137             : }
     138             : 
     139             : /* xref check that the extent is not free in the rtbitmap */
     140             : void
     141    75408514 : xchk_xref_is_used_rt_space(
     142             :         struct xfs_scrub        *sc,
     143             :         xfs_rtblock_t           fsbno,
     144             :         xfs_extlen_t            len)
     145             : {
     146    75408514 :         xfs_rtblock_t           startext;
     147    75408514 :         xfs_rtblock_t           endext;
     148    75408514 :         xfs_rtblock_t           extcount;
     149    75408514 :         bool                    is_free;
     150    75408514 :         int                     error;
     151             : 
     152    75408514 :         if (xchk_skip_xref(sc->sm))
     153           0 :                 return;
     154             : 
     155    75408514 :         startext = fsbno;
     156    75408514 :         endext = fsbno + len - 1;
     157    75408514 :         do_div(startext, sc->mp->m_sb.sb_rextsize);
     158    75408514 :         do_div(endext, sc->mp->m_sb.sb_rextsize);
     159    75408514 :         extcount = endext - startext + 1;
     160    75408514 :         xfs_ilock(sc->mp->m_rbmip, XFS_ILOCK_SHARED | XFS_ILOCK_RTBITMAP);
     161    75464004 :         error = xfs_rtalloc_extent_is_free(sc->mp, sc->tp, startext, extcount,
     162             :                         &is_free);
     163    75559784 :         if (!xchk_should_check_xref(sc, &error, NULL))
     164           0 :                 goto out_unlock;
     165    75493298 :         if (is_free)
     166           0 :                 xchk_ino_xref_set_corrupt(sc, sc->mp->m_rbmip->i_ino);
     167    75493298 : out_unlock:
     168    75493298 :         xfs_iunlock(sc->mp->m_rbmip, XFS_ILOCK_SHARED | XFS_ILOCK_RTBITMAP);
     169             : }

Generated by: LCOV version 1.14