LCOV - code coverage report
Current view: top level - fs/xfs/scrub - common.c (source / functions) Hit Total Coverage
Test: fstests of 6.5.0-rc3-djwa @ Mon Jul 31 20:08:17 PDT 2023 Lines: 302 402 75.1 %
Date: 2023-07-31 20:08:17 Functions: 35 43 81.4 %

          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_inode.h"
      16             : #include "xfs_icache.h"
      17             : #include "xfs_alloc.h"
      18             : #include "xfs_alloc_btree.h"
      19             : #include "xfs_ialloc.h"
      20             : #include "xfs_ialloc_btree.h"
      21             : #include "xfs_refcount_btree.h"
      22             : #include "xfs_rmap.h"
      23             : #include "xfs_rmap_btree.h"
      24             : #include "xfs_log.h"
      25             : #include "xfs_trans_priv.h"
      26             : #include "xfs_da_format.h"
      27             : #include "xfs_da_btree.h"
      28             : #include "xfs_attr.h"
      29             : #include "xfs_reflink.h"
      30             : #include "xfs_ag.h"
      31             : #include "scrub/scrub.h"
      32             : #include "scrub/common.h"
      33             : #include "scrub/trace.h"
      34             : #include "scrub/repair.h"
      35             : #include "scrub/health.h"
      36             : 
      37             : /* Common code for the metadata scrubbers. */
      38             : 
      39             : /*
      40             :  * Handling operational errors.
      41             :  *
      42             :  * The *_process_error() family of functions are used to process error return
      43             :  * codes from functions called as part of a scrub operation.
      44             :  *
      45             :  * If there's no error, we return true to tell the caller that it's ok
      46             :  * to move on to the next check in its list.
      47             :  *
      48             :  * For non-verifier errors (e.g. ENOMEM) we return false to tell the
      49             :  * caller that something bad happened, and we preserve *error so that
      50             :  * the caller can return the *error up the stack to userspace.
      51             :  *
      52             :  * Verifier errors (EFSBADCRC/EFSCORRUPTED) are recorded by setting
      53             :  * OFLAG_CORRUPT in sm_flags and the *error is cleared.  In other words,
      54             :  * we track verifier errors (and failed scrub checks) via OFLAG_CORRUPT,
      55             :  * not via return codes.  We return false to tell the caller that
      56             :  * something bad happened.  Since the error has been cleared, the caller
      57             :  * will (presumably) return that zero and scrubbing will move on to
      58             :  * whatever's next.
      59             :  *
      60             :  * ftrace can be used to record the precise metadata location and the
      61             :  * approximate code location of the failed operation.
      62             :  */
      63             : 
      64             : /* Check for operational errors. */
      65             : static bool
      66   376425143 : __xchk_process_error(
      67             :         struct xfs_scrub        *sc,
      68             :         xfs_agnumber_t          agno,
      69             :         xfs_agblock_t           bno,
      70             :         int                     *error,
      71             :         __u32                   errflag,
      72             :         void                    *ret_ip)
      73             : {
      74   376425143 :         switch (*error) {
      75             :         case 0:
      76             :                 return true;
      77       31336 :         case -EDEADLOCK:
      78             :         case -ECHRNG:
      79             :                 /* Used to restart an op with deadlock avoidance. */
      80       62672 :                 trace_xchk_deadlock_retry(
      81       31336 :                                 sc->ip ? sc->ip : XFS_I(file_inode(sc->file)),
      82             :                                 sc->sm, *error);
      83       31336 :                 break;
      84           2 :         case -EFSBADCRC:
      85             :         case -EFSCORRUPTED:
      86             :                 /* Note the badness but don't abort. */
      87           2 :                 sc->sm->sm_flags |= errflag;
      88           2 :                 *error = 0;
      89           5 :                 fallthrough;
      90           5 :         default:
      91           5 :                 trace_xchk_op_error(sc, agno, bno, *error,
      92             :                                 ret_ip);
      93           5 :                 break;
      94             :         }
      95             :         return false;
      96             : }
      97             : 
      98             : bool
      99     8353643 : xchk_process_error(
     100             :         struct xfs_scrub        *sc,
     101             :         xfs_agnumber_t          agno,
     102             :         xfs_agblock_t           bno,
     103             :         int                     *error)
     104             : {
     105     8353643 :         return __xchk_process_error(sc, agno, bno, error,
     106             :                         XFS_SCRUB_OFLAG_CORRUPT, __return_address);
     107             : }
     108             : 
     109             : bool
     110   368073617 : xchk_xref_process_error(
     111             :         struct xfs_scrub        *sc,
     112             :         xfs_agnumber_t          agno,
     113             :         xfs_agblock_t           bno,
     114             :         int                     *error)
     115             : {
     116   368073617 :         return __xchk_process_error(sc, agno, bno, error,
     117             :                         XFS_SCRUB_OFLAG_XFAIL, __return_address);
     118             : }
     119             : 
     120             : /* Check for operational errors for a file offset. */
     121             : static bool
     122  2605189394 : __xchk_fblock_process_error(
     123             :         struct xfs_scrub        *sc,
     124             :         int                     whichfork,
     125             :         xfs_fileoff_t           offset,
     126             :         int                     *error,
     127             :         __u32                   errflag,
     128             :         void                    *ret_ip)
     129             : {
     130  2605189394 :         switch (*error) {
     131             :         case 0:
     132             :                 return true;
     133           0 :         case -EDEADLOCK:
     134             :         case -ECHRNG:
     135             :                 /* Used to restart an op with deadlock avoidance. */
     136           0 :                 trace_xchk_deadlock_retry(sc->ip, sc->sm, *error);
     137           0 :                 break;
     138           2 :         case -EFSBADCRC:
     139             :         case -EFSCORRUPTED:
     140             :                 /* Note the badness but don't abort. */
     141           2 :                 sc->sm->sm_flags |= errflag;
     142           2 :                 *error = 0;
     143           2 :                 fallthrough;
     144           2 :         default:
     145           2 :                 trace_xchk_file_op_error(sc, whichfork, offset, *error,
     146             :                                 ret_ip);
     147           2 :                 break;
     148             :         }
     149             :         return false;
     150             : }
     151             : 
     152             : bool
     153  1124216466 : xchk_fblock_process_error(
     154             :         struct xfs_scrub        *sc,
     155             :         int                     whichfork,
     156             :         xfs_fileoff_t           offset,
     157             :         int                     *error)
     158             : {
     159  1124594380 :         return __xchk_fblock_process_error(sc, whichfork, offset, error,
     160             :                         XFS_SCRUB_OFLAG_CORRUPT, __return_address);
     161             : }
     162             : 
     163             : bool
     164  1480327173 : xchk_fblock_xref_process_error(
     165             :         struct xfs_scrub        *sc,
     166             :         int                     whichfork,
     167             :         xfs_fileoff_t           offset,
     168             :         int                     *error)
     169             : {
     170  1480327173 :         return __xchk_fblock_process_error(sc, whichfork, offset, error,
     171             :                         XFS_SCRUB_OFLAG_XFAIL, __return_address);
     172             : }
     173             : 
     174             : /*
     175             :  * Handling scrub corruption/optimization/warning checks.
     176             :  *
     177             :  * The *_set_{corrupt,preen,warning}() family of functions are used to
     178             :  * record the presence of metadata that is incorrect (corrupt), could be
     179             :  * optimized somehow (preen), or should be flagged for administrative
     180             :  * review but is not incorrect (warn).
     181             :  *
     182             :  * ftrace can be used to record the precise metadata location and
     183             :  * approximate code location of the failed check.
     184             :  */
     185             : 
     186             : /* Record a block which could be optimized. */
     187             : void
     188     2072959 : xchk_block_set_preen(
     189             :         struct xfs_scrub        *sc,
     190             :         struct xfs_buf          *bp)
     191             : {
     192     2072959 :         sc->sm->sm_flags |= XFS_SCRUB_OFLAG_PREEN;
     193     2072959 :         trace_xchk_block_preen(sc, xfs_buf_daddr(bp), __return_address);
     194     2072967 : }
     195             : 
     196             : /*
     197             :  * Record an inode which could be optimized.  The trace data will
     198             :  * include the block given by bp if bp is given; otherwise it will use
     199             :  * the block location of the inode record itself.
     200             :  */
     201             : void
     202     4809202 : xchk_ino_set_preen(
     203             :         struct xfs_scrub        *sc,
     204             :         xfs_ino_t               ino)
     205             : {
     206     4809202 :         sc->sm->sm_flags |= XFS_SCRUB_OFLAG_PREEN;
     207     4809202 :         trace_xchk_ino_preen(sc, ino, __return_address);
     208     4809214 : }
     209             : 
     210             : /* Record something being wrong with the filesystem primary superblock. */
     211             : void
     212           0 : xchk_set_corrupt(
     213             :         struct xfs_scrub        *sc)
     214             : {
     215           0 :         sc->sm->sm_flags |= XFS_SCRUB_OFLAG_CORRUPT;
     216           0 :         trace_xchk_fs_error(sc, 0, __return_address);
     217           0 : }
     218             : 
     219             : /* Record a corrupt block. */
     220             : void
     221           0 : xchk_block_set_corrupt(
     222             :         struct xfs_scrub        *sc,
     223             :         struct xfs_buf          *bp)
     224             : {
     225           0 :         sc->sm->sm_flags |= XFS_SCRUB_OFLAG_CORRUPT;
     226           0 :         trace_xchk_block_error(sc, xfs_buf_daddr(bp), __return_address);
     227           0 : }
     228             : 
     229             : /* Record a corruption while cross-referencing. */
     230             : void
     231           0 : xchk_block_xref_set_corrupt(
     232             :         struct xfs_scrub        *sc,
     233             :         struct xfs_buf          *bp)
     234             : {
     235           0 :         sc->sm->sm_flags |= XFS_SCRUB_OFLAG_XCORRUPT;
     236           0 :         trace_xchk_block_error(sc, xfs_buf_daddr(bp), __return_address);
     237           0 : }
     238             : 
     239             : /*
     240             :  * Record a corrupt inode.  The trace data will include the block given
     241             :  * by bp if bp is given; otherwise it will use the block location of the
     242             :  * inode record itself.
     243             :  */
     244             : void
     245           0 : xchk_ino_set_corrupt(
     246             :         struct xfs_scrub        *sc,
     247             :         xfs_ino_t               ino)
     248             : {
     249           0 :         sc->sm->sm_flags |= XFS_SCRUB_OFLAG_CORRUPT;
     250           0 :         trace_xchk_ino_error(sc, ino, __return_address);
     251           0 : }
     252             : 
     253             : /* Record a corruption while cross-referencing with an inode. */
     254             : void
     255           0 : xchk_ino_xref_set_corrupt(
     256             :         struct xfs_scrub        *sc,
     257             :         xfs_ino_t               ino)
     258             : {
     259           0 :         sc->sm->sm_flags |= XFS_SCRUB_OFLAG_XCORRUPT;
     260           0 :         trace_xchk_ino_error(sc, ino, __return_address);
     261           0 : }
     262             : 
     263             : /* Record corruption in a block indexed by a file fork. */
     264             : void
     265           4 : xchk_fblock_set_corrupt(
     266             :         struct xfs_scrub        *sc,
     267             :         int                     whichfork,
     268             :         xfs_fileoff_t           offset)
     269             : {
     270           4 :         sc->sm->sm_flags |= XFS_SCRUB_OFLAG_CORRUPT;
     271           4 :         trace_xchk_fblock_error(sc, whichfork, offset, __return_address);
     272           4 : }
     273             : 
     274             : /* Record a corruption while cross-referencing a fork block. */
     275             : void
     276           0 : xchk_fblock_xref_set_corrupt(
     277             :         struct xfs_scrub        *sc,
     278             :         int                     whichfork,
     279             :         xfs_fileoff_t           offset)
     280             : {
     281           0 :         sc->sm->sm_flags |= XFS_SCRUB_OFLAG_XCORRUPT;
     282           0 :         trace_xchk_fblock_error(sc, whichfork, offset, __return_address);
     283           0 : }
     284             : 
     285             : /*
     286             :  * Warn about inodes that need administrative review but is not
     287             :  * incorrect.
     288             :  */
     289             : void
     290           0 : xchk_ino_set_warning(
     291             :         struct xfs_scrub        *sc,
     292             :         xfs_ino_t               ino)
     293             : {
     294           0 :         sc->sm->sm_flags |= XFS_SCRUB_OFLAG_WARNING;
     295           0 :         trace_xchk_ino_warning(sc, ino, __return_address);
     296           0 : }
     297             : 
     298             : /* Warn about a block indexed by a file fork that needs review. */
     299             : void
     300          27 : xchk_fblock_set_warning(
     301             :         struct xfs_scrub        *sc,
     302             :         int                     whichfork,
     303             :         xfs_fileoff_t           offset)
     304             : {
     305          27 :         sc->sm->sm_flags |= XFS_SCRUB_OFLAG_WARNING;
     306          27 :         trace_xchk_fblock_warning(sc, whichfork, offset, __return_address);
     307          27 : }
     308             : 
     309             : /* Signal an incomplete scrub. */
     310             : void
     311      521950 : xchk_set_incomplete(
     312             :         struct xfs_scrub        *sc)
     313             : {
     314      521950 :         sc->sm->sm_flags |= XFS_SCRUB_OFLAG_INCOMPLETE;
     315      521950 :         trace_xchk_incomplete(sc, __return_address);
     316      521950 : }
     317             : 
     318             : /*
     319             :  * rmap scrubbing -- compute the number of blocks with a given owner,
     320             :  * at least according to the reverse mapping data.
     321             :  */
     322             : 
     323             : struct xchk_rmap_ownedby_info {
     324             :         const struct xfs_owner_info     *oinfo;
     325             :         xfs_filblks_t                   *blocks;
     326             : };
     327             : 
     328             : STATIC int
     329  3467402575 : xchk_count_rmap_ownedby_irec(
     330             :         struct xfs_btree_cur            *cur,
     331             :         const struct xfs_rmap_irec      *rec,
     332             :         void                            *priv)
     333             : {
     334  3467402575 :         struct xchk_rmap_ownedby_info   *sroi = priv;
     335  3467402575 :         bool                            irec_attr;
     336  3467402575 :         bool                            oinfo_attr;
     337             : 
     338  3467402575 :         irec_attr = rec->rm_flags & XFS_RMAP_ATTR_FORK;
     339  3467402575 :         oinfo_attr = sroi->oinfo->oi_flags & XFS_OWNER_INFO_ATTR_FORK;
     340             : 
     341  3467402575 :         if (rec->rm_owner != sroi->oinfo->oi_owner)
     342             :                 return 0;
     343             : 
     344    16938496 :         if (XFS_RMAP_NON_INODE_OWNER(rec->rm_owner) || irec_attr == oinfo_attr)
     345    16938496 :                 (*sroi->blocks) += rec->rm_blockcount;
     346             : 
     347             :         return 0;
     348             : }
     349             : 
     350             : /*
     351             :  * Calculate the number of blocks the rmap thinks are owned by something.
     352             :  * The caller should pass us an rmapbt cursor.
     353             :  */
     354             : int
     355     2501797 : xchk_count_rmap_ownedby_ag(
     356             :         struct xfs_scrub                *sc,
     357             :         struct xfs_btree_cur            *cur,
     358             :         const struct xfs_owner_info     *oinfo,
     359             :         xfs_filblks_t                   *blocks)
     360             : {
     361     2501797 :         struct xchk_rmap_ownedby_info   sroi = {
     362             :                 .oinfo                  = oinfo,
     363             :                 .blocks                 = blocks,
     364             :         };
     365             : 
     366     2501797 :         *blocks = 0;
     367     2501797 :         return xfs_rmap_query_all(cur, xchk_count_rmap_ownedby_irec,
     368             :                         &sroi);
     369             : }
     370             : 
     371             : /*
     372             :  * AG scrubbing
     373             :  *
     374             :  * These helpers facilitate locking an allocation group's header
     375             :  * buffers, setting up cursors for all btrees that are present, and
     376             :  * cleaning everything up once we're through.
     377             :  */
     378             : 
     379             : /* Decide if we want to return an AG header read failure. */
     380             : static inline bool
     381             : want_ag_read_header_failure(
     382             :         struct xfs_scrub        *sc,
     383             :         unsigned int            type)
     384             : {
     385             :         /* Return all AG header read failures when scanning btrees. */
     386           0 :         if (sc->sm->sm_type != XFS_SCRUB_TYPE_AGF &&
     387           0 :             sc->sm->sm_type != XFS_SCRUB_TYPE_AGFL &&
     388             :             sc->sm->sm_type != XFS_SCRUB_TYPE_AGI)
     389             :                 return true;
     390             :         /*
     391             :          * If we're scanning a given type of AG header, we only want to
     392             :          * see read failures from that specific header.  We'd like the
     393             :          * other headers to cross-check them, but this isn't required.
     394             :          */
     395           0 :         if (sc->sm->sm_type == type)
     396             :                 return true;
     397             :         return false;
     398             : }
     399             : 
     400             : /*
     401             :  * Grab the AG header buffers for the attached perag structure.
     402             :  *
     403             :  * The headers should be released by xchk_ag_free, but as a fail safe we attach
     404             :  * all the buffers we grab to the scrub transaction so they'll all be freed
     405             :  * when we cancel it.
     406             :  */
     407             : static inline int
     408   526998960 : xchk_perag_read_headers(
     409             :         struct xfs_scrub        *sc,
     410             :         struct xchk_ag          *sa)
     411             : {
     412   526998960 :         int                     error;
     413             : 
     414   526998960 :         error = xfs_ialloc_read_agi(sa->pag, sc->tp, &sa->agi_bp);
     415   527034656 :         if (error && want_ag_read_header_failure(sc, XFS_SCRUB_TYPE_AGI))
     416             :                 return error;
     417             : 
     418   527034656 :         error = xfs_alloc_read_agf(sa->pag, sc->tp, 0, &sa->agf_bp);
     419   527034497 :         if (error && want_ag_read_header_failure(sc, XFS_SCRUB_TYPE_AGF))
     420           0 :                 return error;
     421             : 
     422             :         return 0;
     423             : }
     424             : 
     425             : /*
     426             :  * Grab the AG headers for the attached perag structure and wait for pending
     427             :  * intents to drain.
     428             :  */
     429             : static int
     430   526965183 : xchk_perag_drain_and_lock(
     431             :         struct xfs_scrub        *sc)
     432             : {
     433   526965183 :         struct xchk_ag          *sa = &sc->sa;
     434   526965183 :         int                     error = 0;
     435             : 
     436   526965183 :         ASSERT(sa->pag != NULL);
     437   526965183 :         ASSERT(sa->agi_bp == NULL);
     438   526965183 :         ASSERT(sa->agf_bp == NULL);
     439             : 
     440   526994859 :         do {
     441   526994859 :                 if (xchk_should_terminate(sc, &error))
     442           2 :                         return error;
     443             : 
     444   526988156 :                 error = xchk_perag_read_headers(sc, sa);
     445   527033996 :                 if (error)
     446           0 :                         return error;
     447             : 
     448             :                 /*
     449             :                  * If we've grabbed an inode for scrubbing then we assume that
     450             :                  * holding its ILOCK will suffice to coordinate with any intent
     451             :                  * chains involving this inode.
     452             :                  */
     453   527033996 :                 if (sc->ip)
     454             :                         return 0;
     455             : 
     456             :                 /*
     457             :                  * Decide if this AG is quiet enough for all metadata to be
     458             :                  * consistent with each other.  XFS allows the AG header buffer
     459             :                  * locks to cycle across transaction rolls while processing
     460             :                  * chains of deferred ops, which means that there could be
     461             :                  * other threads in the middle of processing a chain of
     462             :                  * deferred ops.  For regular operations we are careful about
     463             :                  * ordering operations to prevent collisions between threads
     464             :                  * (which is why we don't need a per-AG lock), but scrub and
     465             :                  * repair have to serialize against chained operations.
     466             :                  *
     467             :                  * We just locked all the AG headers buffers; now take a look
     468             :                  * to see if there are any intents in progress.  If there are,
     469             :                  * drop the AG headers and wait for the intents to drain.
     470             :                  * Since we hold all the AG header locks for the duration of
     471             :                  * the scrub, this is the only time we have to sample the
     472             :                  * intents counter; any threads increasing it after this point
     473             :                  * can't possibly be in the middle of a chain of AG metadata
     474             :                  * updates.
     475             :                  *
     476             :                  * Obviously, this should be slanted against scrub and in favor
     477             :                  * of runtime threads.
     478             :                  */
     479     8768303 :                 if (!xfs_perag_intent_busy(sa->pag))
     480             :                         return 0;
     481             : 
     482       79287 :                 if (sa->agf_bp) {
     483       79287 :                         xfs_trans_brelse(sc->tp, sa->agf_bp);
     484       79287 :                         sa->agf_bp = NULL;
     485             :                 }
     486             : 
     487       79287 :                 if (sa->agi_bp) {
     488       79287 :                         xfs_trans_brelse(sc->tp, sa->agi_bp);
     489       79287 :                         sa->agi_bp = NULL;
     490             :                 }
     491             : 
     492       79287 :                 if (!(sc->flags & XCHK_FSGATES_DRAIN))
     493             :                         return -ECHRNG;
     494       29676 :                 error = xfs_perag_intent_drain(sa->pag);
     495       29676 :                 if (error == -ERESTARTSYS)
     496           0 :                         error = -EINTR;
     497       29676 :         } while (!error);
     498             : 
     499             :         return error;
     500             : }
     501             : 
     502             : /*
     503             :  * Grab the per-AG structure, grab all AG header buffers, and wait until there
     504             :  * aren't any pending intents.  Returns -ENOENT if we can't grab the perag
     505             :  * structure.
     506             :  */
     507             : int
     508   526962277 : xchk_ag_read_headers(
     509             :         struct xfs_scrub        *sc,
     510             :         xfs_agnumber_t          agno,
     511             :         struct xchk_ag          *sa)
     512             : {
     513   526962277 :         struct xfs_mount        *mp = sc->mp;
     514             : 
     515   526962277 :         ASSERT(!sa->pag);
     516   526962277 :         sa->pag = xfs_perag_get(mp, agno);
     517   526959438 :         if (!sa->pag)
     518             :                 return -ENOENT;
     519             : 
     520   526959438 :         return xchk_perag_drain_and_lock(sc);
     521             : }
     522             : 
     523             : /* Release all the AG btree cursors. */
     524             : void
     525  2667929140 : xchk_ag_btcur_free(
     526             :         struct xchk_ag          *sa)
     527             : {
     528  2667929140 :         if (sa->refc_cur)
     529   331921605 :                 xfs_btree_del_cursor(sa->refc_cur, XFS_BTREE_ERROR);
     530  2668123287 :         if (sa->rmap_cur)
     531   331926839 :                 xfs_btree_del_cursor(sa->rmap_cur, XFS_BTREE_ERROR);
     532  2668888302 :         if (sa->fino_cur)
     533   526954412 :                 xfs_btree_del_cursor(sa->fino_cur, XFS_BTREE_ERROR);
     534  2668893370 :         if (sa->ino_cur)
     535   526957080 :                 xfs_btree_del_cursor(sa->ino_cur, XFS_BTREE_ERROR);
     536  2668883191 :         if (sa->cnt_cur)
     537   526955175 :                 xfs_btree_del_cursor(sa->cnt_cur, XFS_BTREE_ERROR);
     538  2669013953 :         if (sa->bno_cur)
     539   526956090 :                 xfs_btree_del_cursor(sa->bno_cur, XFS_BTREE_ERROR);
     540             : 
     541  2669014030 :         sa->refc_cur = NULL;
     542  2669014030 :         sa->rmap_cur = NULL;
     543  2669014030 :         sa->fino_cur = NULL;
     544  2669014030 :         sa->ino_cur = NULL;
     545  2669014030 :         sa->bno_cur = NULL;
     546  2669014030 :         sa->cnt_cur = NULL;
     547  2669014030 : }
     548             : 
     549             : /* Initialize all the btree cursors for an AG. */
     550             : void
     551   526962820 : xchk_ag_btcur_init(
     552             :         struct xfs_scrub        *sc,
     553             :         struct xchk_ag          *sa)
     554             : {
     555   526962820 :         struct xfs_mount        *mp = sc->mp;
     556             : 
     557  1053915548 :         if (sa->agf_bp &&
     558   526948801 :             xchk_ag_btree_healthy_enough(sc, sa->pag, XFS_BTNUM_BNO)) {
     559             :                 /* Set up a bnobt cursor for cross-referencing. */
     560   526953795 :                 sa->bno_cur = xfs_allocbt_init_cursor(mp, sc->tp, sa->agf_bp,
     561             :                                 sa->pag, XFS_BTNUM_BNO);
     562             :         }
     563             : 
     564  1053921505 :         if (sa->agf_bp &&
     565   526954682 :             xchk_ag_btree_healthy_enough(sc, sa->pag, XFS_BTNUM_CNT)) {
     566             :                 /* Set up a cntbt cursor for cross-referencing. */
     567   526954035 :                 sa->cnt_cur = xfs_allocbt_init_cursor(mp, sc->tp, sa->agf_bp,
     568             :                                 sa->pag, XFS_BTNUM_CNT);
     569             :         }
     570             : 
     571             :         /* Set up a inobt cursor for cross-referencing. */
     572  1053921508 :         if (sa->agi_bp &&
     573   526954699 :             xchk_ag_btree_healthy_enough(sc, sa->pag, XFS_BTNUM_INO)) {
     574   526954050 :                 sa->ino_cur = xfs_inobt_init_cursor(sa->pag, sc->tp, sa->agi_bp,
     575             :                                 XFS_BTNUM_INO);
     576             :         }
     577             : 
     578             :         /* Set up a finobt cursor for cross-referencing. */
     579  1053909982 :         if (sa->agi_bp && xfs_has_finobt(mp) &&
     580   526951837 :             xchk_ag_btree_healthy_enough(sc, sa->pag, XFS_BTNUM_FINO)) {
     581   526953423 :                 sa->fino_cur = xfs_inobt_init_cursor(sa->pag, sc->tp, sa->agi_bp,
     582             :                                 XFS_BTNUM_FINO);
     583             :         }
     584             : 
     585             :         /* Set up a rmapbt cursor for cross-referencing. */
     586   858884613 :         if (sa->agf_bp && xfs_has_rmapbt(mp) &&
     587   331923336 :             xchk_ag_btree_healthy_enough(sc, sa->pag, XFS_BTNUM_RMAP)) {
     588   331925569 :                 sa->rmap_cur = xfs_rmapbt_init_cursor(mp, sc->tp, sa->agf_bp,
     589             :                                 sa->pag);
     590             :         }
     591             : 
     592             :         /* Set up a refcountbt cursor for cross-referencing. */
     593   858885807 :         if (sa->agf_bp && xfs_has_reflink(mp) &&
     594   331925190 :             xchk_ag_btree_healthy_enough(sc, sa->pag, XFS_BTNUM_REFC)) {
     595   331925974 :                 sa->refc_cur = xfs_refcountbt_init_cursor(mp, sc->tp,
     596             :                                 sa->agf_bp, sa->pag);
     597             :         }
     598   526956521 : }
     599             : 
     600             : /* Release the AG header context and btree cursors. */
     601             : void
     602  2390112779 : xchk_ag_free(
     603             :         struct xfs_scrub        *sc,
     604             :         struct xchk_ag          *sa)
     605             : {
     606  2390112779 :         xchk_ag_btcur_free(sa);
     607  2391261355 :         if (sa->agf_bp) {
     608   526956531 :                 xfs_trans_brelse(sc->tp, sa->agf_bp);
     609   526956597 :                 sa->agf_bp = NULL;
     610             :         }
     611  2391261421 :         if (sa->agi_bp) {
     612   526955579 :                 xfs_trans_brelse(sc->tp, sa->agi_bp);
     613   526956946 :                 sa->agi_bp = NULL;
     614             :         }
     615  2391262788 :         if (sa->pag) {
     616   527006692 :                 xfs_perag_put(sa->pag);
     617   527002107 :                 sa->pag = NULL;
     618             :         }
     619  2391258203 : }
     620             : 
     621             : /*
     622             :  * For scrub, grab the perag structure, the AGI, and the AGF headers, in that
     623             :  * order.  Locking order requires us to get the AGI before the AGF.  We use the
     624             :  * transaction to avoid deadlocking on crosslinked metadata buffers; either the
     625             :  * caller passes one in (bmap scrub) or we have to create a transaction
     626             :  * ourselves.  Returns ENOENT if the perag struct cannot be grabbed.
     627             :  */
     628             : int
     629   523535857 : xchk_ag_init(
     630             :         struct xfs_scrub        *sc,
     631             :         xfs_agnumber_t          agno,
     632             :         struct xchk_ag          *sa)
     633             : {
     634   523535857 :         int                     error;
     635             : 
     636   523535857 :         error = xchk_ag_read_headers(sc, agno, sa);
     637   523574655 :         if (error)
     638             :                 return error;
     639             : 
     640   523555329 :         xchk_ag_btcur_init(sc, sa);
     641   523555329 :         return 0;
     642             : }
     643             : 
     644             : /* Per-scrubber setup functions */
     645             : 
     646             : void
     647         849 : xchk_trans_cancel(
     648             :         struct xfs_scrub        *sc)
     649             : {
     650         849 :         xfs_trans_cancel(sc->tp);
     651        5075 :         sc->tp = NULL;
     652           0 : }
     653             : 
     654             : /*
     655             :  * Grab an empty transaction so that we can re-grab locked buffers if
     656             :  * one of our btrees turns out to be cyclic.
     657             :  *
     658             :  * If we're going to repair something, we need to ask for the largest possible
     659             :  * log reservation so that we can handle the worst case scenario for metadata
     660             :  * updates while rebuilding a metadata item.  We also need to reserve as many
     661             :  * blocks in the head transaction as we think we're going to need to rebuild
     662             :  * the metadata object.
     663             :  */
     664             : int
     665  1864565407 : xchk_trans_alloc(
     666             :         struct xfs_scrub        *sc,
     667             :         uint                    resblks)
     668             : {
     669  1864565407 :         if (sc->sm->sm_flags & XFS_SCRUB_IFLAG_REPAIR)
     670   278734858 :                 return xfs_trans_alloc(sc->mp, &M_RES(sc->mp)->tr_itruncate,
     671             :                                 resblks, 0, 0, &sc->tp);
     672             : 
     673  1585830549 :         return xfs_trans_alloc_empty(sc->mp, &sc->tp);
     674             : }
     675             : 
     676             : /* Set us up with a transaction and an empty context. */
     677             : int
     678    10364863 : xchk_setup_fs(
     679             :         struct xfs_scrub        *sc)
     680             : {
     681    10364863 :         uint                    resblks;
     682             : 
     683    10364863 :         resblks = xrep_calc_ag_resblks(sc);
     684    10365229 :         return xchk_trans_alloc(sc, resblks);
     685             : }
     686             : 
     687             : /* Set us up with AG headers and btree cursors. */
     688             : int
     689     4237642 : xchk_setup_ag_btree(
     690             :         struct xfs_scrub        *sc,
     691             :         bool                    force_log)
     692             : {
     693     4237642 :         struct xfs_mount        *mp = sc->mp;
     694     4237642 :         int                     error;
     695             : 
     696             :         /*
     697             :          * If the caller asks us to checkpont the log, do so.  This
     698             :          * expensive operation should be performed infrequently and only
     699             :          * as a last resort.  Any caller that sets force_log should
     700             :          * document why they need to do so.
     701             :          */
     702     4237642 :         if (force_log) {
     703           0 :                 error = xchk_checkpoint_log(mp);
     704           0 :                 if (error)
     705             :                         return error;
     706             :         }
     707             : 
     708     4237642 :         error = xchk_setup_fs(sc);
     709     4237690 :         if (error)
     710             :                 return error;
     711             : 
     712     4237693 :         return xchk_ag_init(sc, sc->sm->sm_agno, &sc->sa);
     713             : }
     714             : 
     715             : /* Push everything out of the log onto disk. */
     716             : int
     717           0 : xchk_checkpoint_log(
     718             :         struct xfs_mount        *mp)
     719             : {
     720           0 :         int                     error;
     721             : 
     722           0 :         error = xfs_log_force(mp, XFS_LOG_SYNC);
     723           0 :         if (error)
     724             :                 return error;
     725           0 :         xfs_ail_push_all_sync(mp->m_ail);
     726           0 :         return 0;
     727             : }
     728             : 
     729             : /* Verify that an inode is allocated ondisk, then return its cached inode. */
     730             : int
     731  2039529824 : xchk_iget(
     732             :         struct xfs_scrub        *sc,
     733             :         xfs_ino_t               inum,
     734             :         struct xfs_inode        **ipp)
     735             : {
     736  2039529824 :         return xfs_iget(sc->mp, sc->tp, inum, XFS_IGET_UNTRUSTED, 0, ipp);
     737             : }
     738             : 
     739             : /*
     740             :  * Try to grab an inode in a manner that avoids races with physical inode
     741             :  * allocation.  If we can't, return the locked AGI buffer so that the caller
     742             :  * can single-step the loading process to see where things went wrong.
     743             :  * Callers must have a valid scrub transaction.
     744             :  *
     745             :  * If the iget succeeds, return 0, a NULL AGI, and the inode.
     746             :  *
     747             :  * If the iget fails, return the error, the locked AGI, and a NULL inode.  This
     748             :  * can include -EINVAL and -ENOENT for invalid inode numbers or inodes that are
     749             :  * no longer allocated; or any other corruption or runtime error.
     750             :  *
     751             :  * If the AGI read fails, return the error, a NULL AGI, and NULL inode.
     752             :  *
     753             :  * If a fatal signal is pending, return -EINTR, a NULL AGI, and a NULL inode.
     754             :  */
     755             : int
     756        5075 : xchk_iget_agi(
     757             :         struct xfs_scrub        *sc,
     758             :         xfs_ino_t               inum,
     759             :         struct xfs_buf          **agi_bpp,
     760             :         struct xfs_inode        **ipp)
     761             : {
     762        5075 :         struct xfs_mount        *mp = sc->mp;
     763        5075 :         struct xfs_trans        *tp = sc->tp;
     764        5075 :         struct xfs_perag        *pag;
     765        5075 :         int                     error;
     766             : 
     767        5075 :         ASSERT(sc->tp != NULL);
     768             : 
     769        5075 : again:
     770        5075 :         *agi_bpp = NULL;
     771        5075 :         *ipp = NULL;
     772        5075 :         error = 0;
     773             : 
     774        5075 :         if (xchk_should_terminate(sc, &error))
     775           0 :                 return error;
     776             : 
     777             :         /*
     778             :          * Attach the AGI buffer to the scrub transaction to avoid deadlocks
     779             :          * in the iget cache miss path.
     780             :          */
     781        5075 :         pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, inum));
     782        5075 :         error = xfs_ialloc_read_agi(pag, tp, agi_bpp);
     783        5075 :         xfs_perag_put(pag);
     784        5075 :         if (error)
     785           0 :                 return error;
     786             : 
     787        5075 :         error = xfs_iget(mp, tp, inum,
     788             :                         XFS_IGET_NORETRY | XFS_IGET_UNTRUSTED, 0, ipp);
     789        5075 :         if (error == -EAGAIN) {
     790             :                 /*
     791             :                  * The inode may be in core but temporarily unavailable and may
     792             :                  * require the AGI buffer before it can be returned.  Drop the
     793             :                  * AGI buffer and retry the lookup.
     794             :                  *
     795             :                  * Incore lookup will fail with EAGAIN on a cache hit if the
     796             :                  * inode is queued to the inactivation list.  The inactivation
     797             :                  * worker may remove the inode from the unlinked list and hence
     798             :                  * needs the AGI.
     799             :                  *
     800             :                  * Hence xchk_iget_agi() needs to drop the AGI lock on EAGAIN
     801             :                  * to allow inodegc to make progress and move the inode to
     802             :                  * IRECLAIMABLE state where xfs_iget will be able to return it
     803             :                  * again if it can lock the inode.
     804             :                  */
     805           0 :                 xfs_trans_brelse(tp, *agi_bpp);
     806           0 :                 delay(1);
     807           0 :                 goto again;
     808             :         }
     809        5075 :         if (error)
     810             :                 return error;
     811             : 
     812             :         /* We got the inode, so we can release the AGI. */
     813           0 :         ASSERT(*ipp != NULL);
     814           0 :         xfs_trans_brelse(tp, *agi_bpp);
     815           0 :         *agi_bpp = NULL;
     816           0 :         return 0;
     817             : }
     818             : 
     819             : /* Install an inode that we opened by handle for scrubbing. */
     820             : int
     821  1402333040 : xchk_install_handle_inode(
     822             :         struct xfs_scrub        *sc,
     823             :         struct xfs_inode        *ip)
     824             : {
     825  1402333040 :         if (VFS_I(ip)->i_generation != sc->sm->sm_gen) {
     826      640975 :                 xchk_irele(sc, ip);
     827      640975 :                 return -ENOENT;
     828             :         }
     829             : 
     830  1401692065 :         sc->ip = ip;
     831  1401692065 :         return 0;
     832             : }
     833             : 
     834             : /*
     835             :  * In preparation to scrub metadata structures that hang off of an inode,
     836             :  * grab either the inode referenced in the scrub control structure or the
     837             :  * inode passed in.  If the inumber does not reference an allocated inode
     838             :  * record, the function returns ENOENT to end the scrub early.  The inode
     839             :  * is not locked.
     840             :  */
     841             : int
     842  1538307175 : xchk_iget_for_scrubbing(
     843             :         struct xfs_scrub        *sc)
     844             : {
     845  1538307175 :         struct xfs_imap         imap;
     846  1538307175 :         struct xfs_mount        *mp = sc->mp;
     847  1538307175 :         struct xfs_perag        *pag;
     848  1538307175 :         struct xfs_buf          *agi_bp;
     849  1538307175 :         struct xfs_inode        *ip_in = XFS_I(file_inode(sc->file));
     850  1538307175 :         struct xfs_inode        *ip = NULL;
     851  1538307175 :         xfs_agnumber_t          agno = XFS_INO_TO_AGNO(mp, sc->sm->sm_ino);
     852  1538307175 :         int                     error;
     853             : 
     854  1538307175 :         ASSERT(sc->tp == NULL);
     855             : 
     856             :         /* We want to scan the inode we already had opened. */
     857  1538307175 :         if (sc->sm->sm_ino == 0 || sc->sm->sm_ino == ip_in->i_ino) {
     858   377611675 :                 sc->ip = ip_in;
     859   377611675 :                 return 0;
     860             :         }
     861             : 
     862             :         /* Reject internal metadata files and obviously bad inode numbers. */
     863  1160695500 :         if (xfs_internal_inum(mp, sc->sm->sm_ino))
     864             :                 return -ENOENT;
     865  1157988694 :         if (!xfs_verify_ino(sc->mp, sc->sm->sm_ino))
     866             :                 return -ENOENT;
     867             : 
     868             :         /* Try a regular untrusted iget. */
     869  1157905935 :         error = xchk_iget(sc, sc->sm->sm_ino, &ip);
     870  1156581357 :         if (!error)
     871  1152387781 :                 return xchk_install_handle_inode(sc, ip);
     872     4193576 :         if (error == -ENOENT)
     873             :                 return error;
     874        4226 :         if (error != -EINVAL)
     875           0 :                 goto out_error;
     876             : 
     877             :         /*
     878             :          * EINVAL with IGET_UNTRUSTED probably means one of several things:
     879             :          * userspace gave us an inode number that doesn't correspond to fs
     880             :          * space; the inode btree lacks a record for this inode; or there is a
     881             :          * record, and it says this inode is free.
     882             :          *
     883             :          * We want to look up this inode in the inobt to distinguish two
     884             :          * scenarios: (1) the inobt says the inode is free, in which case
     885             :          * there's nothing to do; and (2) the inobt says the inode is
     886             :          * allocated, but loading it failed due to corruption.
     887             :          *
     888             :          * Allocate a transaction and grab the AGI to prevent inobt activity
     889             :          * in this AG.  Retry the iget in case someone allocated a new inode
     890             :          * after the first iget failed.
     891             :          */
     892        4226 :         error = xchk_trans_alloc(sc, 0);
     893        4226 :         if (error)
     894           0 :                 goto out_error;
     895             : 
     896        4226 :         error = xchk_iget_agi(sc, sc->sm->sm_ino, &agi_bp, &ip);
     897        4226 :         if (error == 0) {
     898             :                 /* Actually got the inode, so install it. */
     899           0 :                 xchk_trans_cancel(sc);
     900           0 :                 return xchk_install_handle_inode(sc, ip);
     901             :         }
     902        4226 :         if (error == -ENOENT)
     903           0 :                 goto out_gone;
     904        4226 :         if (error != -EINVAL)
     905           0 :                 goto out_cancel;
     906             : 
     907             :         /* Ensure that we have protected against inode allocation/freeing. */
     908        4226 :         if (agi_bp == NULL) {
     909           0 :                 ASSERT(agi_bp != NULL);
     910           0 :                 error = -ECANCELED;
     911           0 :                 goto out_cancel;
     912             :         }
     913             : 
     914             :         /*
     915             :          * Untrusted iget failed a second time.  Let's try an inobt lookup.
     916             :          * If the inobt thinks this the inode neither can exist inside the
     917             :          * filesystem nor is allocated, return ENOENT to signal that the check
     918             :          * can be skipped.
     919             :          *
     920             :          * If the lookup returns corruption, we'll mark this inode corrupt and
     921             :          * exit to userspace.  There's little chance of fixing anything until
     922             :          * the inobt is straightened out, but there's nothing we can do here.
     923             :          *
     924             :          * If the lookup encounters any other error, exit to userspace.
     925             :          *
     926             :          * If the lookup succeeds, something else must be very wrong in the fs
     927             :          * such that setting up the incore inode failed in some strange way.
     928             :          * Treat those as corruptions.
     929             :          */
     930        4226 :         pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, sc->sm->sm_ino));
     931        4226 :         if (!pag) {
     932           0 :                 error = -EFSCORRUPTED;
     933           0 :                 goto out_cancel;
     934             :         }
     935             : 
     936        4226 :         error = xfs_imap(pag, sc->tp, sc->sm->sm_ino, &imap,
     937             :                         XFS_IGET_UNTRUSTED);
     938        4226 :         xfs_perag_put(pag);
     939        4226 :         if (error == -EINVAL || error == -ENOENT)
     940        4226 :                 goto out_gone;
     941           0 :         if (!error)
     942           0 :                 error = -EFSCORRUPTED;
     943             : 
     944           0 : out_cancel:
     945           0 :         xchk_trans_cancel(sc);
     946           0 : out_error:
     947           0 :         trace_xchk_op_error(sc, agno, XFS_INO_TO_AGBNO(mp, sc->sm->sm_ino),
     948             :                         error, __return_address);
     949           0 :         return error;
     950        4226 : out_gone:
     951             :         /* The file is gone, so there's nothing to check. */
     952        4226 :         xchk_trans_cancel(sc);
     953        4226 :         return -ENOENT;
     954             : }
     955             : 
     956             : /* Release an inode, possibly dropping it in the process. */
     957             : void
     958  2035477236 : xchk_irele(
     959             :         struct xfs_scrub        *sc,
     960             :         struct xfs_inode        *ip)
     961             : {
     962  2035477236 :         if (current->journal_info != NULL) {
     963   633313036 :                 ASSERT(current->journal_info == sc->tp);
     964             : 
     965             :                 /*
     966             :                  * If we are in a transaction, we /cannot/ drop the inode
     967             :                  * ourselves, because the VFS will trigger writeback, which
     968             :                  * can require a transaction.  Clear DONTCACHE to force the
     969             :                  * inode to the LRU, where someone else can take care of
     970             :                  * dropping it.
     971             :                  *
     972             :                  * Note that when we grabbed our reference to the inode, it
     973             :                  * could have had an active ref and DONTCACHE set if a sysadmin
     974             :                  * is trying to coerce a change in file access mode.  icache
     975             :                  * hits do not clear DONTCACHE, so we must do it here.
     976             :                  */
     977   633313036 :                 spin_lock(&VFS_I(ip)->i_lock);
     978   633404839 :                 VFS_I(ip)->i_state &= ~I_DONTCACHE;
     979   633404839 :                 spin_unlock(&VFS_I(ip)->i_lock);
     980  1402164200 :         } else if (atomic_read(&VFS_I(ip)->i_count) == 1) {
     981             :                 /*
     982             :                  * If this is the last reference to the inode and the caller
     983             :                  * permits it, set DONTCACHE to avoid thrashing.
     984             :                  */
     985   210175684 :                 d_mark_dontcache(VFS_I(ip));
     986             :         }
     987             : 
     988  2035635427 :         xfs_irele(ip);
     989  2034891038 : }
     990             : 
     991             : /*
     992             :  * Set us up to scrub metadata mapped by a file's fork.  Callers must not use
     993             :  * this to operate on user-accessible regular file data because the MMAPLOCK is
     994             :  * not taken.
     995             :  */
     996             : int
     997   638854798 : xchk_setup_inode_contents(
     998             :         struct xfs_scrub        *sc,
     999             :         unsigned int            resblks)
    1000             : {
    1001   638854798 :         int                     error;
    1002             : 
    1003   638854798 :         error = xchk_iget_for_scrubbing(sc);
    1004   638776363 :         if (error)
    1005             :                 return error;
    1006             : 
    1007             :         /* Lock the inode so the VFS cannot touch this file. */
    1008   635765501 :         sc->ilock_flags = XFS_IOLOCK_EXCL;
    1009   635765501 :         xfs_ilock(sc->ip, sc->ilock_flags);
    1010             : 
    1011   635844550 :         error = xchk_trans_alloc(sc, resblks);
    1012   635816311 :         if (error)
    1013           0 :                 goto out;
    1014   635816311 :         sc->ilock_flags |= XFS_ILOCK_EXCL;
    1015   635816311 :         xfs_ilock(sc->ip, XFS_ILOCK_EXCL);
    1016             : 
    1017             : out:
    1018             :         /* scrub teardown will unlock and release the inode for us */
    1019             :         return error;
    1020             : }
    1021             : 
    1022             : /*
    1023             :  * Predicate that decides if we need to evaluate the cross-reference check.
    1024             :  * If there was an error accessing the cross-reference btree, just delete
    1025             :  * the cursor and skip the check.
    1026             :  */
    1027             : bool
    1028 10122762715 : xchk_should_check_xref(
    1029             :         struct xfs_scrub        *sc,
    1030             :         int                     *error,
    1031             :         struct xfs_btree_cur    **curpp)
    1032             : {
    1033             :         /* No point in xref if we already know we're corrupt. */
    1034 10122762715 :         if (xchk_skip_xref(sc->sm))
    1035             :                 return false;
    1036             : 
    1037 10122762715 :         if (*error == 0)
    1038             :                 return true;
    1039             : 
    1040           0 :         if (curpp) {
    1041             :                 /* If we've already given up on xref, just bail out. */
    1042           0 :                 if (!*curpp)
    1043             :                         return false;
    1044             : 
    1045             :                 /* xref error, delete cursor and bail out. */
    1046           0 :                 xfs_btree_del_cursor(*curpp, XFS_BTREE_ERROR);
    1047           0 :                 *curpp = NULL;
    1048             :         }
    1049             : 
    1050           0 :         sc->sm->sm_flags |= XFS_SCRUB_OFLAG_XFAIL;
    1051           0 :         trace_xchk_xref_error(sc, *error, __return_address);
    1052             : 
    1053             :         /*
    1054             :          * Errors encountered during cross-referencing with another
    1055             :          * data structure should not cause this scrubber to abort.
    1056             :          */
    1057           0 :         *error = 0;
    1058           0 :         return false;
    1059             : }
    1060             : 
    1061             : /* Run the structure verifiers on in-memory buffers to detect bad memory. */
    1062             : void
    1063   144240646 : xchk_buffer_recheck(
    1064             :         struct xfs_scrub        *sc,
    1065             :         struct xfs_buf          *bp)
    1066             : {
    1067   144240646 :         xfs_failaddr_t          fa;
    1068             : 
    1069   144240646 :         if (bp->b_ops == NULL) {
    1070           0 :                 xchk_block_set_corrupt(sc, bp);
    1071           0 :                 return;
    1072             :         }
    1073   144240646 :         if (bp->b_ops->verify_struct == NULL) {
    1074           0 :                 xchk_set_incomplete(sc);
    1075           0 :                 return;
    1076             :         }
    1077   144240646 :         fa = bp->b_ops->verify_struct(bp);
    1078   144232359 :         if (!fa)
    1079             :                 return;
    1080           0 :         sc->sm->sm_flags |= XFS_SCRUB_OFLAG_CORRUPT;
    1081           0 :         trace_xchk_block_error(sc, xfs_buf_daddr(bp), fa);
    1082             : }
    1083             : 
    1084             : static inline int
    1085     1958934 : xchk_metadata_inode_subtype(
    1086             :         struct xfs_scrub        *sc,
    1087             :         unsigned int            scrub_type)
    1088             : {
    1089     1958934 :         __u32                   smtype = sc->sm->sm_type;
    1090     1958934 :         int                     error;
    1091             : 
    1092     1958934 :         sc->sm->sm_type = scrub_type;
    1093             : 
    1094     1958934 :         switch (scrub_type) {
    1095      979467 :         case XFS_SCRUB_TYPE_INODE:
    1096      979467 :                 error = xchk_inode(sc);
    1097      979467 :                 break;
    1098      979467 :         case XFS_SCRUB_TYPE_BMBTD:
    1099      979467 :                 error = xchk_bmap_data(sc);
    1100      979467 :                 break;
    1101           0 :         default:
    1102           0 :                 ASSERT(0);
    1103           0 :                 error = -EFSCORRUPTED;
    1104           0 :                 break;
    1105             :         }
    1106             : 
    1107     1958934 :         sc->sm->sm_type = smtype;
    1108     1958934 :         return error;
    1109             : }
    1110             : 
    1111             : /*
    1112             :  * Scrub the attr/data forks of a metadata inode.  The metadata inode must be
    1113             :  * pointed to by sc->ip and the ILOCK must be held.
    1114             :  */
    1115             : int
    1116      979467 : xchk_metadata_inode_forks(
    1117             :         struct xfs_scrub        *sc)
    1118             : {
    1119      979467 :         bool                    shared;
    1120      979467 :         int                     error;
    1121             : 
    1122      979467 :         if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)
    1123             :                 return 0;
    1124             : 
    1125             :         /* Check the inode record. */
    1126      979467 :         error = xchk_metadata_inode_subtype(sc, XFS_SCRUB_TYPE_INODE);
    1127      979467 :         if (error || (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT))
    1128             :                 return error;
    1129             : 
    1130             :         /* Metadata inodes don't live on the rt device. */
    1131      979467 :         if (sc->ip->i_diflags & XFS_DIFLAG_REALTIME) {
    1132           0 :                 xchk_ino_set_corrupt(sc, sc->ip->i_ino);
    1133           0 :                 return 0;
    1134             :         }
    1135             : 
    1136             :         /* They should never participate in reflink. */
    1137      979467 :         if (xfs_is_reflink_inode(sc->ip)) {
    1138           0 :                 xchk_ino_set_corrupt(sc, sc->ip->i_ino);
    1139           0 :                 return 0;
    1140             :         }
    1141             : 
    1142             :         /* They also should never have extended attributes. */
    1143      979467 :         if (xfs_inode_hasattr(sc->ip)) {
    1144           0 :                 xchk_ino_set_corrupt(sc, sc->ip->i_ino);
    1145           0 :                 return 0;
    1146             :         }
    1147             : 
    1148             :         /* Invoke the data fork scrubber. */
    1149      979467 :         error = xchk_metadata_inode_subtype(sc, XFS_SCRUB_TYPE_BMBTD);
    1150      979467 :         if (error || (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT))
    1151             :                 return error;
    1152             : 
    1153             :         /* Look for incorrect shared blocks. */
    1154      979466 :         if (xfs_has_reflink(sc->mp)) {
    1155      377914 :                 error = xfs_reflink_inode_has_shared_extents(sc->tp, sc->ip,
    1156             :                                 &shared);
    1157      755828 :                 if (!xchk_fblock_process_error(sc, XFS_DATA_FORK, 0,
    1158             :                                 &error))
    1159           0 :                         return error;
    1160      377914 :                 if (shared)
    1161           0 :                         xchk_ino_set_corrupt(sc, sc->ip->i_ino);
    1162             :         }
    1163             : 
    1164             :         return 0;
    1165             : }
    1166             : 
    1167             : /*
    1168             :  * Enable filesystem hooks (i.e. runtime code patching) before starting a scrub
    1169             :  * operation.  Callers must not hold any locks that intersect with the CPU
    1170             :  * hotplug lock (e.g. writeback locks) because code patching must halt the CPUs
    1171             :  * to change kernel code.
    1172             :  */
    1173             : void
    1174       49232 : xchk_fsgates_enable(
    1175             :         struct xfs_scrub        *sc,
    1176             :         unsigned int            scrub_fsgates)
    1177             : {
    1178       49232 :         ASSERT(!(scrub_fsgates & ~XCHK_FSGATES_ALL));
    1179       49232 :         ASSERT(!(sc->flags & scrub_fsgates));
    1180             : 
    1181       49232 :         trace_xchk_fsgates_enable(sc, scrub_fsgates);
    1182             : 
    1183       49232 :         if (scrub_fsgates & XCHK_FSGATES_DRAIN)
    1184       49232 :                 xfs_drain_wait_enable();
    1185             : 
    1186       49232 :         sc->flags |= scrub_fsgates;
    1187       49232 : }

Generated by: LCOV version 1.14