LCOV - code coverage report
Current view: top level - fs/xfs/scrub - bmap_repair.c (source / functions) Hit Total Coverage
Test: fstests of 6.5.0-rc4-xfsx @ Mon Jul 31 20:08:34 PDT 2023 Lines: 346 367 94.3 %
Date: 2023-07-31 20:08:34 Functions: 24 24 100.0 %

          Line data    Source code
       1             : // SPDX-License-Identifier: GPL-2.0-or-later
       2             : /*
       3             :  * Copyright (C) 2018-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_defer.h"
      13             : #include "xfs_btree.h"
      14             : #include "xfs_btree_staging.h"
      15             : #include "xfs_bit.h"
      16             : #include "xfs_log_format.h"
      17             : #include "xfs_trans.h"
      18             : #include "xfs_sb.h"
      19             : #include "xfs_inode.h"
      20             : #include "xfs_inode_fork.h"
      21             : #include "xfs_alloc.h"
      22             : #include "xfs_rtalloc.h"
      23             : #include "xfs_bmap.h"
      24             : #include "xfs_bmap_util.h"
      25             : #include "xfs_bmap_btree.h"
      26             : #include "xfs_rmap.h"
      27             : #include "xfs_rmap_btree.h"
      28             : #include "xfs_rtrmap_btree.h"
      29             : #include "xfs_refcount.h"
      30             : #include "xfs_quota.h"
      31             : #include "xfs_ialloc.h"
      32             : #include "xfs_ag.h"
      33             : #include "xfs_reflink.h"
      34             : #include "xfs_rtgroup.h"
      35             : #include "scrub/xfs_scrub.h"
      36             : #include "scrub/scrub.h"
      37             : #include "scrub/common.h"
      38             : #include "scrub/btree.h"
      39             : #include "scrub/trace.h"
      40             : #include "scrub/repair.h"
      41             : #include "scrub/bitmap.h"
      42             : #include "scrub/xfile.h"
      43             : #include "scrub/xfarray.h"
      44             : #include "scrub/newbt.h"
      45             : #include "scrub/reap.h"
      46             : 
      47             : /*
      48             :  * Inode Fork Block Mapping (BMBT) Repair
      49             :  * ======================================
      50             :  *
      51             :  * Gather all the rmap records for the inode and fork we're fixing, reset the
      52             :  * incore fork, then recreate the btree.
      53             :  */
      54             : struct xrep_bmap {
      55             :         /* Old bmbt blocks */
      56             :         struct xfsb_bitmap      old_bmbt_blocks;
      57             : 
      58             :         /* New fork. */
      59             :         struct xrep_newbt       new_bmapbt;
      60             : 
      61             :         /* List of new bmap records. */
      62             :         struct xfarray          *bmap_records;
      63             : 
      64             :         struct xfs_scrub        *sc;
      65             : 
      66             :         /* How many blocks did we find allocated to this file? */
      67             :         xfs_rfsblock_t          nblocks;
      68             : 
      69             :         /* How many bmbt blocks did we find for this fork? */
      70             :         xfs_rfsblock_t          old_bmbt_block_count;
      71             : 
      72             :         /* get_records()'s position in the free space record array. */
      73             :         xfarray_idx_t           array_cur;
      74             : 
      75             :         /* How many real (non-hole, non-delalloc) mappings do we have? */
      76             :         uint64_t                real_mappings;
      77             : 
      78             :         /* Which fork are we fixing? */
      79             :         int                     whichfork;
      80             : 
      81             :         /* Are there shared extents? */
      82             :         bool                    shared_extents;
      83             : 
      84             :         /* Do we allow unwritten extents? */
      85             :         bool                    allow_unwritten;
      86             : };
      87             : 
      88             : /* Is this space extent shared?  Flag the inode if it is. */
      89             : STATIC int
      90    83851926 : xrep_bmap_discover_shared(
      91             :         struct xrep_bmap        *rb,
      92             :         xfs_fsblock_t           startblock,
      93             :         xfs_filblks_t           blockcount,
      94             :         bool                    unwritten)
      95             : {
      96    83851926 :         struct xfs_scrub        *sc = rb->sc;
      97    83851926 :         struct xfs_btree_cur    *cur;
      98    83851926 :         xfs_agblock_t           agbno;
      99    83851926 :         xfs_agblock_t           fbno;
     100    83851926 :         xfs_extlen_t            flen;
     101    83851926 :         int                     error;
     102             : 
     103             :         /*
     104             :          * Only investigate if we need to set the shared extents flag if we are
     105             :          * adding a written extent mapping to the data fork of a regular file
     106             :          * on reflink filesystem.
     107             :          */
     108    83851926 :         if (rb->shared_extents)
     109             :                 return 0;
     110    64530419 :         if (unwritten)
     111             :                 return 0;
     112    63880178 :         if (rb->whichfork != XFS_DATA_FORK)
     113             :                 return 0;
     114    63821301 :         if (!S_ISREG(VFS_I(sc->ip)->i_mode))
     115             :                 return 0;
     116    63771682 :         if (!xfs_has_reflink(sc->mp))
     117             :                 return 0;
     118             : 
     119    63766850 :         if (XFS_IS_REALTIME_INODE(sc->ip)) {
     120     2584583 :                 xfs_rgnumber_t          rgno;
     121             : 
     122     2584583 :                 agbno = xfs_rtb_to_rgbno(sc->mp, startblock, &rgno);
     123     2584590 :                 cur = sc->sr.refc_cur;
     124             :         } else {
     125    61182267 :                 agbno = XFS_FSB_TO_AGBNO(sc->mp, startblock);
     126    61182267 :                 cur = sc->sa.refc_cur;
     127             :         }
     128    63766857 :         error = xfs_refcount_find_shared(cur, agbno, blockcount, &fbno, &flen,
     129             :                         false);
     130    63766700 :         if (error)
     131             :                 return error;
     132             : 
     133    63766700 :         if (fbno != NULLAGBLOCK)
     134           0 :                 rb->shared_extents = true;
     135             : 
     136             :         return 0;
     137             : }
     138             : 
     139             : /* Remember this reverse-mapping as a series of bmap records. */
     140             : STATIC int
     141    83851644 : xrep_bmap_from_rmap(
     142             :         struct xrep_bmap        *rb,
     143             :         xfs_fileoff_t           startoff,
     144             :         xfs_fsblock_t           startblock,
     145             :         xfs_filblks_t           blockcount,
     146             :         bool                    unwritten)
     147             : {
     148    83851644 :         struct xfs_bmbt_irec    irec = {
     149             :                 .br_startoff    = startoff,
     150             :                 .br_startblock  = startblock,
     151    83851644 :                 .br_state       = unwritten ? XFS_EXT_UNWRITTEN : XFS_EXT_NORM,
     152             :         };
     153    83851644 :         struct xfs_bmbt_rec     rbe;
     154    83851644 :         struct xfs_scrub        *sc = rb->sc;
     155    83851644 :         int                     error = 0;
     156             : 
     157             :         /*
     158             :          * If we're repairing the data fork of a non-reflinked regular file on
     159             :          * a reflink filesystem, we need to figure out if this space extent is
     160             :          * shared.
     161             :          */
     162    83851644 :         error = xrep_bmap_discover_shared(rb, startblock, blockcount,
     163             :                         unwritten);
     164    83851559 :         if (error)
     165             :                 return error;
     166             : 
     167    83851563 :         do {
     168    83851563 :                 xfs_failaddr_t  fa;
     169             : 
     170    83851563 :                 irec.br_blockcount = min_t(xfs_filblks_t, blockcount,
     171             :                                 XFS_MAX_BMBT_EXTLEN);
     172             : 
     173    83851563 :                 fa = xfs_bmap_validate_extent(sc->ip, rb->whichfork, &irec);
     174    83851503 :                 if (fa)
     175             :                         return -EFSCORRUPTED;
     176             : 
     177    83851503 :                 xfs_bmbt_disk_set_all(&rbe, &irec);
     178             : 
     179    83851468 :                 trace_xrep_bmap_found(sc->ip, rb->whichfork, &irec);
     180             : 
     181    83851338 :                 if (xchk_should_terminate(sc, &error))
     182           0 :                         return error;
     183             : 
     184    83851539 :                 error = xfarray_append(rb->bmap_records, &rbe);
     185    83851864 :                 if (error)
     186           0 :                         return error;
     187             : 
     188    83851864 :                 rb->real_mappings++;
     189             : 
     190    83851864 :                 irec.br_startblock += irec.br_blockcount;
     191    83851864 :                 irec.br_startoff += irec.br_blockcount;
     192    83851864 :                 blockcount -= irec.br_blockcount;
     193    83851864 :         } while (blockcount > 0);
     194             : 
     195             :         return 0;
     196             : }
     197             : 
     198             : /* Check for any obvious errors or conflicts in the file mapping. */
     199             : STATIC int
     200    68634651 : xrep_bmap_check_fork_rmap(
     201             :         struct xrep_bmap                *rb,
     202             :         struct xfs_btree_cur            *cur,
     203             :         const struct xfs_rmap_irec      *rec)
     204             : {
     205    68634651 :         struct xfs_scrub                *sc = rb->sc;
     206    68634651 :         enum xbtree_recpacking          outcome;
     207    68634651 :         int                             error;
     208             : 
     209             :         /*
     210             :          * Data extents for rt files are never stored on the data device, but
     211             :          * everything else (xattrs, bmbt blocks) can be.
     212             :          */
     213    68634651 :         if (XFS_IS_REALTIME_INODE(sc->ip) &&
     214      111258 :             !(rec->rm_flags & (XFS_RMAP_ATTR_FORK | XFS_RMAP_BMBT_BLOCK)))
     215             :                 return -EFSCORRUPTED;
     216             : 
     217             :         /* Check that this is within the AG. */
     218    68634651 :         if (!xfs_verify_agbext(cur->bc_ag.pag, rec->rm_startblock,
     219    68634651 :                                 rec->rm_blockcount))
     220             :                 return -EFSCORRUPTED;
     221             : 
     222             :         /* Check the file offset range. */
     223   137080067 :         if (!(rec->rm_flags & XFS_RMAP_BMBT_BLOCK) &&
     224    68445419 :             !xfs_verify_fileext(sc->mp, rec->rm_offset, rec->rm_blockcount))
     225             :                 return -EFSCORRUPTED;
     226             : 
     227             :         /* No contradictory flags. */
     228    68634648 :         if ((rec->rm_flags & (XFS_RMAP_ATTR_FORK | XFS_RMAP_BMBT_BLOCK)) &&
     229      254952 :             (rec->rm_flags & XFS_RMAP_UNWRITTEN))
     230             :                 return -EFSCORRUPTED;
     231             : 
     232             :         /* Make sure this isn't free space. */
     233    68634648 :         error = xfs_alloc_has_records(sc->sa.bno_cur, rec->rm_startblock,
     234    68634648 :                         rec->rm_blockcount, &outcome);
     235    68634644 :         if (error)
     236             :                 return error;
     237    68634644 :         if (outcome != XBTREE_RECPACKING_EMPTY)
     238             :                 return -EFSCORRUPTED;
     239             : 
     240             :         /* Must not be an inode chunk. */
     241    68634644 :         error = xfs_ialloc_has_inodes_at_extent(sc->sa.ino_cur,
     242    68634644 :                         rec->rm_startblock, rec->rm_blockcount, &outcome);
     243    68634661 :         if (error)
     244             :                 return error;
     245    68634661 :         if (outcome != XBTREE_RECPACKING_EMPTY)
     246           0 :                 return -EFSCORRUPTED;
     247             : 
     248             :         return 0;
     249             : }
     250             : 
     251             : /* Record extents that belong to this inode's fork. */
     252             : STATIC int
     253 35313860850 : xrep_bmap_walk_rmap(
     254             :         struct xfs_btree_cur            *cur,
     255             :         const struct xfs_rmap_irec      *rec,
     256             :         void                            *priv)
     257             : {
     258 35313860850 :         struct xrep_bmap                *rb = priv;
     259 35313860850 :         struct xfs_mount                *mp = cur->bc_mp;
     260 35313860850 :         xfs_fsblock_t                   fsbno;
     261 35313860850 :         int                             error = 0;
     262             : 
     263 35313860850 :         if (xchk_should_terminate(rb->sc, &error))
     264           3 :                 return error;
     265             : 
     266 35315622965 :         if (rec->rm_owner != rb->sc->ip->i_ino)
     267             :                 return 0;
     268             : 
     269    68634657 :         error = xrep_bmap_check_fork_rmap(rb, cur, rec);
     270    68634660 :         if (error)
     271             :                 return error;
     272             : 
     273             :         /*
     274             :          * Record all blocks allocated to this file even if the extent isn't
     275             :          * for the fork we're rebuilding so that we can reset di_nblocks later.
     276             :          */
     277    68634660 :         rb->nblocks += rec->rm_blockcount;
     278             : 
     279             :         /* If this rmap isn't for the fork we want, we're done. */
     280    68634660 :         if (rb->whichfork == XFS_DATA_FORK &&
     281    68529040 :             (rec->rm_flags & XFS_RMAP_ATTR_FORK))
     282             :                 return 0;
     283    68627811 :         if (rb->whichfork == XFS_ATTR_FORK &&
     284      105620 :             !(rec->rm_flags & XFS_RMAP_ATTR_FORK))
     285             :                 return 0;
     286             : 
     287             :         /* Reject unwritten extents if we don't allow those. */
     288    68581075 :         if ((rec->rm_flags & XFS_RMAP_UNWRITTEN) && !rb->allow_unwritten)
     289             :                 return -EFSCORRUPTED;
     290             : 
     291    68581075 :         fsbno = XFS_AGB_TO_FSB(mp, cur->bc_ag.pag->pag_agno,
     292             :                         rec->rm_startblock);
     293             : 
     294    68581075 :         if (rec->rm_flags & XFS_RMAP_BMBT_BLOCK) {
     295      187024 :                 rb->old_bmbt_block_count += rec->rm_blockcount;
     296      187024 :                 return xfsb_bitmap_set(&rb->old_bmbt_blocks, fsbno,
     297      187024 :                                 rec->rm_blockcount);
     298             :         }
     299             : 
     300    68394051 :         return xrep_bmap_from_rmap(rb, rec->rm_offset, fsbno,
     301    68394051 :                         rec->rm_blockcount,
     302    68394051 :                         rec->rm_flags & XFS_RMAP_UNWRITTEN);
     303             : }
     304             : 
     305             : /*
     306             :  * Compare two block mapping records.  We want to sort in order of increasing
     307             :  * file offset.
     308             :  */
     309             : static int
     310  1161476327 : xrep_bmap_extent_cmp(
     311             :         const void                      *a,
     312             :         const void                      *b)
     313             : {
     314  1161476327 :         xfs_fileoff_t                   ao;
     315  1161476327 :         xfs_fileoff_t                   bo;
     316             : 
     317  1161476327 :         ao = xfs_bmbt_disk_get_startoff((struct xfs_bmbt_rec *)a);
     318  1161476247 :         bo = xfs_bmbt_disk_get_startoff((struct xfs_bmbt_rec *)b);
     319             : 
     320  1161476457 :         if (ao > bo)
     321             :                 return 1;
     322   605448797 :         else if (ao < bo)
     323   605448790 :                 return -1;
     324             :         return 0;
     325             : }
     326             : 
     327             : /*
     328             :  * Sort the bmap extents by fork offset or else the records will be in the
     329             :  * wrong order.  Ensure there are no overlaps in the file offset ranges.
     330             :  */
     331             : STATIC int
     332     3340419 : xrep_bmap_sort_records(
     333             :         struct xrep_bmap        *rb)
     334             : {
     335     3340419 :         struct xfs_bmbt_irec    irec;
     336     3340419 :         xfs_fileoff_t           next_off = 0;
     337     3340419 :         xfarray_idx_t           array_cur;
     338     3340419 :         int                     error;
     339             : 
     340     3340419 :         error = xfarray_sort(rb->bmap_records, xrep_bmap_extent_cmp,
     341             :                         XFARRAY_SORT_KILLABLE);
     342     3340419 :         if (error)
     343             :                 return error;
     344             : 
     345    87192663 :         foreach_xfarray_idx(rb->bmap_records, array_cur) {
     346    83852245 :                 struct xfs_bmbt_rec     rec;
     347             : 
     348    83852245 :                 if (xchk_should_terminate(rb->sc, &error))
     349           0 :                         return error;
     350             : 
     351    83852245 :                 error = xfarray_load(rb->bmap_records, array_cur, &rec);
     352    83852245 :                 if (error)
     353           0 :                         return error;
     354             : 
     355    83852245 :                 xfs_bmbt_disk_get_all(&rec, &irec);
     356             : 
     357    83852244 :                 if (irec.br_startoff < next_off)
     358             :                         return -EFSCORRUPTED;
     359             : 
     360    83852244 :                 next_off = irec.br_startoff + irec.br_blockcount;
     361             :         }
     362             : 
     363             :         return 0;
     364             : }
     365             : 
     366             : /* Scan one AG for reverse mappings that we can turn into extent maps. */
     367             : STATIC int
     368    19449900 : xrep_bmap_scan_ag(
     369             :         struct xrep_bmap        *rb,
     370             :         struct xfs_perag        *pag)
     371             : {
     372    19449900 :         struct xfs_scrub        *sc = rb->sc;
     373    19449900 :         int                     error;
     374             : 
     375    19449900 :         error = xrep_ag_init(sc, pag, &sc->sa);
     376    19449506 :         if (error)
     377             :                 return error;
     378             : 
     379    19449456 :         error = xfs_rmap_query_all(sc->sa.rmap_cur, xrep_bmap_walk_rmap, rb);
     380    19449136 :         xchk_ag_free(sc, &sc->sa);
     381    19449136 :         return error;
     382             : }
     383             : 
     384             : #ifdef CONFIG_XFS_RT
     385             : /* Check for any obvious errors or conflicts in the file mapping. */
     386             : STATIC int
     387    15499934 : xrep_bmap_check_rtfork_rmap(
     388             :         struct xfs_scrub                *sc,
     389             :         struct xfs_btree_cur            *cur,
     390             :         const struct xfs_rmap_irec      *rec)
     391             : {
     392    15499934 :         xfs_rtblock_t                   rtbno;
     393             : 
     394             :         /* xattr extents are never stored on realtime devices */
     395    15499934 :         if (rec->rm_flags & XFS_RMAP_ATTR_FORK)
     396             :                 return -EFSCORRUPTED;
     397             : 
     398             :         /* bmbt blocks are never stored on realtime devices */
     399    15499934 :         if (rec->rm_flags & XFS_RMAP_BMBT_BLOCK)
     400             :                 return -EFSCORRUPTED;
     401             : 
     402             :         /* Data extents for non-rt files are never stored on the rt device. */
     403    15499934 :         if (!XFS_IS_REALTIME_INODE(sc->ip))
     404             :                 return -EFSCORRUPTED;
     405             : 
     406             :         /* Check the file offsets and physical extents. */
     407    15499934 :         if (!xfs_verify_fileext(sc->mp, rec->rm_offset, rec->rm_blockcount))
     408             :                 return -EFSCORRUPTED;
     409             : 
     410             :         /* Check that this is within the rtgroup. */
     411    15499773 :         if (!xfs_verify_rgbext(cur->bc_ino.rtg, rec->rm_startblock,
     412    15499773 :                                 rec->rm_blockcount))
     413             :                 return -EFSCORRUPTED;
     414             : 
     415             :         /* Make sure this isn't free space. */
     416    15499773 :         rtbno = xfs_rgbno_to_rtb(sc->mp, cur->bc_ino.rtg->rtg_rgno,
     417             :                         rec->rm_startblock);
     418    15499756 :         return xrep_require_rtext_inuse(sc, rtbno, rec->rm_blockcount, false);
     419             : }
     420             : 
     421             : /* Record realtime extents that belong to this inode's fork. */
     422             : STATIC int
     423 66978338397 : xrep_bmap_walk_rtrmap(
     424             :         struct xfs_btree_cur            *cur,
     425             :         const struct xfs_rmap_irec      *rec,
     426             :         void                            *priv)
     427             : {
     428 66978338397 :         struct xrep_bmap                *rb = priv;
     429 66978338397 :         xfs_rtblock_t                   rtbno;
     430 66978338397 :         int                             error = 0;
     431             : 
     432 66978338397 :         if (xchk_should_terminate(rb->sc, &error))
     433           1 :                 return error;
     434             : 
     435             :         /* Skip extents which are not owned by this inode and fork. */
     436 66909019017 :         if (rec->rm_owner != rb->sc->ip->i_ino)
     437             :                 return 0;
     438             : 
     439    15500012 :         error = xrep_bmap_check_rtfork_rmap(rb->sc, cur, rec);
     440    15501172 :         if (error)
     441             :                 return error;
     442             : 
     443             :         /*
     444             :          * Record all blocks allocated to this file even if the extent isn't
     445             :          * for the fork we're rebuilding so that we can reset di_nblocks later.
     446             :          */
     447    15501172 :         rb->nblocks += rec->rm_blockcount;
     448             : 
     449             :         /* If this rmap isn't for the fork we want, we're done. */
     450    15501172 :         if (rb->whichfork == XFS_DATA_FORK &&
     451    15457623 :             (rec->rm_flags & XFS_RMAP_ATTR_FORK))
     452             :                 return 0;
     453    15501172 :         if (rb->whichfork == XFS_ATTR_FORK &&
     454       43593 :             !(rec->rm_flags & XFS_RMAP_ATTR_FORK))
     455             :                 return 0;
     456             : 
     457    15457579 :         rtbno = xfs_rgbno_to_rtb(cur->bc_mp, cur->bc_ino.rtg->rtg_rgno,
     458    15457579 :                         rec->rm_startblock);
     459    15457580 :         return xrep_bmap_from_rmap(rb, rec->rm_offset, rtbno,
     460    15457580 :                         rec->rm_blockcount,
     461    15457580 :                         rec->rm_flags & XFS_RMAP_UNWRITTEN);
     462             : }
     463             : 
     464             : /* Scan the realtime reverse mappings to build the new extent map. */
     465             : STATIC int
     466     5892653 : xrep_bmap_scan_rtgroup(
     467             :         struct xrep_bmap        *rb,
     468             :         struct xfs_rtgroup      *rtg)
     469             : {
     470     5892653 :         struct xfs_scrub        *sc = rb->sc;
     471     5892653 :         int                     error;
     472             : 
     473     5892653 :         if (xrep_is_rtmeta_ino(sc, rtg, sc->ip->i_ino))
     474             :                 return 0;
     475             : 
     476     5392011 :         error = xrep_rtgroup_init(sc, rtg, &sc->sr,
     477             :                         XFS_RTGLOCK_RMAP |
     478             :                         XFS_RTGLOCK_REFCOUNT |
     479             :                         XFS_RTGLOCK_BITMAP_SHARED);
     480     5392167 :         if (error)
     481             :                 return error;
     482             : 
     483     5392174 :         error = xfs_rmap_query_all(sc->sr.rmap_cur, xrep_bmap_walk_rtrmap, rb);
     484     5393075 :         xchk_rtgroup_btcur_free(&sc->sr);
     485     5393081 :         xchk_rtgroup_free(sc, &sc->sr);
     486     5393081 :         return error;
     487             : }
     488             : #else
     489             : static inline int
     490             : xrep_bmap_scan_rtgroup(struct xrep_bmap *rb, struct xfs_rtgroup *rtg)
     491             : {
     492             :         return -EFSCORRUPTED;
     493             : }
     494             : #endif
     495             : 
     496             : /* Find the delalloc extents from the old incore extent tree. */
     497             : STATIC int
     498     3340419 : xrep_bmap_find_delalloc(
     499             :         struct xrep_bmap        *rb)
     500             : {
     501     3340419 :         struct xfs_bmbt_irec    irec;
     502     3340419 :         struct xfs_iext_cursor  icur;
     503     3340419 :         struct xfs_bmbt_rec     rbe;
     504     3340419 :         struct xfs_inode        *ip = rb->sc->ip;
     505     3340419 :         struct xfs_ifork        *ifp = xfs_ifork_ptr(ip, rb->whichfork);
     506     3340419 :         int                     error = 0;
     507             : 
     508             :         /*
     509             :          * Skip this scan if we don't expect to find delayed allocation
     510             :          * reservations in this fork.
     511             :          */
     512     3340419 :         if (rb->whichfork == XFS_ATTR_FORK || ip->i_delayed_blks == 0)
     513             :                 return 0;
     514             : 
     515      114398 :         for_each_xfs_iext(ifp, &icur, &irec) {
     516      110328 :                 if (!isnullstartblock(irec.br_startblock))
     517      110328 :                         continue;
     518             : 
     519           0 :                 xfs_bmbt_disk_set_all(&rbe, &irec);
     520             : 
     521           0 :                 trace_xrep_bmap_found(ip, rb->whichfork, &irec);
     522             : 
     523           0 :                 if (xchk_should_terminate(rb->sc, &error))
     524           0 :                         return error;
     525             : 
     526           0 :                 error = xfarray_append(rb->bmap_records, &rbe);
     527           0 :                 if (error)
     528           0 :                         return error;
     529             :         }
     530             : 
     531             :         return 0;
     532             : }
     533             : 
     534             : /*
     535             :  * Collect block mappings for this fork of this inode and decide if we have
     536             :  * enough space to rebuild.  Caller is responsible for cleaning up the list if
     537             :  * anything goes wrong.
     538             :  */
     539             : STATIC int
     540     3338428 : xrep_bmap_find_mappings(
     541             :         struct xrep_bmap        *rb)
     542             : {
     543     3338428 :         struct xfs_scrub        *sc = rb->sc;
     544     3338428 :         struct xfs_perag        *pag;
     545     3338428 :         struct xfs_rtgroup      *rtg;
     546     3338428 :         xfs_agnumber_t          agno;
     547     3338428 :         xfs_rgnumber_t          rgno;
     548     3338428 :         int                     error = 0;
     549             : 
     550             :         /* Iterate the rtrmaps for extents. */
     551     9231511 :         for_each_rtgroup(sc->mp, rgno, rtg) {
     552     5893057 :                 error = xrep_bmap_scan_rtgroup(rb, rtg);
     553     5893084 :                 if (error) {
     554           1 :                         xfs_rtgroup_rele(rtg);
     555           1 :                         return error;
     556             :                 }
     557             :         }
     558             : 
     559             :         /* Iterate the rmaps for extents. */
     560    22790005 :         for_each_perag(sc->mp, agno, pag) {
     561    19450420 :                 error = xrep_bmap_scan_ag(rb, pag);
     562    19451503 :                 if (error) {
     563           3 :                         xfs_perag_rele(pag);
     564           3 :                         return error;
     565             :                 }
     566             :         }
     567             : 
     568     3340419 :         return xrep_bmap_find_delalloc(rb);
     569             : }
     570             : 
     571             : /* Retrieve real extent mappings for bulk loading the bmap btree. */
     572             : STATIC int
     573      479493 : xrep_bmap_get_records(
     574             :         struct xfs_btree_cur    *cur,
     575             :         unsigned int            idx,
     576             :         struct xfs_btree_block  *block,
     577             :         unsigned int            nr_wanted,
     578             :         void                    *priv)
     579             : {
     580      479493 :         struct xfs_bmbt_rec     rec;
     581      479493 :         struct xfs_bmbt_irec    *irec = &cur->bc_rec.b;
     582      479493 :         struct xrep_bmap        *rb = priv;
     583      479493 :         union xfs_btree_rec     *block_rec;
     584      479493 :         unsigned int            loaded;
     585      479493 :         int                     error;
     586             : 
     587    82895249 :         for (loaded = 0; loaded < nr_wanted; loaded++, idx++) {
     588    82415756 :                 do {
     589    82415756 :                         error = xfarray_load(rb->bmap_records, rb->array_cur++,
     590             :                                         &rec);
     591    82415752 :                         if (error)
     592           0 :                                 return error;
     593             : 
     594    82415752 :                         xfs_bmbt_disk_get_all(&rec, irec);
     595    82415753 :                 } while (isnullstartblock(irec->br_startblock));
     596             : 
     597    82415753 :                 block_rec = xfs_btree_rec_addr(cur, idx, block);
     598    82415753 :                 cur->bc_ops->init_rec_from_cur(cur, block_rec);
     599             :         }
     600             : 
     601      479493 :         return loaded;
     602             : }
     603             : 
     604             : /* Feed one of the new btree blocks to the bulk loader. */
     605             : STATIC int
     606      486445 : xrep_bmap_claim_block(
     607             :         struct xfs_btree_cur    *cur,
     608             :         union xfs_btree_ptr     *ptr,
     609             :         void                    *priv)
     610             : {
     611      486445 :         struct xrep_bmap        *rb = priv;
     612      486445 :         int                     error;
     613             : 
     614      486445 :         error = xrep_newbt_relog_autoreap(&rb->new_bmapbt);
     615      486445 :         if (error)
     616             :                 return error;
     617             : 
     618      486445 :         return xrep_newbt_claim_block(cur, &rb->new_bmapbt, ptr);
     619             : }
     620             : 
     621             : /* Figure out how much space we need to create the incore btree root block. */
     622             : STATIC size_t
     623       99041 : xrep_bmap_iroot_size(
     624             :         struct xfs_btree_cur    *cur,
     625             :         unsigned int            level,
     626             :         unsigned int            nr_this_level,
     627             :         void                    *priv)
     628             : {
     629       99041 :         ASSERT(level > 0);
     630             : 
     631       99041 :         return xfs_bmap_broot_space_calc(cur->bc_mp, level, nr_this_level);
     632             : }
     633             : 
     634             : /* Update the inode counters. */
     635             : STATIC int
     636     3340402 : xrep_bmap_reset_counters(
     637             :         struct xrep_bmap        *rb)
     638             : {
     639     3340402 :         struct xfs_scrub        *sc = rb->sc;
     640     3340402 :         struct xbtree_ifakeroot *ifake = &rb->new_bmapbt.ifake;
     641     3340402 :         int64_t                 delta;
     642             : 
     643     3340402 :         if (rb->shared_extents)
     644       90393 :                 sc->ip->i_diflags2 |= XFS_DIFLAG2_REFLINK;
     645             : 
     646             :         /*
     647             :          * Update the inode block counts to reflect the extents we found in the
     648             :          * rmapbt.
     649             :          */
     650     3340402 :         delta = ifake->if_blocks - rb->old_bmbt_block_count;
     651     3340402 :         sc->ip->i_nblocks = rb->nblocks + delta;
     652     3340402 :         xfs_trans_log_inode(sc->tp, sc->ip, XFS_ILOG_CORE);
     653             : 
     654             :         /*
     655             :          * Adjust the quota counts by the difference in size between the old
     656             :          * and new bmbt.
     657             :          */
     658     3340404 :         xfs_trans_mod_dquot_byino(sc->tp, sc->ip, XFS_TRANS_DQ_BCOUNT, delta);
     659     3340403 :         return 0;
     660             : }
     661             : 
     662             : /*
     663             :  * Create a new iext tree and load it with block mappings.  If the inode is
     664             :  * in extents format, that's all we need to do to commit the new mappings.
     665             :  * If it is in btree format, this takes care of preloading the incore tree.
     666             :  */
     667             : STATIC int
     668     3340404 : xrep_bmap_extents_load(
     669             :         struct xrep_bmap        *rb)
     670             : {
     671     3340404 :         struct xfs_iext_cursor  icur;
     672     3340404 :         struct xfs_bmbt_irec    irec;
     673     3340404 :         struct xfs_ifork        *ifp = rb->new_bmapbt.ifake.if_fork;
     674     3340404 :         xfarray_idx_t           array_cur;
     675     3340404 :         int                     error;
     676             : 
     677     3340404 :         ASSERT(ifp->if_bytes == 0);
     678             : 
     679             :         /* Add all the mappings (incl. delalloc) to the incore extent tree. */
     680     3340404 :         xfs_iext_first(ifp, &icur);
     681    90372317 :         foreach_xfarray_idx(rb->bmap_records, array_cur) {
     682    83691491 :                 struct xfs_bmbt_rec     rec;
     683             : 
     684    83691491 :                 error = xfarray_load(rb->bmap_records, array_cur, &rec);
     685    83691529 :                 if (error)
     686           0 :                         return error;
     687             : 
     688    83691529 :                 xfs_bmbt_disk_get_all(&rec, &irec);
     689             : 
     690    83691538 :                 xfs_iext_insert_raw(ifp, &icur, &irec);
     691    83691509 :                 if (!isnullstartblock(irec.br_startblock))
     692    83691509 :                         ifp->if_nextents++;
     693             : 
     694    83691509 :                 xfs_iext_next(ifp, &icur);
     695             :         }
     696             : 
     697     3340405 :         return xrep_ino_ensure_extent_count(rb->sc, rb->whichfork,
     698             :                         ifp->if_nextents);
     699             : }
     700             : 
     701             : /*
     702             :  * Reserve new btree blocks, bulk load the bmap records into the ondisk btree,
     703             :  * and load the incore extent tree.
     704             :  */
     705             : STATIC int
     706       99055 : xrep_bmap_btree_load(
     707             :         struct xrep_bmap        *rb,
     708             :         struct xfs_btree_cur    *bmap_cur)
     709             : {
     710       99055 :         struct xfs_scrub        *sc = rb->sc;
     711       99055 :         int                     error;
     712             : 
     713             :         /* Compute how many blocks we'll need. */
     714       99055 :         error = xfs_btree_bload_compute_geometry(bmap_cur,
     715             :                         &rb->new_bmapbt.bload, rb->real_mappings);
     716       99055 :         if (error)
     717             :                 return error;
     718             : 
     719             :         /* Last chance to abort before we start committing fixes. */
     720       99055 :         if (xchk_should_terminate(sc, &error))
     721           0 :                 return error;
     722             : 
     723             :         /*
     724             :          * Guess how many blocks we're going to need to rebuild an entire bmap
     725             :          * from the number of extents we found, and pump up our transaction to
     726             :          * have sufficient block reservation.  We're allowed to exceed file
     727             :          * quota to repair inconsistent metadata.
     728             :          */
     729      198110 :         error = xfs_trans_reserve_more_inode(sc->tp, sc->ip,
     730       99055 :                         rb->new_bmapbt.bload.nr_blocks, 0, true);
     731       99055 :         if (error)
     732             :                 return error;
     733             : 
     734             :         /* Reserve the space we'll need for the new btree. */
     735       99041 :         error = xrep_newbt_alloc_blocks(&rb->new_bmapbt,
     736             :                         rb->new_bmapbt.bload.nr_blocks);
     737       99041 :         if (error)
     738             :                 return error;
     739             : 
     740             :         /* Add all observed bmap records. */
     741       99041 :         rb->array_cur = XFARRAY_CURSOR_INIT;
     742       99041 :         error = xfs_btree_bload(bmap_cur, &rb->new_bmapbt.bload, rb);
     743       99041 :         if (error)
     744             :                 return error;
     745             : 
     746             :         /*
     747             :          * Load the new bmap records into the new incore extent tree to
     748             :          * preserve delalloc reservations for regular files.  The directory
     749             :          * code loads the extent tree during xfs_dir_open and assumes
     750             :          * thereafter that it remains loaded, so we must not violate that
     751             :          * assumption.
     752             :          */
     753       99041 :         return xrep_bmap_extents_load(rb);
     754             : }
     755             : 
     756             : /*
     757             :  * Use the collected bmap information to stage a new bmap fork.  If this is
     758             :  * successful we'll return with the new fork information logged to the repair
     759             :  * transaction but not yet committed.  The caller must ensure that the inode
     760             :  * is joined to the transaction; the inode will be joined to a clean
     761             :  * transaction when the function returns.
     762             :  */
     763             : STATIC int
     764     3340419 : xrep_bmap_build_new_fork(
     765             :         struct xrep_bmap        *rb)
     766             : {
     767     3340419 :         struct xfs_owner_info   oinfo;
     768     3340419 :         struct xfs_scrub        *sc = rb->sc;
     769     3340419 :         struct xfs_btree_cur    *bmap_cur;
     770     3340419 :         struct xbtree_ifakeroot *ifake = &rb->new_bmapbt.ifake;
     771     3340419 :         int                     error;
     772             : 
     773     3340419 :         error = xrep_bmap_sort_records(rb);
     774     3340419 :         if (error)
     775             :                 return error;
     776             : 
     777             :         /*
     778             :          * Prepare to construct the new fork by initializing the new btree
     779             :          * structure and creating a fake ifork in the ifakeroot structure.
     780             :          */
     781     3340419 :         xfs_rmap_ino_bmbt_owner(&oinfo, sc->ip->i_ino, rb->whichfork);
     782     3340419 :         error = xrep_newbt_init_inode(&rb->new_bmapbt, sc, rb->whichfork,
     783             :                         &oinfo);
     784     3340419 :         if (error)
     785             :                 return error;
     786             : 
     787     3340419 :         rb->new_bmapbt.bload.get_records = xrep_bmap_get_records;
     788     3340419 :         rb->new_bmapbt.bload.claim_block = xrep_bmap_claim_block;
     789     3340419 :         rb->new_bmapbt.bload.iroot_size = xrep_bmap_iroot_size;
     790     3340419 :         bmap_cur = xfs_bmbt_stage_cursor(sc->mp, sc->ip, ifake);
     791             : 
     792             :         /*
     793             :          * Figure out the size and format of the new fork, then fill it with
     794             :          * all the bmap records we've found.  Join the inode to the transaction
     795             :          * so that we can roll the transaction while holding the inode locked.
     796             :          */
     797     3340419 :         if (rb->real_mappings <= XFS_IFORK_MAXEXT(sc->ip, rb->whichfork)) {
     798     3241364 :                 ifake->if_fork->if_format = XFS_DINODE_FMT_EXTENTS;
     799     3241364 :                 error = xrep_bmap_extents_load(rb);
     800             :         } else {
     801       99055 :                 ifake->if_fork->if_format = XFS_DINODE_FMT_BTREE;
     802       99055 :                 error = xrep_bmap_btree_load(rb, bmap_cur);
     803             :         }
     804     3340419 :         if (error)
     805          14 :                 goto err_cur;
     806             : 
     807             :         /*
     808             :          * Install the new fork in the inode.  After this point the old mapping
     809             :          * data are no longer accessible and the new tree is live.  We delete
     810             :          * the cursor immediately after committing the staged root because the
     811             :          * staged fork might be in extents format.
     812             :          */
     813     3340405 :         xfs_bmbt_commit_staged_btree(bmap_cur, sc->tp, rb->whichfork);
     814     3340405 :         xfs_btree_del_cursor(bmap_cur, 0);
     815             : 
     816             :         /* Reset the inode counters now that we've changed the fork. */
     817     3340402 :         error = xrep_bmap_reset_counters(rb);
     818     3340402 :         if (error)
     819           0 :                 goto err_newbt;
     820             : 
     821             :         /* Dispose of any unused blocks and the accounting information. */
     822     3340402 :         error = xrep_newbt_commit(&rb->new_bmapbt);
     823     3340404 :         if (error)
     824             :                 return error;
     825             : 
     826     3340404 :         return xrep_roll_trans(sc);
     827             : 
     828             : err_cur:
     829          14 :         if (bmap_cur)
     830          14 :                 xfs_btree_del_cursor(bmap_cur, error);
     831           0 : err_newbt:
     832          14 :         xrep_newbt_cancel(&rb->new_bmapbt);
     833          14 :         return error;
     834             : }
     835             : 
     836             : /*
     837             :  * Now that we've logged the new inode btree, invalidate all of the old blocks
     838             :  * and free them, if there were any.
     839             :  */
     840             : STATIC int
     841     3340395 : xrep_bmap_remove_old_tree(
     842             :         struct xrep_bmap        *rb)
     843             : {
     844     3340395 :         struct xfs_scrub        *sc = rb->sc;
     845     3340395 :         struct xfs_owner_info   oinfo;
     846             : 
     847             :         /* Free the old bmbt blocks if they're not in use. */
     848     3340395 :         xfs_rmap_ino_bmbt_owner(&oinfo, sc->ip->i_ino, rb->whichfork);
     849     3340395 :         return xrep_reap_fsblocks(sc, &rb->old_bmbt_blocks, &oinfo);
     850             : }
     851             : 
     852             : /* Check for garbage inputs.  Returns -ECANCELED if there's nothing to do. */
     853             : STATIC int
     854     8037102 : xrep_bmap_check_inputs(
     855             :         struct xfs_scrub        *sc,
     856             :         int                     whichfork)
     857             : {
     858     8037102 :         struct xfs_ifork        *ifp = xfs_ifork_ptr(sc->ip, whichfork);
     859             : 
     860     8036583 :         ASSERT(whichfork == XFS_DATA_FORK || whichfork == XFS_ATTR_FORK);
     861             : 
     862     8036583 :         if (!xfs_has_rmapbt(sc->mp))
     863             :                 return -EOPNOTSUPP;
     864             : 
     865             :         /* No fork means nothing to rebuild. */
     866     7756993 :         if (!ifp)
     867             :                 return -ECANCELED;
     868             : 
     869             :         /*
     870             :          * We only know how to repair extent mappings, which is to say that we
     871             :          * only support extents and btree fork format.  Repairs to a local
     872             :          * format fork require a higher level repair function, so we do not
     873             :          * have any work to do here.
     874             :          */
     875     7756993 :         switch (ifp->if_format) {
     876             :         case XFS_DINODE_FMT_DEV:
     877             :         case XFS_DINODE_FMT_LOCAL:
     878             :         case XFS_DINODE_FMT_UUID:
     879             :         case XFS_DINODE_FMT_RMAP:
     880             :         case XFS_DINODE_FMT_REFCOUNT:
     881             :                 return -ECANCELED;
     882             :         case XFS_DINODE_FMT_EXTENTS:
     883             :         case XFS_DINODE_FMT_BTREE:
     884     3338933 :                 break;
     885           0 :         default:
     886           0 :                 return -EFSCORRUPTED;
     887             :         }
     888             : 
     889     3338933 :         if (whichfork == XFS_ATTR_FORK)
     890             :                 return 0;
     891             : 
     892             :         /* Only files, symlinks, and directories get to have data forks. */
     893     3282039 :         switch (VFS_I(sc->ip)->i_mode & S_IFMT) {
     894             :         case S_IFREG:
     895             :         case S_IFDIR:
     896             :         case S_IFLNK:
     897             :                 /* ok */
     898     3282039 :                 break;
     899             :         default:
     900             :                 return -EINVAL;
     901             :         }
     902             : 
     903     3282039 :         return 0;
     904             : }
     905             : 
     906             : /* Repair an inode fork. */
     907             : int
     908     8037255 : xrep_bmap(
     909             :         struct xfs_scrub        *sc,
     910             :         int                     whichfork,
     911             :         bool                    allow_unwritten)
     912             : {
     913     8037255 :         struct xrep_bmap        *rb;
     914     8037255 :         char                    *descr;
     915     8037255 :         unsigned int            max_bmbt_recs;
     916     8037255 :         bool                    large_extcount;
     917     8037255 :         int                     error = 0;
     918             : 
     919     8037255 :         error = xrep_bmap_check_inputs(sc, whichfork);
     920     8036703 :         if (error == -ECANCELED)
     921             :                 return 0;
     922     3618681 :         if (error)
     923             :                 return error;
     924             : 
     925     3339609 :         rb = kzalloc(sizeof(struct xrep_bmap), XCHK_GFP_FLAGS);
     926     3339914 :         if (!rb)
     927             :                 return -ENOMEM;
     928     3339914 :         rb->sc = sc;
     929     3339914 :         rb->whichfork = whichfork;
     930     3339914 :         rb->allow_unwritten = allow_unwritten;
     931             : 
     932             :         /*
     933             :          * No need to waste time scanning for shared extents if the inode is
     934             :          * already marked.
     935             :          */
     936     3339914 :         if (whichfork == XFS_DATA_FORK && xfs_is_reflink_inode(sc->ip))
     937       90394 :                 rb->shared_extents = true;
     938             : 
     939             :         /* Set up enough storage to handle the max records for this fork. */
     940     3339914 :         large_extcount = xfs_has_large_extent_counts(sc->mp);
     941     3339914 :         max_bmbt_recs = xfs_iext_max_nextents(large_extcount, whichfork);
     942     3396594 :         descr = xchk_xfile_ino_descr(sc, "%s fork mapping records",
     943             :                         whichfork == XFS_DATA_FORK ? "data" : "attr");
     944     3339219 :         error = xfarray_create(descr, max_bmbt_recs,
     945             :                         sizeof(struct xfs_bmbt_rec), &rb->bmap_records);
     946     3338124 :         kfree(descr);
     947     3337800 :         if (error)
     948           0 :                 goto out_rb;
     949             : 
     950             :         /* Collect all reverse mappings for this fork's extents. */
     951     3337800 :         xfsb_bitmap_init(&rb->old_bmbt_blocks);
     952     3338074 :         error = xrep_bmap_find_mappings(rb);
     953     3340423 :         if (error)
     954           4 :                 goto out_bitmap;
     955             : 
     956     3340419 :         xfs_trans_ijoin(sc->tp, sc->ip, 0);
     957             : 
     958             :         /* Rebuild the bmap information. */
     959     3340419 :         error = xrep_bmap_build_new_fork(rb);
     960     3340412 :         if (error)
     961          14 :                 goto out_bitmap;
     962             : 
     963             :         /* Kill the old tree. */
     964     3340398 :         error = xrep_bmap_remove_old_tree(rb);
     965             : 
     966     3340401 : out_bitmap:
     967     3340401 :         xfsb_bitmap_destroy(&rb->old_bmbt_blocks);
     968     3340399 :         xfarray_destroy(rb->bmap_records);
     969     3340415 : out_rb:
     970     3340415 :         kfree(rb);
     971     3340415 :         return error;
     972             : }
     973             : 
     974             : /* Repair an inode's data fork. */
     975             : int
     976     4000596 : xrep_bmap_data(
     977             :         struct xfs_scrub        *sc)
     978             : {
     979     4000596 :         return xrep_bmap(sc, XFS_DATA_FORK, true);
     980             : }
     981             : 
     982             : /* Repair an inode's attr fork. */
     983             : int
     984     3777612 : xrep_bmap_attr(
     985             :         struct xfs_scrub        *sc)
     986             : {
     987     3777612 :         return xrep_bmap(sc, XFS_ATTR_FORK, false);
     988             : }

Generated by: LCOV version 1.14