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-djwx @ Mon Jul 31 20:08:22 PDT 2023 Lines: 77 86 89.5 %
Date: 2023-07-31 20:08:22 Functions: 6 6 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             : 
      20             : /* Set us up with the realtime metadata locked. */
      21             : int
      22      629506 : xchk_setup_rt(
      23             :         struct xfs_scrub        *sc)
      24             : {
      25      629506 :         int                     error;
      26             : 
      27      629506 :         error = xchk_setup_fs(sc);
      28      629506 :         if (error)
      29             :                 return error;
      30             : 
      31      629494 :         sc->ilock_flags = XFS_ILOCK_EXCL | XFS_ILOCK_RTBITMAP;
      32      629494 :         sc->ip = sc->mp->m_rbmip;
      33      629494 :         xfs_ilock(sc->ip, sc->ilock_flags);
      34             : 
      35      629494 :         return 0;
      36             : }
      37             : 
      38             : /* Realtime bitmap. */
      39             : 
      40             : /* Scrub a free extent record from the realtime bitmap. */
      41             : STATIC int
      42    18389908 : xchk_rtbitmap_rec(
      43             :         struct xfs_mount        *mp,
      44             :         struct xfs_trans        *tp,
      45             :         const struct xfs_rtalloc_rec *rec,
      46             :         void                    *priv)
      47             : {
      48    18389908 :         struct xfs_scrub        *sc = priv;
      49    18389908 :         xfs_rtblock_t           startblock;
      50    18389908 :         xfs_rtblock_t           blockcount;
      51             : 
      52    18389908 :         startblock = rec->ar_startext * mp->m_sb.sb_rextsize;
      53    18389908 :         blockcount = rec->ar_extcount * mp->m_sb.sb_rextsize;
      54             : 
      55    18389908 :         if (!xfs_verify_rtext(mp, startblock, blockcount))
      56           0 :                 xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, 0);
      57    18389908 :         return 0;
      58             : }
      59             : 
      60             : /* Make sure the entire rtbitmap file is mapped with written extents. */
      61             : STATIC int
      62       89673 : xchk_rtbitmap_check_extents(
      63             :         struct xfs_scrub        *sc)
      64             : {
      65       89673 :         struct xfs_mount        *mp = sc->mp;
      66       89673 :         struct xfs_bmbt_irec    map;
      67       89673 :         xfs_rtblock_t           off;
      68       89673 :         int                     nmap;
      69       89673 :         int                     error = 0;
      70             : 
      71      179361 :         for (off = 0; off < mp->m_sb.sb_rbmblocks;) {
      72       89688 :                 if (xchk_should_terminate(sc, &error) ||
      73       89688 :                     (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT))
      74             :                         break;
      75             : 
      76             :                 /* Make sure we have a written extent. */
      77       89688 :                 nmap = 1;
      78      179376 :                 error = xfs_bmapi_read(mp->m_rbmip, off,
      79       89688 :                                 mp->m_sb.sb_rbmblocks - off, &map, &nmap,
      80             :                                 XFS_DATA_FORK);
      81       89688 :                 if (!xchk_fblock_process_error(sc, XFS_DATA_FORK, off, &error))
      82             :                         break;
      83             : 
      84       89688 :                 if (nmap != 1 || !xfs_bmap_is_written_extent(&map)) {
      85           0 :                         xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, off);
      86           0 :                         break;
      87             :                 }
      88             : 
      89       89688 :                 off += map.br_blockcount;
      90             :         }
      91             : 
      92       89673 :         return error;
      93             : }
      94             : 
      95             : /* Scrub the realtime bitmap. */
      96             : int
      97       89673 : xchk_rtbitmap(
      98             :         struct xfs_scrub        *sc)
      99             : {
     100       89673 :         int                     error;
     101             : 
     102             :         /* Is the size of the rtbitmap correct? */
     103      179346 :         if (sc->mp->m_rbmip->i_disk_size !=
     104       89673 :             XFS_FSB_TO_B(sc->mp, sc->mp->m_sb.sb_rbmblocks)) {
     105           0 :                 xchk_ino_set_corrupt(sc, sc->mp->m_rbmip->i_ino);
     106           0 :                 return 0;
     107             :         }
     108             : 
     109             :         /* Invoke the fork scrubber. */
     110       89673 :         error = xchk_metadata_inode_forks(sc);
     111       89673 :         if (error || (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT))
     112             :                 return error;
     113             : 
     114       89673 :         error = xchk_rtbitmap_check_extents(sc);
     115       89673 :         if (error || (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT))
     116             :                 return error;
     117             : 
     118       89673 :         error = xfs_rtalloc_query_all(sc->mp, sc->tp, xchk_rtbitmap_rec, sc);
     119       89673 :         if (!xchk_fblock_process_error(sc, XFS_DATA_FORK, 0, &error))
     120             :                 goto out;
     121             : 
     122             : out:
     123       89673 :         return error;
     124             : }
     125             : 
     126             : /* Scrub the realtime summary. */
     127             : int
     128      539821 : xchk_rtsummary(
     129             :         struct xfs_scrub        *sc)
     130             : {
     131      539821 :         struct xfs_inode        *rsumip = sc->mp->m_rsumip;
     132      539821 :         struct xfs_inode        *old_ip = sc->ip;
     133      539821 :         uint                    old_ilock_flags = sc->ilock_flags;
     134      539821 :         int                     error = 0;
     135             : 
     136             :         /*
     137             :          * We ILOCK'd the rt bitmap ip in the setup routine, now lock the
     138             :          * rt summary ip in compliance with the rt inode locking rules.
     139             :          *
     140             :          * Since we switch sc->ip to rsumip we have to save the old ilock
     141             :          * flags so that we don't mix up the inode state that @sc tracks.
     142             :          */
     143      539821 :         sc->ip = rsumip;
     144      539821 :         sc->ilock_flags = XFS_ILOCK_EXCL | XFS_ILOCK_RTSUM;
     145      539821 :         xfs_ilock(sc->ip, sc->ilock_flags);
     146             : 
     147             :         /* Invoke the fork scrubber. */
     148      539821 :         error = xchk_metadata_inode_forks(sc);
     149      539821 :         if (error || (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT))
     150           0 :                 goto out;
     151             : 
     152             :         /* XXX: implement this some day */
     153      539821 :         xchk_set_incomplete(sc);
     154      539821 : out:
     155             :         /* Switch back to the rtbitmap inode and lock flags. */
     156      539821 :         xfs_iunlock(sc->ip, sc->ilock_flags);
     157      539821 :         sc->ilock_flags = old_ilock_flags;
     158      539821 :         sc->ip = old_ip;
     159      539821 :         return error;
     160             : }
     161             : 
     162             : 
     163             : /* xref check that the extent is not free in the rtbitmap */
     164             : void
     165   263436084 : xchk_xref_is_used_rt_space(
     166             :         struct xfs_scrub        *sc,
     167             :         xfs_rtblock_t           fsbno,
     168             :         xfs_extlen_t            len)
     169             : {
     170   263436084 :         xfs_rtblock_t           startext;
     171   263436084 :         xfs_rtblock_t           endext;
     172   263436084 :         xfs_rtblock_t           extcount;
     173   263436084 :         bool                    is_free;
     174   263436084 :         int                     error;
     175             : 
     176   263436084 :         if (xchk_skip_xref(sc->sm))
     177           0 :                 return;
     178             : 
     179   263436084 :         startext = fsbno;
     180   263436084 :         endext = fsbno + len - 1;
     181   263436084 :         do_div(startext, sc->mp->m_sb.sb_rextsize);
     182   263436084 :         do_div(endext, sc->mp->m_sb.sb_rextsize);
     183   263436084 :         extcount = endext - startext + 1;
     184   263436084 :         xfs_ilock(sc->mp->m_rbmip, XFS_ILOCK_SHARED | XFS_ILOCK_RTBITMAP);
     185   263675789 :         error = xfs_rtalloc_extent_is_free(sc->mp, sc->tp, startext, extcount,
     186             :                         &is_free);
     187   263911153 :         if (!xchk_should_check_xref(sc, &error, NULL))
     188           0 :                 goto out_unlock;
     189   263308113 :         if (is_free)
     190           0 :                 xchk_ino_xref_set_corrupt(sc, sc->mp->m_rbmip->i_ino);
     191   263308113 : out_unlock:
     192   263308113 :         xfs_iunlock(sc->mp->m_rbmip, XFS_ILOCK_SHARED | XFS_ILOCK_RTBITMAP);
     193             : }

Generated by: LCOV version 1.14