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-acha @ Mon Jul 31 20:08:06 PDT 2023 Lines: 67 75 89.3 %
Date: 2023-07-31 20:08:07 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       24060 : xchk_setup_rtbitmap(
      24             :         struct xfs_scrub        *sc)
      25             : {
      26       24060 :         unsigned int            resblks = 0;
      27       24060 :         int                     error;
      28             : 
      29       48120 :         if (xchk_could_repair(sc)) {
      30         949 :                 error = xrep_setup_rtbitmap(sc, &resblks);
      31         949 :                 if (error)
      32             :                         return error;
      33             :         }
      34             : 
      35       24060 :         error = xchk_trans_alloc(sc, resblks);
      36       24060 :         if (error)
      37             :                 return error;
      38             : 
      39       24060 :         error = xchk_install_live_inode(sc, sc->mp->m_rbmip);
      40       24060 :         if (error)
      41             :                 return error;
      42             : 
      43       24060 :         error = xchk_ino_dqattach(sc);
      44       24060 :         if (error)
      45             :                 return error;
      46             : 
      47       24060 :         xchk_ilock(sc, XFS_ILOCK_EXCL | XFS_ILOCK_RTBITMAP);
      48       24060 :         return 0;
      49             : }
      50             : 
      51             : /* Realtime bitmap. */
      52             : 
      53             : /* Scrub a free extent record from the realtime bitmap. */
      54             : STATIC int
      55    10146368 : 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    10146368 :         struct xfs_scrub        *sc = priv;
      62    10146368 :         xfs_rtblock_t           startblock;
      63    10146368 :         xfs_rtblock_t           blockcount;
      64             : 
      65    10146368 :         startblock = rec->ar_startext * mp->m_sb.sb_rextsize;
      66    10146368 :         blockcount = rec->ar_extcount * mp->m_sb.sb_rextsize;
      67             : 
      68    10146368 :         if (!xfs_verify_rtext(mp, startblock, blockcount))
      69           0 :                 xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, 0);
      70    10146368 :         return 0;
      71             : }
      72             : 
      73             : /* Make sure the entire rtbitmap file is mapped with written extents. */
      74             : STATIC int
      75       24060 : xchk_rtbitmap_check_extents(
      76             :         struct xfs_scrub        *sc)
      77             : {
      78       24060 :         struct xfs_mount        *mp = sc->mp;
      79       24060 :         struct xfs_bmbt_irec    map;
      80       24060 :         xfs_rtblock_t           off;
      81       24060 :         int                     nmap;
      82       24060 :         int                     error = 0;
      83             : 
      84       48121 :         for (off = 0; off < mp->m_sb.sb_rbmblocks;) {
      85       24061 :                 if (xchk_should_terminate(sc, &error) ||
      86       24061 :                     (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT))
      87             :                         break;
      88             : 
      89             :                 /* Make sure we have a written extent. */
      90       24061 :                 nmap = 1;
      91       48122 :                 error = xfs_bmapi_read(mp->m_rbmip, off,
      92       24061 :                                 mp->m_sb.sb_rbmblocks - off, &map, &nmap,
      93             :                                 XFS_DATA_FORK);
      94       24061 :                 if (!xchk_fblock_process_error(sc, XFS_DATA_FORK, off, &error))
      95             :                         break;
      96             : 
      97       24061 :                 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       24061 :                 off += map.br_blockcount;
     103             :         }
     104             : 
     105       24060 :         return error;
     106             : }
     107             : 
     108             : /* Scrub the realtime bitmap. */
     109             : int
     110       24060 : xchk_rtbitmap(
     111             :         struct xfs_scrub        *sc)
     112             : {
     113       24060 :         int                     error;
     114             : 
     115             :         /* Is the size of the rtbitmap correct? */
     116       24060 :         if (sc->mp->m_rbmip->i_disk_size !=
     117       24060 :             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       24060 :         error = xchk_metadata_inode_forks(sc);
     124       24060 :         if (error || (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT))
     125             :                 return error;
     126             : 
     127       24060 :         error = xchk_rtbitmap_check_extents(sc);
     128       24060 :         if (error || (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT))
     129             :                 return error;
     130             : 
     131       24060 :         error = xfs_rtalloc_query_all(sc->mp, sc->tp, xchk_rtbitmap_rec, sc);
     132       24060 :         if (!xchk_fblock_process_error(sc, XFS_DATA_FORK, 0, &error))
     133             :                 goto out;
     134             : 
     135             : out:
     136       24060 :         return error;
     137             : }
     138             : 
     139             : /* xref check that the extent is not free in the rtbitmap */
     140             : void
     141    41372815 : xchk_xref_is_used_rt_space(
     142             :         struct xfs_scrub        *sc,
     143             :         xfs_rtblock_t           fsbno,
     144             :         xfs_extlen_t            len)
     145             : {
     146    41372815 :         xfs_rtblock_t           startext;
     147    41372815 :         xfs_rtblock_t           endext;
     148    41372815 :         xfs_rtblock_t           extcount;
     149    41372815 :         bool                    is_free;
     150    41372815 :         int                     error;
     151             : 
     152    41372815 :         if (xchk_skip_xref(sc->sm))
     153           0 :                 return;
     154             : 
     155    41372815 :         startext = fsbno;
     156    41372815 :         endext = fsbno + len - 1;
     157    41372815 :         do_div(startext, sc->mp->m_sb.sb_rextsize);
     158    41372815 :         do_div(endext, sc->mp->m_sb.sb_rextsize);
     159    41372815 :         extcount = endext - startext + 1;
     160    41372815 :         xfs_ilock(sc->mp->m_rbmip, XFS_ILOCK_SHARED | XFS_ILOCK_RTBITMAP);
     161    41376578 :         error = xfs_rtalloc_extent_is_free(sc->mp, sc->tp, startext, extcount,
     162             :                         &is_free);
     163    41377957 :         if (!xchk_should_check_xref(sc, &error, NULL))
     164           0 :                 goto out_unlock;
     165    41378106 :         if (is_free)
     166           0 :                 xchk_ino_xref_set_corrupt(sc, sc->mp->m_rbmip->i_ino);
     167    41378106 : out_unlock:
     168    41378106 :         xfs_iunlock(sc->mp->m_rbmip, XFS_ILOCK_SHARED | XFS_ILOCK_RTBITMAP);
     169             : }

Generated by: LCOV version 1.14