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-xfsx @ Mon Jul 31 20:08:34 PDT 2023 Lines: 120 132 90.9 %
Date: 2023-07-31 20:08:34 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      257506 : xchk_setup_rgbitmap(
      29             :         struct xfs_scrub        *sc)
      30             : {
      31      257506 :         unsigned int            resblks = 0;
      32      257506 :         unsigned int            rtglock_flags = XCHK_RTGLOCK_ALL;
      33      257506 :         int                     error;
      34             : 
      35      257506 :         if (xchk_need_intent_drain(sc))
      36       27352 :                 xchk_fsgates_enable(sc, XCHK_FSGATES_DRAIN);
      37             : 
      38      515012 :         if (xchk_could_repair(sc)) {
      39       54687 :                 error = xrep_setup_rgbitmap(sc, &resblks);
      40       54706 :                 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      257505 :         error = xchk_trans_alloc(sc, resblks);
      52      257539 :         if (error)
      53             :                 return error;
      54             : 
      55      257534 :         error = xchk_install_live_inode(sc, sc->mp->m_rbmip);
      56      257693 :         if (error)
      57             :                 return error;
      58             : 
      59      257693 :         error = xchk_ino_dqattach(sc);
      60      257664 :         if (error)
      61             :                 return error;
      62             : 
      63      257664 :         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       48755 : xchk_setup_rtbitmap(
      69             :         struct xfs_scrub        *sc)
      70             : {
      71       48755 :         unsigned int            resblks = 0;
      72       48755 :         int                     error;
      73             : 
      74       97510 :         if (xchk_could_repair(sc)) {
      75        9691 :                 error = xrep_setup_rtbitmap(sc, &resblks);
      76        9691 :                 if (error)
      77             :                         return error;
      78             :         }
      79             : 
      80       48755 :         error = xchk_trans_alloc(sc, resblks);
      81       48755 :         if (error)
      82             :                 return error;
      83             : 
      84       48751 :         error = xchk_install_live_inode(sc, sc->mp->m_rbmip);
      85       48751 :         if (error)
      86             :                 return error;
      87             : 
      88       48751 :         error = xchk_ino_dqattach(sc);
      89       48751 :         if (error)
      90             :                 return error;
      91             : 
      92       48751 :         xchk_rt_init(sc, &sc->sr, XCHK_RTLOCK_BITMAP);
      93       48751 :         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    26095447 : xchk_rtbitmap_xref(
     108             :         struct xchk_rtbitmap    *rtb,
     109             :         xfs_rtblock_t           startblock,
     110             :         xfs_rtblock_t           blockcount)
     111             : {
     112    26095447 :         struct xfs_scrub        *sc = rtb->sc;
     113    26095447 :         xfs_rgnumber_t          rgno;
     114    26095447 :         xfs_rgblock_t           rgbno;
     115             : 
     116    26095447 :         if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)
     117     1316917 :                 return;
     118    26095447 :         if (!sc->sr.rmap_cur)
     119             :                 return;
     120             : 
     121    24778530 :         rgbno = xfs_rtb_to_rgbno(sc->mp, startblock, &rgno);
     122    24778238 :         xchk_xref_has_no_rt_owner(sc, rgbno, blockcount);
     123    24782077 :         xchk_xref_is_not_rt_shared(sc, rgbno, blockcount);
     124    24782419 :         xchk_xref_is_not_rt_cow_staging(sc, rgbno, blockcount);
     125             : 
     126    24782076 :         if (rtb->next_free_rtblock < startblock) {
     127    24782085 :                 xfs_rgblock_t   next_rgbno;
     128             : 
     129    24782085 :                 next_rgbno = xfs_rtb_to_rgbno(sc->mp, rtb->next_free_rtblock,
     130             :                                 &rgno);
     131    24781875 :                 xchk_xref_has_rt_owner(sc, next_rgbno, rgbno - next_rgbno);
     132             :         }
     133             : 
     134    24782337 :         rtb->next_free_rtblock = startblock + blockcount;
     135             : }
     136             : 
     137             : /* Scrub a free extent record from the realtime bitmap. */
     138             : STATIC int
     139    26098466 : 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    26098466 :         struct xchk_rtbitmap    *rtb = priv;
     146    26098466 :         struct xfs_scrub        *sc = rtb->sc;
     147    26098466 :         xfs_rtblock_t           startblock;
     148    26098466 :         xfs_filblks_t           blockcount;
     149             : 
     150    26098466 :         startblock = xfs_rtx_to_rtb(mp, rec->ar_startext);
     151    26097992 :         blockcount = xfs_rtx_to_rtb(mp, rec->ar_extcount);
     152             : 
     153    26097639 :         if (!xfs_verify_rtbext(mp, startblock, blockcount))
     154           0 :                 xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, 0);
     155             : 
     156    26095148 :         xchk_rtbitmap_xref(rtb, startblock, blockcount);
     157             : 
     158    26099870 :         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       48751 : xchk_rtbitmap_check_extents(
     167             :         struct xfs_scrub        *sc)
     168             : {
     169       48751 :         struct xfs_mount        *mp = sc->mp;
     170       48751 :         struct xfs_bmbt_irec    map;
     171       48751 :         xfs_fileoff_t           off;
     172       48751 :         int                     nmap;
     173       48751 :         int                     error = 0;
     174             : 
     175      183736 :         for (off = 0; off < mp->m_sb.sb_rbmblocks;) {
     176      134985 :                 if (xchk_should_terminate(sc, &error) ||
     177      134985 :                     (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT))
     178             :                         break;
     179             : 
     180             :                 /* Make sure we have a written extent. */
     181      134985 :                 nmap = 1;
     182      269970 :                 error = xfs_bmapi_read(mp->m_rbmip, off,
     183      134985 :                                 mp->m_sb.sb_rbmblocks - off, &map, &nmap,
     184             :                                 XFS_DATA_FORK);
     185      134985 :                 if (!xchk_fblock_process_error(sc, XFS_DATA_FORK, off, &error))
     186             :                         break;
     187             : 
     188      134985 :                 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      134985 :                 off += map.br_blockcount;
     194             :         }
     195             : 
     196       48751 :         return error;
     197             : }
     198             : 
     199             : /* Scrub this group's realtime bitmap. */
     200             : int
     201      236564 : xchk_rgbitmap(
     202             :         struct xfs_scrub        *sc)
     203             : {
     204      236564 :         struct xfs_rtalloc_rec  keys[2];
     205      236564 :         struct xchk_rtbitmap    rtb = {
     206             :                 .sc             = sc,
     207             :         };
     208      236564 :         struct xfs_rtgroup      *rtg = sc->sr.rtg;
     209      236564 :         xfs_rtblock_t           rtbno;
     210      236564 :         xfs_rtblock_t           last_rtbno;
     211      236564 :         xfs_rgblock_t           last_rgbno = rtg->rtg_blockcount - 1;
     212      236564 :         int                     error;
     213             : 
     214             :         /* Sanity check the realtime bitmap size. */
     215      473128 :         if (sc->mp->m_rbmip->i_disk_size !=
     216      236564 :             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      236564 :         rtbno = xfs_rgbno_to_rtb(sc->mp, rtg->rtg_rgno, 0);
     226      236521 :         rtb.next_free_rtblock = rtbno;
     227      236521 :         keys[0].ar_startext = xfs_rtb_to_rtxt(sc->mp, rtbno);
     228             : 
     229      236523 :         rtbno = xfs_rgbno_to_rtb(sc->mp, rtg->rtg_rgno, last_rgbno);
     230      236504 :         keys[1].ar_startext = xfs_rtb_to_rtxt(sc->mp, rtbno);
     231      236503 :         keys[0].ar_extcount = keys[1].ar_extcount = 0;
     232             : 
     233      236503 :         error = xfs_rtalloc_query_range(sc->mp, sc->tp, &keys[0], &keys[1],
     234             :                         xchk_rtbitmap_rec, &rtb);
     235      236561 :         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      236546 :         last_rtbno = xfs_rgbno_to_rtb(sc->mp, rtg->rtg_rgno, last_rgbno);
     244      236551 :         if (rtb.next_free_rtblock < last_rtbno) {
     245       91499 :                 xfs_rgnumber_t  rgno;
     246       91499 :                 xfs_rgblock_t   next_rgbno;
     247             : 
     248       91499 :                 next_rgbno = xfs_rtb_to_rgbno(sc->mp, rtb.next_free_rtblock,
     249             :                                 &rgno);
     250       91499 :                 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       48751 : xchk_rtbitmap(
     260             :         struct xfs_scrub        *sc)
     261             : {
     262       48751 :         struct xchk_rtbitmap    rtb = {
     263             :                 .sc             = sc,
     264             :         };
     265       48751 :         int                     error;
     266             : 
     267             :         /* Is the size of the rtbitmap correct? */
     268       97502 :         if (sc->mp->m_rbmip->i_disk_size !=
     269       48751 :             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       48751 :         error = xchk_metadata_inode_forks(sc);
     276       48751 :         if (error || (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT))
     277             :                 return error;
     278             : 
     279       48751 :         error = xchk_rtbitmap_check_extents(sc);
     280       48751 :         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       48751 :         if (xfs_has_rtgroups(sc->mp))
     288             :                 return 0;
     289             : 
     290        2386 :         error = xfs_rtalloc_query_all(sc->mp, sc->tp, xchk_rtbitmap_rec, &rtb);
     291        2386 :         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  1009001130 : xchk_xref_is_used_rt_space(
     300             :         struct xfs_scrub        *sc,
     301             :         xfs_rtblock_t           rtbno,
     302             :         xfs_extlen_t            len)
     303             : {
     304  1009001130 :         xfs_rtxnum_t            startext;
     305  1009001130 :         xfs_rtxnum_t            endext;
     306  1009001130 :         bool                    is_free;
     307  1009001130 :         int                     error;
     308             : 
     309  1009001130 :         if (xchk_skip_xref(sc->sm))
     310           0 :                 return;
     311             : 
     312  1009001130 :         startext = xfs_rtb_to_rtxt(sc->mp, rtbno);
     313  1008759081 :         endext = xfs_rtb_to_rtxt(sc->mp, rtbno + len - 1);
     314  2018520959 :         error = xfs_rtalloc_extent_is_free(sc->mp, sc->tp, startext,
     315  1008835508 :                         endext - startext + 1, &is_free);
     316  1009685451 :         if (!xchk_should_check_xref(sc, &error, NULL))
     317             :                 return;
     318  1009137452 :         if (is_free)
     319           0 :                 xchk_ino_xref_set_corrupt(sc, sc->mp->m_rbmip->i_ino);
     320             : }

Generated by: LCOV version 1.14