LCOV - code coverage report
Current view: top level - fs/xfs/scrub - rtbitmap.c (source / functions) Hit Total Coverage
Test: fstests of 6.5.0-rc4-xfsa @ Mon Jul 31 20:08:27 PDT 2023 Lines: 117 132 88.6 %
Date: 2023-07-31 20:08:27 Functions: 8 8 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_btree.h"
      13             : #include "xfs_log_format.h"
      14             : #include "xfs_trans.h"
      15             : #include "xfs_rtbitmap.h"
      16             : #include "xfs_inode.h"
      17             : #include "xfs_bmap.h"
      18             : #include "xfs_rtgroup.h"
      19             : #include "xfs_rmap.h"
      20             : #include "xfs_rtrmap_btree.h"
      21             : #include "scrub/scrub.h"
      22             : #include "scrub/common.h"
      23             : #include "scrub/repair.h"
      24             : #include "scrub/btree.h"
      25             : 
      26             : /* Set us up with the realtime group metadata locked. */
      27             : int
      28      151818 : xchk_setup_rgbitmap(
      29             :         struct xfs_scrub        *sc)
      30             : {
      31      151818 :         unsigned int            resblks = 0;
      32      151818 :         unsigned int            rtglock_flags = XCHK_RTGLOCK_ALL;
      33      151818 :         int                     error;
      34             : 
      35      151818 :         if (xchk_need_intent_drain(sc))
      36       18287 :                 xchk_fsgates_enable(sc, XCHK_FSGATES_DRAIN);
      37             : 
      38      303636 :         if (xchk_could_repair(sc)) {
      39       37459 :                 error = xrep_setup_rgbitmap(sc, &resblks);
      40       37459 :                 if (error)
      41             :                         return error;
      42             : 
      43             :                 /*
      44             :                  * We must hold rbmip with ILOCK_EXCL to use the extent swap
      45             :                  * at the end of the repair function.
      46             :                  */
      47             :                 rtglock_flags &= ~XFS_RTGLOCK_BITMAP_SHARED;
      48             :                 rtglock_flags |= XFS_RTGLOCK_BITMAP;
      49             :         }
      50             : 
      51      151818 :         error = xchk_trans_alloc(sc, resblks);
      52      151816 :         if (error)
      53             :                 return error;
      54             : 
      55      151817 :         error = xchk_install_live_inode(sc, sc->mp->m_rbmip);
      56      151818 :         if (error)
      57             :                 return error;
      58             : 
      59      151818 :         error = xchk_ino_dqattach(sc);
      60      151816 :         if (error)
      61             :                 return error;
      62             : 
      63      151816 :         return xchk_rtgroup_init(sc, sc->sm->sm_agno, &sc->sr, rtglock_flags);
      64             : }
      65             : 
      66             : /* Set us up with the realtime metadata locked. */
      67             : int
      68       27631 : xchk_setup_rtbitmap(
      69             :         struct xfs_scrub        *sc)
      70             : {
      71       27631 :         unsigned int            resblks = 0;
      72       27631 :         int                     error;
      73             : 
      74       55262 :         if (xchk_could_repair(sc)) {
      75        6569 :                 error = xrep_setup_rtbitmap(sc, &resblks);
      76        6569 :                 if (error)
      77             :                         return error;
      78             :         }
      79             : 
      80       27631 :         error = xchk_trans_alloc(sc, resblks);
      81       27631 :         if (error)
      82             :                 return error;
      83             : 
      84       27631 :         error = xchk_install_live_inode(sc, sc->mp->m_rbmip);
      85       27631 :         if (error)
      86             :                 return error;
      87             : 
      88       27631 :         error = xchk_ino_dqattach(sc);
      89       27631 :         if (error)
      90             :                 return error;
      91             : 
      92       27631 :         xchk_rt_init(sc, &sc->sr, XCHK_RTLOCK_BITMAP);
      93       27631 :         return 0;
      94             : }
      95             : 
      96             : /* Realtime bitmap. */
      97             : 
      98             : struct xchk_rtbitmap {
      99             :         struct xfs_scrub        *sc;
     100             : 
     101             :         /* The next free rt block that we expect to see. */
     102             :         xfs_rtblock_t           next_free_rtblock;
     103             : };
     104             : 
     105             : /* Cross-reference rtbitmap entries with other metadata. */
     106             : STATIC void
     107     3838015 : xchk_rtbitmap_xref(
     108             :         struct xchk_rtbitmap    *rtb,
     109             :         xfs_rtblock_t           startblock,
     110             :         xfs_rtblock_t           blockcount)
     111             : {
     112     3838015 :         struct xfs_scrub        *sc = rtb->sc;
     113     3838015 :         xfs_rgnumber_t          rgno;
     114     3838015 :         xfs_rgblock_t           rgbno;
     115             : 
     116     3838015 :         if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)
     117           0 :                 return;
     118     3838015 :         if (!sc->sr.rmap_cur)
     119             :                 return;
     120             : 
     121     3838015 :         rgbno = xfs_rtb_to_rgbno(sc->mp, startblock, &rgno);
     122     3838015 :         xchk_xref_has_no_rt_owner(sc, rgbno, blockcount);
     123     3837971 :         xchk_xref_is_not_rt_shared(sc, rgbno, blockcount);
     124     3837900 :         xchk_xref_is_not_rt_cow_staging(sc, rgbno, blockcount);
     125             : 
     126     3837859 :         if (rtb->next_free_rtblock < startblock) {
     127     3837858 :                 xfs_rgblock_t   next_rgbno;
     128             : 
     129     3837858 :                 next_rgbno = xfs_rtb_to_rgbno(sc->mp, rtb->next_free_rtblock,
     130             :                                 &rgno);
     131     3837863 :                 xchk_xref_has_rt_owner(sc, next_rgbno, rgbno - next_rgbno);
     132             :         }
     133             : 
     134     3837974 :         rtb->next_free_rtblock = startblock + blockcount;
     135             : }
     136             : 
     137             : /* Scrub a free extent record from the realtime bitmap. */
     138             : STATIC int
     139     3838015 : xchk_rtbitmap_rec(
     140             :         struct xfs_mount        *mp,
     141             :         struct xfs_trans        *tp,
     142             :         const struct xfs_rtalloc_rec *rec,
     143             :         void                    *priv)
     144             : {
     145     3838015 :         struct xchk_rtbitmap    *rtb = priv;
     146     3838015 :         struct xfs_scrub        *sc = rtb->sc;
     147     3838015 :         xfs_rtblock_t           startblock;
     148     3838015 :         xfs_filblks_t           blockcount;
     149             : 
     150     3838015 :         startblock = xfs_rtx_to_rtb(mp, rec->ar_startext);
     151     3838015 :         blockcount = xfs_rtx_to_rtb(mp, rec->ar_extcount);
     152             : 
     153     3838015 :         if (!xfs_verify_rtbext(mp, startblock, blockcount))
     154           0 :                 xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, 0);
     155             : 
     156     3838014 :         xchk_rtbitmap_xref(rtb, startblock, blockcount);
     157             : 
     158     3837975 :         if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)
     159           0 :                 return -ECANCELED;
     160             : 
     161             :         return 0;
     162             : }
     163             : 
     164             : /* Make sure the entire rtbitmap file is mapped with written extents. */
     165             : STATIC int
     166       27631 : xchk_rtbitmap_check_extents(
     167             :         struct xfs_scrub        *sc)
     168             : {
     169       27631 :         struct xfs_mount        *mp = sc->mp;
     170       27631 :         struct xfs_bmbt_irec    map;
     171       27631 :         xfs_fileoff_t           off;
     172       27631 :         int                     nmap;
     173       27631 :         int                     error = 0;
     174             : 
     175      111745 :         for (off = 0; off < mp->m_sb.sb_rbmblocks;) {
     176       84114 :                 if (xchk_should_terminate(sc, &error) ||
     177       84114 :                     (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT))
     178             :                         break;
     179             : 
     180             :                 /* Make sure we have a written extent. */
     181       84114 :                 nmap = 1;
     182      168228 :                 error = xfs_bmapi_read(mp->m_rbmip, off,
     183       84114 :                                 mp->m_sb.sb_rbmblocks - off, &map, &nmap,
     184             :                                 XFS_DATA_FORK);
     185       84114 :                 if (!xchk_fblock_process_error(sc, XFS_DATA_FORK, off, &error))
     186             :                         break;
     187             : 
     188       84114 :                 if (nmap != 1 || !xfs_bmap_is_written_extent(&map)) {
     189           0 :                         xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, off);
     190           0 :                         break;
     191             :                 }
     192             : 
     193       84114 :                 off += map.br_blockcount;
     194             :         }
     195             : 
     196       27631 :         return error;
     197             : }
     198             : 
     199             : /* Scrub this group's realtime bitmap. */
     200             : int
     201      138148 : xchk_rgbitmap(
     202             :         struct xfs_scrub        *sc)
     203             : {
     204      138148 :         struct xfs_rtalloc_rec  keys[2];
     205      138148 :         struct xchk_rtbitmap    rtb = {
     206             :                 .sc             = sc,
     207             :         };
     208      138148 :         struct xfs_rtgroup      *rtg = sc->sr.rtg;
     209      138148 :         xfs_rtblock_t           rtbno;
     210      138148 :         xfs_rtblock_t           last_rtbno;
     211      138148 :         xfs_rgblock_t           last_rgbno = rtg->rtg_blockcount - 1;
     212      138148 :         int                     error;
     213             : 
     214             :         /* Sanity check the realtime bitmap size. */
     215      138148 :         if (sc->mp->m_rbmip->i_disk_size !=
     216      138148 :             XFS_FSB_TO_B(sc->mp, sc->mp->m_sb.sb_rbmblocks)) {
     217           0 :                 xchk_ino_set_corrupt(sc, sc->mp->m_rbmip->i_ino);
     218           0 :                 return 0;
     219             :         }
     220             : 
     221             :         /*
     222             :          * Check only the portion of the rtbitmap that corresponds to this
     223             :          * realtime group.
     224             :          */
     225      138148 :         rtbno = xfs_rgbno_to_rtb(sc->mp, rtg->rtg_rgno, 0);
     226      138147 :         rtb.next_free_rtblock = rtbno;
     227      138147 :         keys[0].ar_startext = xfs_rtb_to_rtxt(sc->mp, rtbno);
     228             : 
     229      138147 :         rtbno = xfs_rgbno_to_rtb(sc->mp, rtg->rtg_rgno, last_rgbno);
     230      138149 :         keys[1].ar_startext = xfs_rtb_to_rtxt(sc->mp, rtbno);
     231      138149 :         keys[0].ar_extcount = keys[1].ar_extcount = 0;
     232             : 
     233      138149 :         error = xfs_rtalloc_query_range(sc->mp, sc->tp, &keys[0], &keys[1],
     234             :                         xchk_rtbitmap_rec, &rtb);
     235      138148 :         if (!xchk_fblock_process_error(sc, XFS_DATA_FORK, 0, &error))
     236           0 :                 return error;
     237             : 
     238             :         /*
     239             :          * Check that the are rmappings for all rt extents between the end of
     240             :          * the last free extent we saw and the last possible extent in the rt
     241             :          * group.
     242             :          */
     243      138148 :         last_rtbno = xfs_rgbno_to_rtb(sc->mp, rtg->rtg_rgno, last_rgbno);
     244      138148 :         if (rtb.next_free_rtblock < last_rtbno) {
     245       78196 :                 xfs_rgnumber_t  rgno;
     246       78196 :                 xfs_rgblock_t   next_rgbno;
     247             : 
     248       78196 :                 next_rgbno = xfs_rtb_to_rgbno(sc->mp, rtb.next_free_rtblock,
     249             :                                 &rgno);
     250       78196 :                 xchk_xref_has_rt_owner(sc, next_rgbno,
     251             :                                 last_rgbno - next_rgbno);
     252             :         }
     253             : 
     254             :         return 0;
     255             : }
     256             : 
     257             : /* Scrub the realtime bitmap. */
     258             : int
     259       27631 : xchk_rtbitmap(
     260             :         struct xfs_scrub        *sc)
     261             : {
     262       27631 :         struct xchk_rtbitmap    rtb = {
     263             :                 .sc             = sc,
     264             :         };
     265       27631 :         int                     error;
     266             : 
     267             :         /* Is the size of the rtbitmap correct? */
     268       27631 :         if (sc->mp->m_rbmip->i_disk_size !=
     269       27631 :             XFS_FSB_TO_B(sc->mp, sc->mp->m_sb.sb_rbmblocks)) {
     270           0 :                 xchk_ino_set_corrupt(sc, sc->mp->m_rbmip->i_ino);
     271           0 :                 return 0;
     272             :         }
     273             : 
     274             :         /* Invoke the fork scrubber. */
     275       27631 :         error = xchk_metadata_inode_forks(sc);
     276       27631 :         if (error || (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT))
     277             :                 return error;
     278             : 
     279       27631 :         error = xchk_rtbitmap_check_extents(sc);
     280       27631 :         if (error || (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT))
     281             :                 return error;
     282             : 
     283             :         /*
     284             :          * Each rtgroup checks its portion of the rt bitmap, so if we don't
     285             :          * have that feature, we have to check the bitmap contents now.
     286             :          */
     287       27631 :         if (xfs_has_rtgroups(sc->mp))
     288             :                 return 0;
     289             : 
     290           0 :         error = xfs_rtalloc_query_all(sc->mp, sc->tp, xchk_rtbitmap_rec, &rtb);
     291           0 :         if (!xchk_fblock_process_error(sc, XFS_DATA_FORK, 0, &error))
     292           0 :                 return error;
     293             : 
     294             :         return 0;
     295             : }
     296             : 
     297             : /* xref check that the extent is not free in the rtbitmap */
     298             : void
     299   688347901 : xchk_xref_is_used_rt_space(
     300             :         struct xfs_scrub        *sc,
     301             :         xfs_rtblock_t           rtbno,
     302             :         xfs_extlen_t            len)
     303             : {
     304   688347901 :         xfs_rtxnum_t            startext;
     305   688347901 :         xfs_rtxnum_t            endext;
     306   688347901 :         bool                    is_free;
     307   688347901 :         int                     error;
     308             : 
     309   688347901 :         if (xchk_skip_xref(sc->sm))
     310           0 :                 return;
     311             : 
     312   688347901 :         startext = xfs_rtb_to_rtxt(sc->mp, rtbno);
     313   688347901 :         endext = xfs_rtb_to_rtxt(sc->mp, rtbno + len - 1);
     314  1376731188 :         error = xfs_rtalloc_extent_is_free(sc->mp, sc->tp, startext,
     315   688347901 :                         endext - startext + 1, &is_free);
     316   688383287 :         if (!xchk_should_check_xref(sc, &error, NULL))
     317             :                 return;
     318   688384031 :         if (is_free)
     319           0 :                 xchk_ino_xref_set_corrupt(sc, sc->mp->m_rbmip->i_ino);
     320             : }

Generated by: LCOV version 1.14