LCOV - code coverage report
Current view: top level - fs/xfs/libxfs - xfs_refcount.c (source / functions) Hit Total Coverage
Test: fstests of 6.5.0-rc4-xfsx @ Mon Jul 31 20:08:34 PDT 2023 Lines: 759 956 79.4 %
Date: 2023-07-31 20:08:34 Functions: 47 48 97.9 %

          Line data    Source code
       1             : // SPDX-License-Identifier: GPL-2.0+
       2             : /*
       3             :  * Copyright (C) 2016 Oracle.  All Rights Reserved.
       4             :  * Author: Darrick J. Wong <darrick.wong@oracle.com>
       5             :  */
       6             : #include "xfs.h"
       7             : #include "xfs_fs.h"
       8             : #include "xfs_shared.h"
       9             : #include "xfs_format.h"
      10             : #include "xfs_log_format.h"
      11             : #include "xfs_trans_resv.h"
      12             : #include "xfs_mount.h"
      13             : #include "xfs_defer.h"
      14             : #include "xfs_btree.h"
      15             : #include "xfs_bmap.h"
      16             : #include "xfs_refcount_btree.h"
      17             : #include "xfs_alloc.h"
      18             : #include "xfs_errortag.h"
      19             : #include "xfs_error.h"
      20             : #include "xfs_trace.h"
      21             : #include "xfs_trans.h"
      22             : #include "xfs_bit.h"
      23             : #include "xfs_refcount.h"
      24             : #include "xfs_rmap.h"
      25             : #include "xfs_ag.h"
      26             : #include "xfs_health.h"
      27             : #include "xfs_rtgroup.h"
      28             : #include "xfs_rtalloc.h"
      29             : #include "xfs_rtrefcount_btree.h"
      30             : 
      31             : struct kmem_cache       *xfs_refcount_intent_cache;
      32             : 
      33             : /* Allowable refcount adjustment amounts. */
      34             : enum xfs_refc_adjust_op {
      35             :         XFS_REFCOUNT_ADJUST_INCREASE    = 1,
      36             :         XFS_REFCOUNT_ADJUST_DECREASE    = -1,
      37             :         XFS_REFCOUNT_ADJUST_COW_ALLOC   = 0,
      38             :         XFS_REFCOUNT_ADJUST_COW_FREE    = -1,
      39             : };
      40             : 
      41             : STATIC int __xfs_refcount_cow_alloc(struct xfs_btree_cur *rcur,
      42             :                 xfs_agblock_t agbno, xfs_extlen_t aglen);
      43             : STATIC int __xfs_refcount_cow_free(struct xfs_btree_cur *rcur,
      44             :                 xfs_agblock_t agbno, xfs_extlen_t aglen);
      45             : 
      46             : /* Return the maximum startblock number of the refcountbt. */
      47             : static inline xfs_agblock_t
      48             : xrefc_max_startblock(
      49             :         struct xfs_btree_cur    *cur)
      50             : {
      51    27715245 :         if (cur->bc_btnum == XFS_BTNUM_RTREFC)
      52     8571772 :                 return cur->bc_mp->m_sb.sb_rgblocks;
      53    19143473 :         return cur->bc_mp->m_sb.sb_agblocks;
      54             : }
      55             : 
      56             : /*
      57             :  * Look up the first record less than or equal to [bno, len] in the btree
      58             :  * given by cur.
      59             :  */
      60             : int
      61  3845981807 : xfs_refcount_lookup_le(
      62             :         struct xfs_btree_cur    *cur,
      63             :         enum xfs_refc_domain    domain,
      64             :         xfs_agblock_t           bno,
      65             :         int                     *stat)
      66             : {
      67  3934859906 :         trace_xfs_refcount_lookup(cur,
      68             :                         xfs_refcount_encode_startblock(bno, domain),
      69             :                         XFS_LOOKUP_LE);
      70  3844203593 :         cur->bc_rec.rc.rc_startblock = bno;
      71  3844203593 :         cur->bc_rec.rc.rc_blockcount = 0;
      72  3844203593 :         cur->bc_rec.rc.rc_domain = domain;
      73  3844203593 :         return xfs_btree_lookup(cur, XFS_LOOKUP_LE, stat);
      74             : }
      75             : 
      76             : /*
      77             :  * Look up the first record greater than or equal to [bno, len] in the btree
      78             :  * given by cur.
      79             :  */
      80             : int
      81   667794530 : xfs_refcount_lookup_ge(
      82             :         struct xfs_btree_cur    *cur,
      83             :         enum xfs_refc_domain    domain,
      84             :         xfs_agblock_t           bno,
      85             :         int                     *stat)
      86             : {
      87   739939302 :         trace_xfs_refcount_lookup(cur,
      88             :                         xfs_refcount_encode_startblock(bno, domain),
      89             :                         XFS_LOOKUP_GE);
      90   667794641 :         cur->bc_rec.rc.rc_startblock = bno;
      91   667794641 :         cur->bc_rec.rc.rc_blockcount = 0;
      92   667794641 :         cur->bc_rec.rc.rc_domain = domain;
      93   667794641 :         return xfs_btree_lookup(cur, XFS_LOOKUP_GE, stat);
      94             : }
      95             : 
      96             : /*
      97             :  * Look up the first record equal to [bno, len] in the btree
      98             :  * given by cur.
      99             :  */
     100             : int
     101           0 : xfs_refcount_lookup_eq(
     102             :         struct xfs_btree_cur    *cur,
     103             :         enum xfs_refc_domain    domain,
     104             :         xfs_agblock_t           bno,
     105             :         int                     *stat)
     106             : {
     107           0 :         trace_xfs_refcount_lookup(cur,
     108             :                         xfs_refcount_encode_startblock(bno, domain),
     109             :                         XFS_LOOKUP_LE);
     110           0 :         cur->bc_rec.rc.rc_startblock = bno;
     111           0 :         cur->bc_rec.rc.rc_blockcount = 0;
     112           0 :         cur->bc_rec.rc.rc_domain = domain;
     113           0 :         return xfs_btree_lookup(cur, XFS_LOOKUP_EQ, stat);
     114             : }
     115             : 
     116             : /* Convert on-disk record to in-core format. */
     117             : void
     118  5266479924 : xfs_refcount_btrec_to_irec(
     119             :         const union xfs_btree_rec       *rec,
     120             :         struct xfs_refcount_irec        *irec)
     121             : {
     122  5266479924 :         uint32_t                        start;
     123             : 
     124  5266479924 :         start = be32_to_cpu(rec->refc.rc_startblock);
     125  5266479924 :         if (start & XFS_REFC_COWFLAG) {
     126   251578958 :                 start &= ~XFS_REFC_COWFLAG;
     127   251578958 :                 irec->rc_domain = XFS_REFC_DOMAIN_COW;
     128             :         } else {
     129  5014900966 :                 irec->rc_domain = XFS_REFC_DOMAIN_SHARED;
     130             :         }
     131             : 
     132  5266479924 :         irec->rc_startblock = start;
     133  5266479924 :         irec->rc_blockcount = be32_to_cpu(rec->refc.rc_blockcount);
     134  5266479924 :         irec->rc_refcount = be32_to_cpu(rec->refc.rc_refcount);
     135  5266479924 : }
     136             : 
     137             : inline xfs_failaddr_t
     138  3129360573 : xfs_refcount_check_perag_irec(
     139             :         struct xfs_perag                *pag,
     140             :         const struct xfs_refcount_irec  *irec)
     141             : {
     142  3129360573 :         if (irec->rc_blockcount == 0 || irec->rc_blockcount > XFS_REFC_LEN_MAX)
     143           0 :                 return __this_address;
     144             : 
     145  3129360573 :         if (!xfs_refcount_check_domain(irec))
     146           0 :                 return __this_address;
     147             : 
     148             :         /* check for valid extent range, including overflow */
     149  3129360573 :         if (!xfs_verify_agbext(pag, irec->rc_startblock, irec->rc_blockcount))
     150          10 :                 return __this_address;
     151             : 
     152  3129360563 :         if (irec->rc_refcount == 0 || irec->rc_refcount > XFS_REFC_REFCOUNT_MAX)
     153           0 :                 return __this_address;
     154             : 
     155             :         return NULL;
     156             : }
     157             : 
     158             : inline xfs_failaddr_t
     159  2150235325 : xfs_refcount_check_rtgroup_irec(
     160             :         struct xfs_rtgroup              *rtg,
     161             :         const struct xfs_refcount_irec  *irec)
     162             : {
     163  2150235325 :         if (irec->rc_blockcount == 0 || irec->rc_blockcount > XFS_REFC_LEN_MAX)
     164           0 :                 return __this_address;
     165             : 
     166  2150235325 :         if (!xfs_refcount_check_domain(irec))
     167           0 :                 return __this_address;
     168             : 
     169             :         /* check for valid extent range, including overflow */
     170  2150235325 :         if (!xfs_verify_rgbext(rtg, irec->rc_startblock, irec->rc_blockcount))
     171           0 :                 return __this_address;
     172             : 
     173  2150235325 :         if (irec->rc_refcount == 0 || irec->rc_refcount > XFS_REFC_REFCOUNT_MAX)
     174           0 :                 return __this_address;
     175             : 
     176             :         return NULL;
     177             : }
     178             : 
     179             : /* Simple checks for refcount records. */
     180             : xfs_failaddr_t
     181  5266521087 : xfs_refcount_check_irec(
     182             :         struct xfs_btree_cur            *cur,
     183             :         const struct xfs_refcount_irec  *irec)
     184             : {
     185  5266521087 :         if (cur->bc_btnum == XFS_BTNUM_RTREFC)
     186  2144478694 :                 return xfs_refcount_check_rtgroup_irec(cur->bc_ino.rtg, irec);
     187  3122042393 :         return xfs_refcount_check_perag_irec(cur->bc_ag.pag, irec);
     188             : }
     189             : 
     190             : static inline int
     191          10 : xfs_refcount_complain_bad_rec(
     192             :         struct xfs_btree_cur            *cur,
     193             :         xfs_failaddr_t                  fa,
     194             :         const struct xfs_refcount_irec  *irec)
     195             : {
     196          10 :         struct xfs_mount                *mp = cur->bc_mp;
     197             : 
     198          10 :         if (cur->bc_btnum == XFS_BTNUM_RTREFC) {
     199           0 :                 xfs_warn(mp,
     200             :  "RT Refcount BTree record corruption in rtgroup %u detected at %pS!",
     201             :                                 cur->bc_ino.rtg->rtg_rgno, fa);
     202             :         } else {
     203          10 :                 xfs_warn(mp,
     204             :  "Refcount BTree record corruption in AG %d detected at %pS!",
     205             :                                 cur->bc_ag.pag->pag_agno, fa);
     206             :         }
     207          10 :         xfs_warn(mp,
     208             :                 "Start block 0x%x, block count 0x%x, references 0x%x",
     209             :                 irec->rc_startblock, irec->rc_blockcount, irec->rc_refcount);
     210          10 :         xfs_btree_mark_sick(cur);
     211          10 :         return -EFSCORRUPTED;
     212             : }
     213             : 
     214             : /*
     215             :  * Get the data from the pointed-to record.
     216             :  */
     217             : int
     218  5166512020 : xfs_refcount_get_rec(
     219             :         struct xfs_btree_cur            *cur,
     220             :         struct xfs_refcount_irec        *irec,
     221             :         int                             *stat)
     222             : {
     223  5166512020 :         union xfs_btree_rec             *rec;
     224  5166512020 :         xfs_failaddr_t                  fa;
     225  5166512020 :         int                             error;
     226             : 
     227  5166512020 :         error = xfs_btree_get_rec(cur, &rec, stat);
     228  5162685367 :         if (error || !*stat)
     229             :                 return error;
     230             : 
     231  5145916506 :         xfs_refcount_btrec_to_irec(rec, irec);
     232  5146756821 :         fa = xfs_refcount_check_irec(cur, irec);
     233  5146434750 :         if (fa)
     234          10 :                 return xfs_refcount_complain_bad_rec(cur, fa, irec);
     235             : 
     236  5146434740 :         trace_xfs_refcount_get(cur, irec);
     237  5146434740 :         return 0;
     238             : }
     239             : 
     240             : /*
     241             :  * Update the record referred to by cur to the value given
     242             :  * by [bno, len, refcount].
     243             :  * This either works (return 0) or gets an EFSCORRUPTED error.
     244             :  */
     245             : STATIC int
     246   259987250 : xfs_refcount_update(
     247             :         struct xfs_btree_cur            *cur,
     248             :         struct xfs_refcount_irec        *irec)
     249             : {
     250   259987250 :         union xfs_btree_rec     rec;
     251   259987250 :         uint32_t                start;
     252   259987250 :         int                     error;
     253             : 
     254   259987250 :         trace_xfs_refcount_update(cur, irec);
     255             : 
     256   259986920 :         start = xfs_refcount_encode_startblock(irec->rc_startblock,
     257             :                         irec->rc_domain);
     258   259986920 :         rec.refc.rc_startblock = cpu_to_be32(start);
     259   259986920 :         rec.refc.rc_blockcount = cpu_to_be32(irec->rc_blockcount);
     260   259986920 :         rec.refc.rc_refcount = cpu_to_be32(irec->rc_refcount);
     261             : 
     262   259986920 :         error = xfs_btree_update(cur, &rec);
     263   259987289 :         if (error)
     264           0 :                 trace_xfs_refcount_update_error(cur, error, _RET_IP_);
     265   259987289 :         return error;
     266             : }
     267             : 
     268             : /*
     269             :  * Insert the record referred to by cur to the value given
     270             :  * by [bno, len, refcount].
     271             :  * This either works (return 0) or gets an EFSCORRUPTED error.
     272             :  */
     273             : int
     274    99937231 : xfs_refcount_insert(
     275             :         struct xfs_btree_cur            *cur,
     276             :         struct xfs_refcount_irec        *irec,
     277             :         int                             *i)
     278             : {
     279    99937231 :         int                             error;
     280             : 
     281    99937231 :         trace_xfs_refcount_insert(cur, irec);
     282             : 
     283    99936948 :         cur->bc_rec.rc.rc_startblock = irec->rc_startblock;
     284    99936948 :         cur->bc_rec.rc.rc_blockcount = irec->rc_blockcount;
     285    99936948 :         cur->bc_rec.rc.rc_refcount = irec->rc_refcount;
     286    99936948 :         cur->bc_rec.rc.rc_domain = irec->rc_domain;
     287             : 
     288    99936948 :         error = xfs_btree_insert(cur, i);
     289    99937124 :         if (error)
     290          70 :                 goto out_error;
     291    99937054 :         if (XFS_IS_CORRUPT(cur->bc_mp, *i != 1)) {
     292           0 :                 xfs_btree_mark_sick(cur);
     293           0 :                 error = -EFSCORRUPTED;
     294           0 :                 goto out_error;
     295             :         }
     296             : 
     297    99937124 : out_error:
     298    99937124 :         if (error)
     299          70 :                 trace_xfs_refcount_insert_error(cur, error, _RET_IP_);
     300    99937124 :         return error;
     301             : }
     302             : 
     303             : /*
     304             :  * Remove the record referred to by cur, then set the pointer to the spot
     305             :  * where the record could be re-inserted, in case we want to increment or
     306             :  * decrement the cursor.
     307             :  * This either works (return 0) or gets an EFSCORRUPTED error.
     308             :  */
     309             : STATIC int
     310    89774871 : xfs_refcount_delete(
     311             :         struct xfs_btree_cur    *cur,
     312             :         int                     *i)
     313             : {
     314    89774871 :         struct xfs_refcount_irec        irec;
     315    89774871 :         int                     found_rec;
     316    89774871 :         int                     error;
     317             : 
     318    89774871 :         error = xfs_refcount_get_rec(cur, &irec, &found_rec);
     319    89776782 :         if (error)
     320           0 :                 goto out_error;
     321    89776782 :         if (XFS_IS_CORRUPT(cur->bc_mp, found_rec != 1)) {
     322           0 :                 xfs_btree_mark_sick(cur);
     323           0 :                 error = -EFSCORRUPTED;
     324           0 :                 goto out_error;
     325             :         }
     326    89776782 :         trace_xfs_refcount_delete(cur, &irec);
     327    89776261 :         error = xfs_btree_delete(cur, i);
     328    89774191 :         if (XFS_IS_CORRUPT(cur->bc_mp, *i != 1)) {
     329           0 :                 xfs_btree_mark_sick(cur);
     330           0 :                 error = -EFSCORRUPTED;
     331           0 :                 goto out_error;
     332             :         }
     333    89774191 :         if (error)
     334           0 :                 goto out_error;
     335    89774191 :         error = xfs_refcount_lookup_ge(cur, irec.rc_domain, irec.rc_startblock,
     336             :                         &found_rec);
     337    89776691 : out_error:
     338    89776691 :         if (error)
     339           0 :                 trace_xfs_refcount_delete_error(cur, error, _RET_IP_);
     340    89776691 :         return error;
     341             : }
     342             : 
     343             : /*
     344             :  * Adjusting the Reference Count
     345             :  *
     346             :  * As stated elsewhere, the reference count btree (refcbt) stores
     347             :  * >1 reference counts for extents of physical blocks.  In this
     348             :  * operation, we're either raising or lowering the reference count of
     349             :  * some subrange stored in the tree:
     350             :  *
     351             :  *      <------ adjustment range ------>
     352             :  * ----+   +---+-----+ +--+--------+---------
     353             :  *  2  |   | 3 |  4  | |17|   55   |   10
     354             :  * ----+   +---+-----+ +--+--------+---------
     355             :  * X axis is physical blocks number;
     356             :  * reference counts are the numbers inside the rectangles
     357             :  *
     358             :  * The first thing we need to do is to ensure that there are no
     359             :  * refcount extents crossing either boundary of the range to be
     360             :  * adjusted.  For any extent that does cross a boundary, split it into
     361             :  * two extents so that we can increment the refcount of one of the
     362             :  * pieces later:
     363             :  *
     364             :  *      <------ adjustment range ------>
     365             :  * ----+   +---+-----+ +--+--------+----+----
     366             :  *  2  |   | 3 |  2  | |17|   55   | 10 | 10
     367             :  * ----+   +---+-----+ +--+--------+----+----
     368             :  *
     369             :  * For this next step, let's assume that all the physical blocks in
     370             :  * the adjustment range are mapped to a file and are therefore in use
     371             :  * at least once.  Therefore, we can infer that any gap in the
     372             :  * refcount tree within the adjustment range represents a physical
     373             :  * extent with refcount == 1:
     374             :  *
     375             :  *      <------ adjustment range ------>
     376             :  * ----+---+---+-----+-+--+--------+----+----
     377             :  *  2  |"1"| 3 |  2  |1|17|   55   | 10 | 10
     378             :  * ----+---+---+-----+-+--+--------+----+----
     379             :  *      ^
     380             :  *
     381             :  * For each extent that falls within the interval range, figure out
     382             :  * which extent is to the left or the right of that extent.  Now we
     383             :  * have a left, current, and right extent.  If the new reference count
     384             :  * of the center extent enables us to merge left, center, and right
     385             :  * into one record covering all three, do so.  If the center extent is
     386             :  * at the left end of the range, abuts the left extent, and its new
     387             :  * reference count matches the left extent's record, then merge them.
     388             :  * If the center extent is at the right end of the range, abuts the
     389             :  * right extent, and the reference counts match, merge those.  In the
     390             :  * example, we can left merge (assuming an increment operation):
     391             :  *
     392             :  *      <------ adjustment range ------>
     393             :  * --------+---+-----+-+--+--------+----+----
     394             :  *    2    | 3 |  2  |1|17|   55   | 10 | 10
     395             :  * --------+---+-----+-+--+--------+----+----
     396             :  *          ^
     397             :  *
     398             :  * For all other extents within the range, adjust the reference count
     399             :  * or delete it if the refcount falls below 2.  If we were
     400             :  * incrementing, the end result looks like this:
     401             :  *
     402             :  *      <------ adjustment range ------>
     403             :  * --------+---+-----+-+--+--------+----+----
     404             :  *    2    | 4 |  3  |2|18|   56   | 11 | 10
     405             :  * --------+---+-----+-+--+--------+----+----
     406             :  *
     407             :  * The result of a decrement operation looks as such:
     408             :  *
     409             :  *      <------ adjustment range ------>
     410             :  * ----+   +---+       +--+--------+----+----
     411             :  *  2  |   | 2 |       |16|   54   |  9 | 10
     412             :  * ----+   +---+       +--+--------+----+----
     413             :  *      DDDD    111111DD
     414             :  *
     415             :  * The blocks marked "D" are freed; the blocks marked "1" are only
     416             :  * referenced once and therefore the record is removed from the
     417             :  * refcount btree.
     418             :  */
     419             : 
     420             : /* Next block after this extent. */
     421             : static inline xfs_agblock_t
     422             : xfs_refc_next(
     423             :         struct xfs_refcount_irec        *rc)
     424             : {
     425   696996806 :         return rc->rc_startblock + rc->rc_blockcount;
     426             : }
     427             : 
     428             : /*
     429             :  * Split a refcount extent that crosses agbno.
     430             :  */
     431             : STATIC int
     432   589406151 : xfs_refcount_split_extent(
     433             :         struct xfs_btree_cur            *cur,
     434             :         enum xfs_refc_domain            domain,
     435             :         xfs_agblock_t                   agbno,
     436             :         bool                            *shape_changed)
     437             : {
     438   589406151 :         struct xfs_refcount_irec        rcext, tmp;
     439   589406151 :         int                             found_rec;
     440   589406151 :         int                             error;
     441             : 
     442   589406151 :         *shape_changed = false;
     443   589406151 :         error = xfs_refcount_lookup_le(cur, domain, agbno, &found_rec);
     444   589420148 :         if (error)
     445         174 :                 goto out_error;
     446   589419974 :         if (!found_rec)
     447             :                 return 0;
     448             : 
     449   568012690 :         error = xfs_refcount_get_rec(cur, &rcext, &found_rec);
     450   568003824 :         if (error)
     451           0 :                 goto out_error;
     452   568003824 :         if (XFS_IS_CORRUPT(cur->bc_mp, found_rec != 1)) {
     453           0 :                 xfs_btree_mark_sick(cur);
     454           0 :                 error = -EFSCORRUPTED;
     455           0 :                 goto out_error;
     456             :         }
     457   568003824 :         if (rcext.rc_domain != domain)
     458             :                 return 0;
     459   566757381 :         if (rcext.rc_startblock == agbno || xfs_refc_next(&rcext) <= agbno)
     460             :                 return 0;
     461             : 
     462    64453308 :         *shape_changed = true;
     463    64453308 :         trace_xfs_refcount_split_extent(cur, &rcext, agbno);
     464             : 
     465             :         /* Establish the right extent. */
     466    64453209 :         tmp = rcext;
     467    64453209 :         tmp.rc_startblock = agbno;
     468    64453209 :         tmp.rc_blockcount -= (agbno - rcext.rc_startblock);
     469    64453209 :         error = xfs_refcount_update(cur, &tmp);
     470    64453236 :         if (error)
     471           0 :                 goto out_error;
     472             : 
     473             :         /* Insert the left extent. */
     474    64453236 :         tmp = rcext;
     475    64453236 :         tmp.rc_blockcount = agbno - rcext.rc_startblock;
     476    64453236 :         error = xfs_refcount_insert(cur, &tmp, &found_rec);
     477    64453140 :         if (error)
     478          31 :                 goto out_error;
     479    64453109 :         if (XFS_IS_CORRUPT(cur->bc_mp, found_rec != 1)) {
     480           0 :                 xfs_btree_mark_sick(cur);
     481           0 :                 error = -EFSCORRUPTED;
     482           0 :                 goto out_error;
     483             :         }
     484             :         return error;
     485             : 
     486         205 : out_error:
     487         205 :         trace_xfs_refcount_split_extent_error(cur, error, _RET_IP_);
     488         205 :         return error;
     489             : }
     490             : 
     491             : /*
     492             :  * Merge the left, center, and right extents.
     493             :  */
     494             : STATIC int
     495     2525919 : xfs_refcount_merge_center_extents(
     496             :         struct xfs_btree_cur            *cur,
     497             :         struct xfs_refcount_irec        *left,
     498             :         struct xfs_refcount_irec        *center,
     499             :         struct xfs_refcount_irec        *right,
     500             :         unsigned long long              extlen,
     501             :         xfs_extlen_t                    *aglen)
     502             : {
     503     2525919 :         int                             error;
     504     2525919 :         int                             found_rec;
     505             : 
     506     2525919 :         trace_xfs_refcount_merge_center_extents(cur, left, center, right);
     507             : 
     508     2525919 :         ASSERT(left->rc_domain == center->rc_domain);
     509     2525919 :         ASSERT(right->rc_domain == center->rc_domain);
     510             : 
     511             :         /*
     512             :          * Make sure the center and right extents are not in the btree.
     513             :          * If the center extent was synthesized, the first delete call
     514             :          * removes the right extent and we skip the second deletion.
     515             :          * If center and right were in the btree, then the first delete
     516             :          * call removes the center and the second one removes the right
     517             :          * extent.
     518             :          */
     519     2525919 :         error = xfs_refcount_lookup_ge(cur, center->rc_domain,
     520             :                         center->rc_startblock, &found_rec);
     521     2525919 :         if (error)
     522           0 :                 goto out_error;
     523     2525919 :         if (XFS_IS_CORRUPT(cur->bc_mp, found_rec != 1)) {
     524           0 :                 xfs_btree_mark_sick(cur);
     525           0 :                 error = -EFSCORRUPTED;
     526           0 :                 goto out_error;
     527             :         }
     528             : 
     529     2525919 :         error = xfs_refcount_delete(cur, &found_rec);
     530     2525918 :         if (error)
     531           0 :                 goto out_error;
     532     2525918 :         if (XFS_IS_CORRUPT(cur->bc_mp, found_rec != 1)) {
     533           0 :                 xfs_btree_mark_sick(cur);
     534           0 :                 error = -EFSCORRUPTED;
     535           0 :                 goto out_error;
     536             :         }
     537             : 
     538     2525918 :         if (center->rc_refcount > 1) {
     539      660864 :                 error = xfs_refcount_delete(cur, &found_rec);
     540      660864 :                 if (error)
     541           0 :                         goto out_error;
     542      660864 :                 if (XFS_IS_CORRUPT(cur->bc_mp, found_rec != 1)) {
     543           0 :                         xfs_btree_mark_sick(cur);
     544           0 :                         error = -EFSCORRUPTED;
     545           0 :                         goto out_error;
     546             :                 }
     547             :         }
     548             : 
     549             :         /* Enlarge the left extent. */
     550     2525918 :         error = xfs_refcount_lookup_le(cur, left->rc_domain,
     551             :                         left->rc_startblock, &found_rec);
     552     2525918 :         if (error)
     553           0 :                 goto out_error;
     554     2525918 :         if (XFS_IS_CORRUPT(cur->bc_mp, found_rec != 1)) {
     555           0 :                 xfs_btree_mark_sick(cur);
     556           0 :                 error = -EFSCORRUPTED;
     557           0 :                 goto out_error;
     558             :         }
     559             : 
     560     2525918 :         left->rc_blockcount = extlen;
     561     2525918 :         error = xfs_refcount_update(cur, left);
     562     2525919 :         if (error)
     563           0 :                 goto out_error;
     564             : 
     565     2525919 :         *aglen = 0;
     566     2525919 :         return error;
     567             : 
     568           0 : out_error:
     569           0 :         trace_xfs_refcount_merge_center_extents_error(cur, error, _RET_IP_);
     570           0 :         return error;
     571             : }
     572             : 
     573             : /*
     574             :  * Merge with the left extent.
     575             :  */
     576             : STATIC int
     577    16865594 : xfs_refcount_merge_left_extent(
     578             :         struct xfs_btree_cur            *cur,
     579             :         struct xfs_refcount_irec        *left,
     580             :         struct xfs_refcount_irec        *cleft,
     581             :         xfs_agblock_t                   *agbno,
     582             :         xfs_extlen_t                    *aglen)
     583             : {
     584    16865594 :         int                             error;
     585    16865594 :         int                             found_rec;
     586             : 
     587    16865594 :         trace_xfs_refcount_merge_left_extent(cur, left, cleft);
     588             : 
     589    16865592 :         ASSERT(left->rc_domain == cleft->rc_domain);
     590             : 
     591             :         /* If the extent at agbno (cleft) wasn't synthesized, remove it. */
     592    16865592 :         if (cleft->rc_refcount > 1) {
     593    10491408 :                 error = xfs_refcount_lookup_le(cur, cleft->rc_domain,
     594             :                                 cleft->rc_startblock, &found_rec);
     595    10491408 :                 if (error)
     596           0 :                         goto out_error;
     597    10491408 :                 if (XFS_IS_CORRUPT(cur->bc_mp, found_rec != 1)) {
     598           0 :                         xfs_btree_mark_sick(cur);
     599           0 :                         error = -EFSCORRUPTED;
     600           0 :                         goto out_error;
     601             :                 }
     602             : 
     603    10491408 :                 error = xfs_refcount_delete(cur, &found_rec);
     604    10491408 :                 if (error)
     605           0 :                         goto out_error;
     606    10491408 :                 if (XFS_IS_CORRUPT(cur->bc_mp, found_rec != 1)) {
     607           0 :                         xfs_btree_mark_sick(cur);
     608           0 :                         error = -EFSCORRUPTED;
     609           0 :                         goto out_error;
     610             :                 }
     611             :         }
     612             : 
     613             :         /* Enlarge the left extent. */
     614    16865592 :         error = xfs_refcount_lookup_le(cur, left->rc_domain,
     615             :                         left->rc_startblock, &found_rec);
     616    16865629 :         if (error)
     617           0 :                 goto out_error;
     618    16865629 :         if (XFS_IS_CORRUPT(cur->bc_mp, found_rec != 1)) {
     619           0 :                 xfs_btree_mark_sick(cur);
     620           0 :                 error = -EFSCORRUPTED;
     621           0 :                 goto out_error;
     622             :         }
     623             : 
     624    16865629 :         left->rc_blockcount += cleft->rc_blockcount;
     625    16865629 :         error = xfs_refcount_update(cur, left);
     626    16865620 :         if (error)
     627           0 :                 goto out_error;
     628             : 
     629    16865620 :         *agbno += cleft->rc_blockcount;
     630    16865620 :         *aglen -= cleft->rc_blockcount;
     631    16865620 :         return error;
     632             : 
     633           0 : out_error:
     634           0 :         trace_xfs_refcount_merge_left_extent_error(cur, error, _RET_IP_);
     635           0 :         return error;
     636             : }
     637             : 
     638             : /*
     639             :  * Merge with the right extent.
     640             :  */
     641             : STATIC int
     642     4584383 : xfs_refcount_merge_right_extent(
     643             :         struct xfs_btree_cur            *cur,
     644             :         struct xfs_refcount_irec        *right,
     645             :         struct xfs_refcount_irec        *cright,
     646             :         xfs_extlen_t                    *aglen)
     647             : {
     648     4584383 :         int                             error;
     649     4584383 :         int                             found_rec;
     650             : 
     651     4584383 :         trace_xfs_refcount_merge_right_extent(cur, cright, right);
     652             : 
     653     4584383 :         ASSERT(right->rc_domain == cright->rc_domain);
     654             : 
     655             :         /*
     656             :          * If the extent ending at agbno+aglen (cright) wasn't synthesized,
     657             :          * remove it.
     658             :          */
     659     4584383 :         if (cright->rc_refcount > 1) {
     660     2364599 :                 error = xfs_refcount_lookup_le(cur, cright->rc_domain,
     661             :                                 cright->rc_startblock, &found_rec);
     662     2364599 :                 if (error)
     663           0 :                         goto out_error;
     664     2364599 :                 if (XFS_IS_CORRUPT(cur->bc_mp, found_rec != 1)) {
     665           0 :                         xfs_btree_mark_sick(cur);
     666           0 :                         error = -EFSCORRUPTED;
     667           0 :                         goto out_error;
     668             :                 }
     669             : 
     670     2364599 :                 error = xfs_refcount_delete(cur, &found_rec);
     671     2364599 :                 if (error)
     672           0 :                         goto out_error;
     673     2364599 :                 if (XFS_IS_CORRUPT(cur->bc_mp, found_rec != 1)) {
     674           0 :                         xfs_btree_mark_sick(cur);
     675           0 :                         error = -EFSCORRUPTED;
     676           0 :                         goto out_error;
     677             :                 }
     678             :         }
     679             : 
     680             :         /* Enlarge the right extent. */
     681     4584383 :         error = xfs_refcount_lookup_le(cur, right->rc_domain,
     682             :                         right->rc_startblock, &found_rec);
     683     4584384 :         if (error)
     684           0 :                 goto out_error;
     685     4584384 :         if (XFS_IS_CORRUPT(cur->bc_mp, found_rec != 1)) {
     686           0 :                 xfs_btree_mark_sick(cur);
     687           0 :                 error = -EFSCORRUPTED;
     688           0 :                 goto out_error;
     689             :         }
     690             : 
     691     4584384 :         right->rc_startblock -= cright->rc_blockcount;
     692     4584384 :         right->rc_blockcount += cright->rc_blockcount;
     693     4584384 :         error = xfs_refcount_update(cur, right);
     694     4584384 :         if (error)
     695           0 :                 goto out_error;
     696             : 
     697     4584384 :         *aglen -= cright->rc_blockcount;
     698     4584384 :         return error;
     699             : 
     700           0 : out_error:
     701           0 :         trace_xfs_refcount_merge_right_extent_error(cur, error, _RET_IP_);
     702           0 :         return error;
     703             : }
     704             : 
     705             : /*
     706             :  * Find the left extent and the one after it (cleft).  This function assumes
     707             :  * that we've already split any extent crossing agbno.
     708             :  */
     709             : STATIC int
     710   294709111 : xfs_refcount_find_left_extents(
     711             :         struct xfs_btree_cur            *cur,
     712             :         struct xfs_refcount_irec        *left,
     713             :         struct xfs_refcount_irec        *cleft,
     714             :         enum xfs_refc_domain            domain,
     715             :         xfs_agblock_t                   agbno,
     716             :         xfs_extlen_t                    aglen)
     717             : {
     718   294709111 :         struct xfs_refcount_irec        tmp;
     719   294709111 :         int                             error;
     720   294709111 :         int                             found_rec;
     721             : 
     722   294709111 :         left->rc_startblock = cleft->rc_startblock = NULLAGBLOCK;
     723   294709111 :         error = xfs_refcount_lookup_le(cur, domain, agbno - 1, &found_rec);
     724   294711420 :         if (error)
     725           0 :                 goto out_error;
     726   294711420 :         if (!found_rec)
     727             :                 return 0;
     728             : 
     729   250611120 :         error = xfs_refcount_get_rec(cur, &tmp, &found_rec);
     730   250611131 :         if (error)
     731           0 :                 goto out_error;
     732   250611131 :         if (XFS_IS_CORRUPT(cur->bc_mp, found_rec != 1)) {
     733           0 :                 xfs_btree_mark_sick(cur);
     734           0 :                 error = -EFSCORRUPTED;
     735           0 :                 goto out_error;
     736             :         }
     737             : 
     738   250611131 :         if (tmp.rc_domain != domain)
     739             :                 return 0;
     740   247989654 :         if (xfs_refc_next(&tmp) != agbno)
     741             :                 return 0;
     742             :         /* We have a left extent; retrieve (or invent) the next right one */
     743    68139542 :         *left = tmp;
     744             : 
     745    68139542 :         error = xfs_btree_increment(cur, 0, &found_rec);
     746    68139491 :         if (error)
     747           0 :                 goto out_error;
     748    68139491 :         if (found_rec) {
     749    66352235 :                 error = xfs_refcount_get_rec(cur, &tmp, &found_rec);
     750    66352292 :                 if (error)
     751           0 :                         goto out_error;
     752    66352292 :                 if (XFS_IS_CORRUPT(cur->bc_mp, found_rec != 1)) {
     753           0 :                         xfs_btree_mark_sick(cur);
     754           0 :                         error = -EFSCORRUPTED;
     755           0 :                         goto out_error;
     756             :                 }
     757             : 
     758    66352292 :                 if (tmp.rc_domain != domain)
     759      271240 :                         goto not_found;
     760             : 
     761             :                 /* if tmp starts at the end of our range, just use that */
     762    66081052 :                 if (tmp.rc_startblock == agbno)
     763    59299193 :                         *cleft = tmp;
     764             :                 else {
     765             :                         /*
     766             :                          * There's a gap in the refcntbt at the start of the
     767             :                          * range we're interested in (refcount == 1) so
     768             :                          * synthesize the implied extent and pass it back.
     769             :                          * We assume here that the agbno/aglen range was
     770             :                          * passed in from a data fork extent mapping and
     771             :                          * therefore is allocated to exactly one owner.
     772             :                          */
     773     6781859 :                         cleft->rc_startblock = agbno;
     774     6781859 :                         cleft->rc_blockcount = min(aglen,
     775             :                                         tmp.rc_startblock - agbno);
     776     6781859 :                         cleft->rc_refcount = 1;
     777     6781859 :                         cleft->rc_domain = domain;
     778             :                 }
     779             :         } else {
     780     1787256 : not_found:
     781             :                 /*
     782             :                  * No extents, so pretend that there's one covering the whole
     783             :                  * range.
     784             :                  */
     785     2058496 :                 cleft->rc_startblock = agbno;
     786     2058496 :                 cleft->rc_blockcount = aglen;
     787     2058496 :                 cleft->rc_refcount = 1;
     788     2058496 :                 cleft->rc_domain = domain;
     789             :         }
     790    68139548 :         trace_xfs_refcount_find_left_extent(cur, left, cleft, agbno);
     791    68139548 :         return error;
     792             : 
     793           0 : out_error:
     794           0 :         trace_xfs_refcount_find_left_extent_error(cur, error, _RET_IP_);
     795           0 :         return error;
     796             : }
     797             : 
     798             : /*
     799             :  * Find the right extent and the one before it (cright).  This function
     800             :  * assumes that we've already split any extents crossing agbno + aglen.
     801             :  */
     802             : STATIC int
     803   294709911 : xfs_refcount_find_right_extents(
     804             :         struct xfs_btree_cur            *cur,
     805             :         struct xfs_refcount_irec        *right,
     806             :         struct xfs_refcount_irec        *cright,
     807             :         enum xfs_refc_domain            domain,
     808             :         xfs_agblock_t                   agbno,
     809             :         xfs_extlen_t                    aglen)
     810             : {
     811   294709911 :         struct xfs_refcount_irec        tmp;
     812   294709911 :         int                             error;
     813   294709911 :         int                             found_rec;
     814             : 
     815   294709911 :         right->rc_startblock = cright->rc_startblock = NULLAGBLOCK;
     816   294709911 :         error = xfs_refcount_lookup_ge(cur, domain, agbno + aglen, &found_rec);
     817   294711098 :         if (error)
     818           0 :                 goto out_error;
     819   294711098 :         if (!found_rec)
     820             :                 return 0;
     821             : 
     822   241838087 :         error = xfs_refcount_get_rec(cur, &tmp, &found_rec);
     823   241838468 :         if (error)
     824          10 :                 goto out_error;
     825   241838458 :         if (XFS_IS_CORRUPT(cur->bc_mp, found_rec != 1)) {
     826           0 :                 xfs_btree_mark_sick(cur);
     827           0 :                 error = -EFSCORRUPTED;
     828           0 :                 goto out_error;
     829             :         }
     830             : 
     831   241838458 :         if (tmp.rc_domain != domain)
     832             :                 return 0;
     833   229693882 :         if (tmp.rc_startblock != agbno + aglen)
     834             :                 return 0;
     835             :         /* We have a right extent; retrieve (or invent) the next left one */
     836    71578481 :         *right = tmp;
     837             : 
     838    71578481 :         error = xfs_btree_decrement(cur, 0, &found_rec);
     839    71578374 :         if (error)
     840           0 :                 goto out_error;
     841    71578374 :         if (found_rec) {
     842    71460986 :                 error = xfs_refcount_get_rec(cur, &tmp, &found_rec);
     843    71460929 :                 if (error)
     844           0 :                         goto out_error;
     845    71460929 :                 if (XFS_IS_CORRUPT(cur->bc_mp, found_rec != 1)) {
     846           0 :                         xfs_btree_mark_sick(cur);
     847           0 :                         error = -EFSCORRUPTED;
     848           0 :                         goto out_error;
     849             :                 }
     850             : 
     851    71460929 :                 if (tmp.rc_domain != domain)
     852        8319 :                         goto not_found;
     853             : 
     854             :                 /* if tmp ends at the end of our range, just use that */
     855    71452610 :                 if (xfs_refc_next(&tmp) == agbno + aglen)
     856    66989720 :                         *cright = tmp;
     857             :                 else {
     858             :                         /*
     859             :                          * There's a gap in the refcntbt at the end of the
     860             :                          * range we're interested in (refcount == 1) so
     861             :                          * create the implied extent and pass it back.
     862             :                          * We assume here that the agbno/aglen range was
     863             :                          * passed in from a data fork extent mapping and
     864             :                          * therefore is allocated to exactly one owner.
     865             :                          */
     866     4462890 :                         cright->rc_startblock = max(agbno, xfs_refc_next(&tmp));
     867     4462890 :                         cright->rc_blockcount = right->rc_startblock -
     868             :                                         cright->rc_startblock;
     869     4462890 :                         cright->rc_refcount = 1;
     870     4462890 :                         cright->rc_domain = domain;
     871             :                 }
     872             :         } else {
     873      117388 : not_found:
     874             :                 /*
     875             :                  * No extents, so pretend that there's one covering the whole
     876             :                  * range.
     877             :                  */
     878      125707 :                 cright->rc_startblock = agbno;
     879      125707 :                 cright->rc_blockcount = aglen;
     880      125707 :                 cright->rc_refcount = 1;
     881      125707 :                 cright->rc_domain = domain;
     882             :         }
     883    71578317 :         trace_xfs_refcount_find_right_extent(cur, cright, right,
     884             :                         agbno + aglen);
     885    71578317 :         return error;
     886             : 
     887          10 : out_error:
     888          10 :         trace_xfs_refcount_find_right_extent_error(cur, error, _RET_IP_);
     889          10 :         return error;
     890             : }
     891             : 
     892             : /* Is this extent valid? */
     893             : static inline bool
     894             : xfs_refc_valid(
     895             :         const struct xfs_refcount_irec  *rc)
     896             : {
     897  1080185179 :         return rc->rc_startblock != NULLAGBLOCK;
     898             : }
     899             : 
     900             : static inline xfs_nlink_t
     901             : xfs_refc_merge_refcount(
     902             :         const struct xfs_refcount_irec  *irec,
     903             :         enum xfs_refc_adjust_op         adjust)
     904             : {
     905             :         /* Once a record hits XFS_REFC_REFCOUNT_MAX, it is pinned forever */
     906   157432367 :         if (irec->rc_refcount == XFS_REFC_REFCOUNT_MAX)
     907             :                 return XFS_REFC_REFCOUNT_MAX;
     908   157432317 :         return irec->rc_refcount + adjust;
     909             : }
     910             : 
     911             : static inline bool
     912    95462690 : xfs_refc_want_merge_center(
     913             :         const struct xfs_refcount_irec  *left,
     914             :         const struct xfs_refcount_irec  *cleft,
     915             :         const struct xfs_refcount_irec  *cright,
     916             :         const struct xfs_refcount_irec  *right,
     917             :         bool                            cleft_is_cright,
     918             :         enum xfs_refc_adjust_op         adjust,
     919             :         unsigned long long              *ulenp)
     920             : {
     921    95462690 :         unsigned long long              ulen = left->rc_blockcount;
     922    95462690 :         xfs_nlink_t                     new_refcount;
     923             : 
     924             :         /*
     925             :          * To merge with a center record, both shoulder records must be
     926             :          * adjacent to the record we want to adjust.  This is only true if
     927             :          * find_left and find_right made all four records valid.
     928             :          */
     929    95462690 :         if (!xfs_refc_valid(left)  || !xfs_refc_valid(right) ||
     930    44254933 :             !xfs_refc_valid(cleft) || !xfs_refc_valid(cright))
     931             :                 return false;
     932             : 
     933             :         /* There must only be one record for the entire range. */
     934    44254933 :         if (!cleft_is_cright)
     935             :                 return false;
     936             : 
     937             :         /* The shoulder record refcounts must match the new refcount. */
     938    29640084 :         new_refcount = xfs_refc_merge_refcount(cleft, adjust);
     939    29640084 :         if (left->rc_refcount != new_refcount)
     940             :                 return false;
     941     9399289 :         if (right->rc_refcount != new_refcount)
     942             :                 return false;
     943             : 
     944             :         /*
     945             :          * The new record cannot exceed the max length.  ulen is a ULL as the
     946             :          * individual record block counts can be up to (u32 - 1) in length
     947             :          * hence we need to catch u32 addition overflows here.
     948             :          */
     949     2525919 :         ulen += cleft->rc_blockcount + right->rc_blockcount;
     950     2525919 :         if (ulen >= XFS_REFC_LEN_MAX)
     951             :                 return false;
     952             : 
     953     2525919 :         *ulenp = ulen;
     954     2525919 :         return true;
     955             : }
     956             : 
     957             : static inline bool
     958    92936657 : xfs_refc_want_merge_left(
     959             :         const struct xfs_refcount_irec  *left,
     960             :         const struct xfs_refcount_irec  *cleft,
     961             :         enum xfs_refc_adjust_op         adjust)
     962             : {
     963    92936657 :         unsigned long long              ulen = left->rc_blockcount;
     964    92936657 :         xfs_nlink_t                     new_refcount;
     965             : 
     966             :         /*
     967             :          * For a left merge, the left shoulder record must be adjacent to the
     968             :          * start of the range.  If this is true, find_left made left and cleft
     969             :          * contain valid contents.
     970             :          */
     971    92936657 :         if (!xfs_refc_valid(left) || !xfs_refc_valid(cleft))
     972             :                 return false;
     973             : 
     974             :         /* Left shoulder record refcount must match the new refcount. */
     975    65613442 :         new_refcount = xfs_refc_merge_refcount(cleft, adjust);
     976    65613442 :         if (left->rc_refcount != new_refcount)
     977             :                 return false;
     978             : 
     979             :         /*
     980             :          * The new record cannot exceed the max length.  ulen is a ULL as the
     981             :          * individual record block counts can be up to (u32 - 1) in length
     982             :          * hence we need to catch u32 addition overflows here.
     983             :          */
     984    16865606 :         ulen += cleft->rc_blockcount;
     985    16865606 :         if (ulen >= XFS_REFC_LEN_MAX)
     986           0 :                 return false;
     987             : 
     988             :         return true;
     989             : }
     990             : 
     991             : static inline bool
     992    86063311 : xfs_refc_want_merge_right(
     993             :         const struct xfs_refcount_irec  *cright,
     994             :         const struct xfs_refcount_irec  *right,
     995             :         enum xfs_refc_adjust_op         adjust)
     996             : {
     997    86063311 :         unsigned long long              ulen = right->rc_blockcount;
     998    86063311 :         xfs_nlink_t                     new_refcount;
     999             : 
    1000             :         /*
    1001             :          * For a right merge, the right shoulder record must be adjacent to the
    1002             :          * end of the range.  If this is true, find_right made cright and right
    1003             :          * contain valid contents.
    1004             :          */
    1005    86063311 :         if (!xfs_refc_valid(right) || !xfs_refc_valid(cright))
    1006             :                 return false;
    1007             : 
    1008             :         /* Right shoulder record refcount must match the new refcount. */
    1009    62178841 :         new_refcount = xfs_refc_merge_refcount(cright, adjust);
    1010    62178841 :         if (right->rc_refcount != new_refcount)
    1011             :                 return false;
    1012             : 
    1013             :         /*
    1014             :          * The new record cannot exceed the max length.  ulen is a ULL as the
    1015             :          * individual record block counts can be up to (u32 - 1) in length
    1016             :          * hence we need to catch u32 addition overflows here.
    1017             :          */
    1018     4584384 :         ulen += cright->rc_blockcount;
    1019     4584384 :         if (ulen >= XFS_REFC_LEN_MAX)
    1020           0 :                 return false;
    1021             : 
    1022             :         return true;
    1023             : }
    1024             : 
    1025             : /*
    1026             :  * Try to merge with any extents on the boundaries of the adjustment range.
    1027             :  */
    1028             : STATIC int
    1029   294709076 : xfs_refcount_merge_extents(
    1030             :         struct xfs_btree_cur    *cur,
    1031             :         enum xfs_refc_domain    domain,
    1032             :         xfs_agblock_t           *agbno,
    1033             :         xfs_extlen_t            *aglen,
    1034             :         enum xfs_refc_adjust_op adjust,
    1035             :         bool                    *shape_changed)
    1036             : {
    1037   294709076 :         struct xfs_refcount_irec        left = {0}, cleft = {0};
    1038   294709076 :         struct xfs_refcount_irec        cright = {0}, right = {0};
    1039   294709076 :         int                             error;
    1040   294709076 :         unsigned long long              ulen;
    1041   294709076 :         bool                            cequal;
    1042             : 
    1043   294709076 :         *shape_changed = false;
    1044             :         /*
    1045             :          * Find the extent just below agbno [left], just above agbno [cleft],
    1046             :          * just below (agbno + aglen) [cright], and just above (agbno + aglen)
    1047             :          * [right].
    1048             :          */
    1049   294709076 :         error = xfs_refcount_find_left_extents(cur, &left, &cleft, domain,
    1050             :                         *agbno, *aglen);
    1051   294710181 :         if (error)
    1052             :                 return error;
    1053   294710323 :         error = xfs_refcount_find_right_extents(cur, &right, &cright, domain,
    1054             :                         *agbno, *aglen);
    1055   294710178 :         if (error)
    1056             :                 return error;
    1057             : 
    1058             :         /* No left or right extent to merge; exit. */
    1059   294710168 :         if (!xfs_refc_valid(&left) && !xfs_refc_valid(&right))
    1060             :                 return 0;
    1061             : 
    1062    95462629 :         cequal = (cleft.rc_startblock == cright.rc_startblock) &&
    1063    29640088 :                  (cleft.rc_blockcount == cright.rc_blockcount);
    1064             : 
    1065             :         /* Try to merge left, cleft, and right.  cleft must == cright. */
    1066    95462629 :         if (xfs_refc_want_merge_center(&left, &cleft, &cright, &right, cequal,
    1067             :                                 adjust, &ulen)) {
    1068     2525919 :                 *shape_changed = true;
    1069     2525919 :                 return xfs_refcount_merge_center_extents(cur, &left, &cleft,
    1070             :                                 &right, ulen, aglen);
    1071             :         }
    1072             : 
    1073             :         /* Try to merge left and cleft. */
    1074    92936520 :         if (xfs_refc_want_merge_left(&left, &cleft, adjust)) {
    1075    16865605 :                 *shape_changed = true;
    1076    16865605 :                 error = xfs_refcount_merge_left_extent(cur, &left, &cleft,
    1077             :                                 agbno, aglen);
    1078    16865611 :                 if (error)
    1079             :                         return error;
    1080             : 
    1081             :                 /*
    1082             :                  * If we just merged left + cleft and cleft == cright,
    1083             :                  * we no longer have a cright to merge with right.  We're done.
    1084             :                  */
    1085    16865611 :                 if (cequal)
    1086             :                         return 0;
    1087             :         }
    1088             : 
    1089             :         /* Try to merge cright and right. */
    1090    86063156 :         if (xfs_refc_want_merge_right(&cright, &right, adjust)) {
    1091     4584383 :                 *shape_changed = true;
    1092     4584383 :                 return xfs_refcount_merge_right_extent(cur, &right, &cright,
    1093             :                                 aglen);
    1094             :         }
    1095             : 
    1096             :         return 0;
    1097             : }
    1098             : 
    1099             : static inline struct xbtree_refc *
    1100             : xrefc_btree_state(
    1101             :         struct xfs_btree_cur    *cur)
    1102             : {
    1103  1963818610 :         if (cur->bc_btnum == XFS_BTNUM_RTREFC)
    1104   756785217 :                 return &cur->bc_ino.refc;
    1105  1207033393 :         return &cur->bc_ag.refc;
    1106             : }
    1107             : 
    1108             : /*
    1109             :  * XXX: This is a pretty hand-wavy estimate.  The penalty for guessing
    1110             :  * true incorrectly is a shutdown FS; the penalty for guessing false
    1111             :  * incorrectly is more transaction rolls than might be necessary.
    1112             :  * Be conservative here.
    1113             :  */
    1114             : static bool
    1115   332501374 : xfs_refcount_still_have_space(
    1116             :         struct xfs_btree_cur            *cur)
    1117             : {
    1118   332501374 :         unsigned long                   overhead;
    1119             : 
    1120             :         /*
    1121             :          * Worst case estimate: full splits of the free space and rmap btrees
    1122             :          * to handle each of the shape changes to the refcount btree.
    1123             :          */
    1124   665002748 :         overhead = xfs_allocfree_block_count(cur->bc_mp,
    1125             :                                 xrefc_btree_state(cur)->shape_changes);
    1126   332498985 :         overhead += cur->bc_maxlevels;
    1127   332498985 :         overhead *= cur->bc_mp->m_sb.sb_blocksize;
    1128             : 
    1129             :         /*
    1130             :          * Only allow 2 refcount extent updates per transaction if the
    1131             :          * refcount continue update "error" has been injected.
    1132             :          */
    1133   711506650 :         if (xrefc_btree_state(cur)->nr_ops > 2 &&
    1134    46508690 :             XFS_TEST_ERROR(false, cur->bc_mp,
    1135             :                         XFS_ERRTAG_REFCOUNT_CONTINUE_UPDATE))
    1136             :                 return false;
    1137             : 
    1138   664997110 :         if (xrefc_btree_state(cur)->nr_ops == 0)
    1139             :                 return true;
    1140    87287731 :         else if (overhead > cur->bc_tp->t_log_res)
    1141             :                 return false;
    1142    87287731 :         return  cur->bc_tp->t_log_res - overhead >
    1143    87287731 :                 xrefc_btree_state(cur)->nr_ops * XFS_REFCOUNT_ITEM_OVERHEAD;
    1144             : }
    1145             : 
    1146             : /* Schedule an extent free. */
    1147             : static int
    1148    75969070 : xrefc_free_extent(
    1149             :         struct xfs_btree_cur            *cur,
    1150             :         struct xfs_refcount_irec        *rec)
    1151             : {
    1152    75969070 :         xfs_fsblock_t                   fsbno;
    1153    75969070 :         unsigned int                    flags = 0;
    1154             : 
    1155    75969070 :         if (cur->bc_btnum == XFS_BTNUM_RTREFC) {
    1156    28847902 :                 flags |= XFS_FREE_EXTENT_REALTIME;
    1157    28847902 :                 fsbno = xfs_rgbno_to_rtb(cur->bc_mp, cur->bc_ino.rtg->rtg_rgno,
    1158             :                                 rec->rc_startblock);
    1159             :         } else {
    1160    47121168 :                 fsbno = XFS_AGB_TO_FSB(cur->bc_mp, cur->bc_ag.pag->pag_agno,
    1161             :                                 rec->rc_startblock);
    1162             :         }
    1163             : 
    1164    75969068 :         return xfs_free_extent_later(cur->bc_tp, fsbno, rec->rc_blockcount,
    1165             :                         NULL, XFS_AG_RESV_NONE, flags);
    1166             : }
    1167             : 
    1168             : /*
    1169             :  * Adjust the refcounts of middle extents.  At this point we should have
    1170             :  * split extents that crossed the adjustment range; merged with adjacent
    1171             :  * extents; and updated agbno/aglen to reflect the merges.  Therefore,
    1172             :  * all we have to do is update the extents inside [agbno, agbno + aglen].
    1173             :  */
    1174             : STATIC int
    1175   268444441 : xfs_refcount_adjust_extents(
    1176             :         struct xfs_btree_cur    *cur,
    1177             :         xfs_agblock_t           *agbno,
    1178             :         xfs_extlen_t            *aglen,
    1179             :         enum xfs_refc_adjust_op adj)
    1180             : {
    1181   268444441 :         struct xfs_refcount_irec        ext, tmp;
    1182   268444441 :         int                             error;
    1183   268444441 :         int                             found_rec, found_tmp;
    1184             : 
    1185             :         /* Merging did all the work already. */
    1186   268444441 :         if (*aglen == 0)
    1187             :                 return 0;
    1188             : 
    1189   247315273 :         error = xfs_refcount_lookup_ge(cur, XFS_REFC_DOMAIN_SHARED, *agbno,
    1190             :                         &found_rec);
    1191   247317231 :         if (error)
    1192           0 :                 goto out_error;
    1193             : 
    1194   471267639 :         while (*aglen > 0 && xfs_refcount_still_have_space(cur)) {
    1195   323262034 :                 error = xfs_refcount_get_rec(cur, &ext, &found_rec);
    1196   323264604 :                 if (error)
    1197           0 :                         goto out_error;
    1198   323264604 :                 if (!found_rec || ext.rc_domain != XFS_REFC_DOMAIN_SHARED) {
    1199    26144361 :                         ext.rc_startblock = xrefc_max_startblock(cur);
    1200    26144361 :                         ext.rc_blockcount = 0;
    1201    26144361 :                         ext.rc_refcount = 0;
    1202    26144361 :                         ext.rc_domain = XFS_REFC_DOMAIN_SHARED;
    1203             :                 }
    1204             : 
    1205             :                 /*
    1206             :                  * Deal with a hole in the refcount tree; if a file maps to
    1207             :                  * these blocks and there's no refcountbt record, pretend that
    1208             :                  * there is one with refcount == 1.
    1209             :                  */
    1210   323264604 :                 if (ext.rc_startblock != *agbno) {
    1211   108549542 :                         tmp.rc_startblock = *agbno;
    1212   108549542 :                         tmp.rc_blockcount = min(*aglen,
    1213             :                                         ext.rc_startblock - *agbno);
    1214   108549542 :                         tmp.rc_refcount = 1 + adj;
    1215   108549542 :                         tmp.rc_domain = XFS_REFC_DOMAIN_SHARED;
    1216             : 
    1217   108549542 :                         trace_xfs_refcount_modify_extent(cur, &tmp);
    1218             : 
    1219             :                         /*
    1220             :                          * Either cover the hole (increment) or
    1221             :                          * delete the range (decrement).
    1222             :                          */
    1223   108548142 :                         xrefc_btree_state(cur)->nr_ops++;
    1224   108548142 :                         if (tmp.rc_refcount) {
    1225    32579285 :                                 error = xfs_refcount_insert(cur, &tmp,
    1226             :                                                 &found_tmp);
    1227    32579276 :                                 if (error)
    1228          39 :                                         goto out_error;
    1229    32579237 :                                 if (XFS_IS_CORRUPT(cur->bc_mp,
    1230             :                                                    found_tmp != 1)) {
    1231           0 :                                         xfs_btree_mark_sick(cur);
    1232           0 :                                         error = -EFSCORRUPTED;
    1233           0 :                                         goto out_error;
    1234             :                                 }
    1235             :                         } else {
    1236    75968857 :                                 error = xrefc_free_extent(cur, &tmp);
    1237    75968766 :                                 if (error)
    1238           0 :                                         goto out_error;
    1239             :                         }
    1240             : 
    1241   108548003 :                         (*agbno) += tmp.rc_blockcount;
    1242   108548003 :                         (*aglen) -= tmp.rc_blockcount;
    1243             : 
    1244             :                         /* Stop if there's nothing left to modify */
    1245   108548003 :                         if (*aglen == 0 || !xfs_refcount_still_have_space(cur))
    1246             :                                 break;
    1247             : 
    1248             :                         /* Move the cursor to the start of ext. */
    1249     9235409 :                         error = xfs_refcount_lookup_ge(cur,
    1250             :                                         XFS_REFC_DOMAIN_SHARED, *agbno,
    1251             :                                         &found_rec);
    1252     9235409 :                         if (error)
    1253           0 :                                 goto out_error;
    1254             :                 }
    1255             : 
    1256             :                 /*
    1257             :                  * A previous step trimmed agbno/aglen such that the end of the
    1258             :                  * range would not be in the middle of the record.  If this is
    1259             :                  * no longer the case, something is seriously wrong with the
    1260             :                  * btree.  Make sure we never feed the synthesized record into
    1261             :                  * the processing loop below.
    1262             :                  */
    1263   223950471 :                 if (XFS_IS_CORRUPT(cur->bc_mp, ext.rc_blockcount == 0) ||
    1264   223950471 :                     XFS_IS_CORRUPT(cur->bc_mp, ext.rc_blockcount > *aglen)) {
    1265           0 :                         xfs_btree_mark_sick(cur);
    1266           0 :                         error = -EFSCORRUPTED;
    1267           0 :                         goto out_error;
    1268             :                 }
    1269             : 
    1270             :                 /*
    1271             :                  * Adjust the reference count and either update the tree
    1272             :                  * (incr) or free the blocks (decr).
    1273             :                  */
    1274   223950471 :                 if (ext.rc_refcount == XFS_REFC_REFCOUNT_MAX)
    1275          80 :                         goto skip;
    1276   223950391 :                 ext.rc_refcount += adj;
    1277   223950391 :                 trace_xfs_refcount_modify_extent(cur, &ext);
    1278   223950086 :                 xrefc_btree_state(cur)->nr_ops++;
    1279   223950086 :                 if (ext.rc_refcount > 1) {
    1280   171558338 :                         error = xfs_refcount_update(cur, &ext);
    1281   171558279 :                         if (error)
    1282           0 :                                 goto out_error;
    1283    52391748 :                 } else if (ext.rc_refcount == 1) {
    1284    52391748 :                         error = xfs_refcount_delete(cur, &found_rec);
    1285    52391749 :                         if (error)
    1286           0 :                                 goto out_error;
    1287    52391749 :                         if (XFS_IS_CORRUPT(cur->bc_mp, found_rec != 1)) {
    1288           0 :                                 xfs_btree_mark_sick(cur);
    1289           0 :                                 error = -EFSCORRUPTED;
    1290           0 :                                 goto out_error;
    1291             :                         }
    1292    52391749 :                         goto advloop;
    1293             :                 } else {
    1294           0 :                         error = xrefc_free_extent(cur, &ext);
    1295           0 :                         if (error)
    1296           0 :                                 goto out_error;
    1297             :                 }
    1298             : 
    1299           0 : skip:
    1300   171558359 :                 error = xfs_btree_increment(cur, 0, &found_rec);
    1301   171558659 :                 if (error)
    1302           0 :                         goto out_error;
    1303             : 
    1304   171558659 : advloop:
    1305   223950408 :                 (*agbno) += ext.rc_blockcount;
    1306   223950408 :                 (*aglen) -= ext.rc_blockcount;
    1307             :         }
    1308             : 
    1309             :         return error;
    1310          39 : out_error:
    1311          39 :         trace_xfs_refcount_modify_extent_error(cur, error, _RET_IP_);
    1312          39 :         return error;
    1313             : }
    1314             : 
    1315             : /* Adjust the reference count of a range of AG blocks. */
    1316             : STATIC int
    1317   268445952 : xfs_refcount_adjust(
    1318             :         struct xfs_btree_cur    *cur,
    1319             :         xfs_agblock_t           *agbno,
    1320             :         xfs_extlen_t            *aglen,
    1321             :         enum xfs_refc_adjust_op adj)
    1322             : {
    1323   268445952 :         bool                    shape_changed;
    1324   268445952 :         int                     shape_changes = 0;
    1325   268445952 :         int                     error;
    1326             : 
    1327   268445952 :         if (adj == XFS_REFCOUNT_ADJUST_INCREASE)
    1328   136258151 :                 trace_xfs_refcount_increase(cur, *agbno, *aglen);
    1329             :         else
    1330   132187801 :                 trace_xfs_refcount_decrease(cur, *agbno, *aglen);
    1331             : 
    1332             :         /*
    1333             :          * Ensure that no rcextents cross the boundary of the adjustment range.
    1334             :          */
    1335   268445273 :         error = xfs_refcount_split_extent(cur, XFS_REFC_DOMAIN_SHARED,
    1336             :                         *agbno, &shape_changed);
    1337   268444547 :         if (error)
    1338         190 :                 goto out_error;
    1339   268444357 :         if (shape_changed)
    1340    19072336 :                 shape_changes++;
    1341             : 
    1342   268444357 :         error = xfs_refcount_split_extent(cur, XFS_REFC_DOMAIN_SHARED,
    1343   268444357 :                         *agbno + *aglen, &shape_changed);
    1344   268445845 :         if (error)
    1345          14 :                 goto out_error;
    1346   268445831 :         if (shape_changed)
    1347    26775947 :                 shape_changes++;
    1348             : 
    1349             :         /*
    1350             :          * Try to merge with the left or right extents of the range.
    1351             :          */
    1352   268445831 :         error = xfs_refcount_merge_extents(cur, XFS_REFC_DOMAIN_SHARED,
    1353             :                         agbno, aglen, adj, &shape_changed);
    1354   268444573 :         if (error)
    1355          10 :                 goto out_error;
    1356   268444563 :         if (shape_changed)
    1357    21938159 :                 shape_changes++;
    1358   268444563 :         if (shape_changes)
    1359    96682486 :                 xrefc_btree_state(cur)->shape_changes++;
    1360             : 
    1361             :         /* Now that we've taken care of the ends, adjust the middle extents */
    1362   268444563 :         error = xfs_refcount_adjust_extents(cur, agbno, aglen, adj);
    1363   268442322 :         if (error)
    1364          39 :                 goto out_error;
    1365             : 
    1366             :         return 0;
    1367             : 
    1368         253 : out_error:
    1369         253 :         trace_xfs_refcount_adjust_error(cur, error, _RET_IP_);
    1370         253 :         return error;
    1371             : }
    1372             : 
    1373             : /* Clean up after calling xfs_refcount_finish_one. */
    1374             : void
    1375   292245129 : xfs_refcount_finish_one_cleanup(
    1376             :         struct xfs_trans        *tp,
    1377             :         struct xfs_btree_cur    *rcur,
    1378             :         int                     error)
    1379             : {
    1380   292245129 :         struct xfs_buf          *agbp = NULL;
    1381             : 
    1382   292245129 :         if (rcur == NULL)
    1383             :                 return;
    1384   292244841 :         if (rcur->bc_btnum == XFS_BTNUM_REFC)
    1385   188563748 :                 agbp = rcur->bc_ag.agbp;
    1386   292244841 :         xfs_btree_del_cursor(rcur, error);
    1387   292247686 :         if (agbp)
    1388   188567834 :                 xfs_trans_brelse(tp, agbp);
    1389             : }
    1390             : 
    1391             : /* Does this btree cursor match the given AG? */
    1392             : static inline bool
    1393             : xfs_refcount_is_wrong_cursor(
    1394             :         struct xfs_btree_cur            *cur,
    1395             :         struct xfs_refcount_intent      *ri)
    1396             : {
    1397     3448348 :         if (cur->bc_btnum == XFS_BTNUM_RTREFC)
    1398     1395173 :                 return cur->bc_ino.rtg != ri->ri_rtg;
    1399     2053175 :         return cur->bc_ag.pag != ri->ri_pag;
    1400             : }
    1401             : 
    1402             : /*
    1403             :  * Set up a continuation a deferred refcount operation by updating the intent.
    1404             :  * Checks to make sure we're not going to run off the end of the AG or rtgroup.
    1405             :  */
    1406             : static inline int
    1407        1795 : xfs_refcount_continue_op(
    1408             :         struct xfs_btree_cur            *cur,
    1409             :         struct xfs_refcount_intent      *ri,
    1410             :         xfs_agblock_t                   new_agbno)
    1411             : {
    1412        1795 :         struct xfs_mount                *mp = cur->bc_mp;
    1413             : 
    1414        1795 :         if (ri->ri_realtime) {
    1415         388 :                 struct xfs_rtgroup      *rtg = ri->ri_rtg;
    1416             : 
    1417         388 :                 if (XFS_IS_CORRUPT(mp, !xfs_verify_rgbext(rtg, new_agbno,
    1418             :                                                 ri->ri_blockcount))) {
    1419           0 :                         xfs_btree_mark_sick(cur);
    1420           0 :                         return -EFSCORRUPTED;
    1421             :                 }
    1422             : 
    1423         388 :                 ri->ri_startblock = xfs_rgbno_to_rtb(mp, rtg->rtg_rgno, new_agbno);
    1424             : 
    1425         388 :                 ASSERT(xfs_verify_rtbext(mp, ri->ri_startblock, ri->ri_blockcount));
    1426         388 :                 ASSERT(rtg->rtg_rgno == xfs_rtb_to_rgno(mp, ri->ri_startblock));
    1427             :         } else {
    1428        1407 :                 struct xfs_perag                *pag = cur->bc_ag.pag;
    1429             : 
    1430        1407 :                 if (XFS_IS_CORRUPT(mp, !xfs_verify_agbext(pag, new_agbno,
    1431             :                                                 ri->ri_blockcount))) {
    1432           0 :                         xfs_btree_mark_sick(cur);
    1433           0 :                         return -EFSCORRUPTED;
    1434             :                 }
    1435             : 
    1436        1407 :                 ri->ri_startblock = XFS_AGB_TO_FSB(mp, pag->pag_agno, new_agbno);
    1437             : 
    1438        1407 :                 ASSERT(xfs_verify_fsbext(mp, ri->ri_startblock, ri->ri_blockcount));
    1439        1407 :                 ASSERT(pag->pag_agno == XFS_FSB_TO_AGNO(mp, ri->ri_startblock));
    1440             :         }
    1441             : 
    1442             :         return 0;
    1443             : }
    1444             : 
    1445             : /*
    1446             :  * Process one of the deferred refcount operations.  We pass back the
    1447             :  * btree cursor to maintain our lock on the btree between calls.
    1448             :  * This saves time and eliminates a buffer deadlock between the
    1449             :  * superblock and the AGF because we'll always grab them in the same
    1450             :  * order.
    1451             :  */
    1452             : int
    1453   294706913 : xfs_refcount_finish_one(
    1454             :         struct xfs_trans                *tp,
    1455             :         struct xfs_refcount_intent      *ri,
    1456             :         struct xfs_btree_cur            **pcur)
    1457             : {
    1458   294706913 :         struct xfs_mount                *mp = tp->t_mountp;
    1459   294706913 :         struct xfs_btree_cur            *rcur;
    1460   294706913 :         struct xfs_buf                  *agbp = NULL;
    1461   294706913 :         int                             error = 0;
    1462   294706913 :         xfs_agblock_t                   bno;
    1463   294706913 :         unsigned long                   nr_ops = 0;
    1464   294706913 :         int                             shape_changes = 0;
    1465             : 
    1466   294706913 :         trace_xfs_refcount_deferred(mp, ri);
    1467             : 
    1468   294702975 :         if (ri->ri_realtime) {
    1469   104598888 :                 xfs_rgnumber_t          rgno;
    1470             : 
    1471   104598888 :                 bno = xfs_rtb_to_rgbno(mp, ri->ri_startblock, &rgno);
    1472             :         } else {
    1473   190104087 :                 bno = XFS_FSB_TO_AGBNO(mp, ri->ri_startblock);
    1474             :         }
    1475             : 
    1476   294702869 :         if (XFS_TEST_ERROR(false, mp, XFS_ERRTAG_REFCOUNT_FINISH_ONE))
    1477             :                 return -EIO;
    1478             : 
    1479             :         /*
    1480             :          * If we haven't gotten a cursor or the cursor AG doesn't match
    1481             :          * the startblock, get one now.
    1482             :          */
    1483   294703821 :         rcur = *pcur;
    1484   298152169 :         if (rcur != NULL && xfs_refcount_is_wrong_cursor(rcur, ri)) {
    1485      984807 :                 nr_ops = xrefc_btree_state(rcur)->nr_ops;
    1486      984807 :                 shape_changes = xrefc_btree_state(rcur)->shape_changes;
    1487      984807 :                 xfs_refcount_finish_one_cleanup(tp, rcur, 0);
    1488      984807 :                 rcur = NULL;
    1489      984807 :                 *pcur = NULL;
    1490             :         }
    1491   294703821 :         if (rcur == NULL) {
    1492   292240032 :                 if (ri->ri_realtime) {
    1493   103679323 :                         xfs_rtgroup_lock(tp, ri->ri_rtg, XFS_RTGLOCK_REFCOUNT);
    1494   103680173 :                         rcur = xfs_rtrefcountbt_init_cursor(mp, tp, ri->ri_rtg,
    1495   103680173 :                                         ri->ri_rtg->rtg_refcountip);
    1496             :                 } else {
    1497   188560709 :                         error = xfs_alloc_read_agf(ri->ri_pag, tp,
    1498             :                                         XFS_ALLOC_FLAG_FREEING, &agbp);
    1499   188567209 :                         if (error)
    1500             :                                 return error;
    1501             : 
    1502   188567066 :                         rcur = xfs_refcountbt_init_cursor(mp, tp, agbp,
    1503             :                                         ri->ri_pag);
    1504             :                 }
    1505   292247709 :                 xrefc_btree_state(rcur)->nr_ops = nr_ops;
    1506   584495418 :                 xrefc_btree_state(rcur)->shape_changes = shape_changes;
    1507             :         }
    1508   294711498 :         *pcur = rcur;
    1509             : 
    1510   294711498 :         switch (ri->ri_type) {
    1511   136258170 :         case XFS_REFCOUNT_INCREASE:
    1512   136258170 :                 error = xfs_refcount_adjust(rcur, &bno, &ri->ri_blockcount,
    1513             :                                 XFS_REFCOUNT_ADJUST_INCREASE);
    1514   136258136 :                 if (error)
    1515             :                         return error;
    1516   136258027 :                 if (ri->ri_blockcount > 0)
    1517         210 :                         error = xfs_refcount_continue_op(rcur, ri, bno);
    1518             :                 break;
    1519   132188224 :         case XFS_REFCOUNT_DECREASE:
    1520   132188224 :                 error = xfs_refcount_adjust(rcur, &bno, &ri->ri_blockcount,
    1521             :                                 XFS_REFCOUNT_ADJUST_DECREASE);
    1522   132184334 :                 if (error)
    1523             :                         return error;
    1524   132184190 :                 if (ri->ri_blockcount > 0)
    1525        1585 :                         error = xfs_refcount_continue_op(rcur, ri, bno);
    1526             :                 break;
    1527     4923613 :         case XFS_REFCOUNT_ALLOC_COW:
    1528     4923613 :                 error = __xfs_refcount_cow_alloc(rcur, bno, ri->ri_blockcount);
    1529     4923401 :                 if (error)
    1530             :                         return error;
    1531     4923400 :                 ri->ri_blockcount = 0;
    1532     4923400 :                 break;
    1533    21341491 :         case XFS_REFCOUNT_FREE_COW:
    1534    21341491 :                 error = __xfs_refcount_cow_free(rcur, bno, ri->ri_blockcount);
    1535    21341656 :                 if (error)
    1536             :                         return error;
    1537    21341656 :                 ri->ri_blockcount = 0;
    1538    21341656 :                 break;
    1539           0 :         default:
    1540           0 :                 ASSERT(0);
    1541           0 :                 return -EFSCORRUPTED;
    1542             :         }
    1543   294707273 :         if (!error && ri->ri_blockcount > 0)
    1544        1795 :                 trace_xfs_refcount_finish_one_leftover(mp, ri);
    1545             :         return error;
    1546             : }
    1547             : 
    1548             : /*
    1549             :  * Record a refcount intent for later processing.
    1550             :  */
    1551             : static void
    1552   294698667 : __xfs_refcount_add(
    1553             :         struct xfs_trans                *tp,
    1554             :         enum xfs_refcount_intent_type   type,
    1555             :         bool                            isrt,
    1556             :         xfs_fsblock_t                   startblock,
    1557             :         xfs_extlen_t                    blockcount)
    1558             : {
    1559   294698667 :         struct xfs_refcount_intent      *ri;
    1560   294698667 :         enum xfs_defer_ops_type         optype;
    1561             : 
    1562   294698667 :         ri = kmem_cache_alloc(xfs_refcount_intent_cache,
    1563             :                         GFP_NOFS | __GFP_NOFAIL);
    1564   294700041 :         INIT_LIST_HEAD(&ri->ri_list);
    1565   294700041 :         ri->ri_type = type;
    1566   294700041 :         ri->ri_startblock = startblock;
    1567   294700041 :         ri->ri_blockcount = blockcount;
    1568   294700041 :         ri->ri_realtime = isrt;
    1569             : 
    1570   294700041 :         trace_xfs_refcount_defer(tp->t_mountp, ri);
    1571             : 
    1572             :         /*
    1573             :          * Deferred refcount updates for the realtime and data sections must
    1574             :          * use separate transactions to finish deferred work because updates to
    1575             :          * realtime metadata files can lock AGFs to allocate btree blocks and
    1576             :          * we don't want that mixing with the AGF locks taken to finish data
    1577             :          * section updates.
    1578             :          */
    1579   294695459 :         if (isrt)
    1580             :                 optype = XFS_DEFER_OPS_TYPE_REFCOUNT_RT;
    1581             :         else
    1582   190097881 :                 optype = XFS_DEFER_OPS_TYPE_REFCOUNT;
    1583             : 
    1584   294695459 :         xfs_refcount_update_get_group(tp->t_mountp, ri);
    1585   294708559 :         xfs_defer_add(tp, optype, &ri->ri_list);
    1586   294708599 : }
    1587             : 
    1588             : /*
    1589             :  * Increase the reference count of the blocks backing a file's extent.
    1590             :  */
    1591             : void
    1592   136257399 : xfs_refcount_increase_extent(
    1593             :         struct xfs_trans                *tp,
    1594             :         bool                            isrt,
    1595             :         struct xfs_bmbt_irec            *PREV)
    1596             : {
    1597   136257399 :         if (!xfs_has_reflink(tp->t_mountp))
    1598             :                 return;
    1599             : 
    1600   136257362 :         __xfs_refcount_add(tp, XFS_REFCOUNT_INCREASE, isrt, PREV->br_startblock,
    1601   136257362 :                         PREV->br_blockcount);
    1602             : }
    1603             : 
    1604             : /*
    1605             :  * Decrease the reference count of the blocks backing a file's extent.
    1606             :  */
    1607             : void
    1608   132182789 : xfs_refcount_decrease_extent(
    1609             :         struct xfs_trans                *tp,
    1610             :         bool                            isrt,
    1611             :         struct xfs_bmbt_irec            *PREV)
    1612             : {
    1613   132182789 :         if (!xfs_has_reflink(tp->t_mountp))
    1614             :                 return;
    1615             : 
    1616   132182176 :         __xfs_refcount_add(tp, XFS_REFCOUNT_DECREASE, isrt, PREV->br_startblock,
    1617   132182176 :                         PREV->br_blockcount);
    1618             : }
    1619             : 
    1620             : /*
    1621             :  * Given an AG extent, find the lowest-numbered run of shared blocks
    1622             :  * within that range and return the range in fbno/flen.  If
    1623             :  * find_end_of_shared is set, return the longest contiguous extent of
    1624             :  * shared blocks; if not, just return the first extent we find.  If no
    1625             :  * shared blocks are found, fbno and flen will be set to NULLAGBLOCK
    1626             :  * and 0, respectively.
    1627             :  */
    1628             : int
    1629  2923361721 : xfs_refcount_find_shared(
    1630             :         struct xfs_btree_cur            *cur,
    1631             :         xfs_agblock_t                   agbno,
    1632             :         xfs_extlen_t                    aglen,
    1633             :         xfs_agblock_t                   *fbno,
    1634             :         xfs_extlen_t                    *flen,
    1635             :         bool                            find_end_of_shared)
    1636             : {
    1637  2923361721 :         struct xfs_refcount_irec        tmp;
    1638  2923361721 :         int                             i;
    1639  2923361721 :         int                             have;
    1640  2923361721 :         int                             error;
    1641             : 
    1642  2923361721 :         trace_xfs_refcount_find_shared(cur, agbno, aglen);
    1643             : 
    1644             :         /* By default, skip the whole range */
    1645  2913348921 :         *fbno = NULLAGBLOCK;
    1646  2913348921 :         *flen = 0;
    1647             : 
    1648             :         /* Try to find a refcount extent that crosses the start */
    1649  2913348921 :         error = xfs_refcount_lookup_le(cur, XFS_REFC_DOMAIN_SHARED, agbno,
    1650             :                         &have);
    1651  2924394415 :         if (error)
    1652          67 :                 goto out_error;
    1653  2924394348 :         if (!have) {
    1654             :                 /* No left extent, look at the next one */
    1655   937091279 :                 error = xfs_btree_increment(cur, 0, &have);
    1656   935535154 :                 if (error)
    1657           0 :                         goto out_error;
    1658   935535154 :                 if (!have)
    1659   888142377 :                         goto done;
    1660             :         }
    1661  2034695846 :         error = xfs_refcount_get_rec(cur, &tmp, &i);
    1662  2031815617 :         if (error)
    1663           0 :                 goto out_error;
    1664  2031815617 :         if (XFS_IS_CORRUPT(cur->bc_mp, i != 1)) {
    1665           0 :                 xfs_btree_mark_sick(cur);
    1666           0 :                 error = -EFSCORRUPTED;
    1667           0 :                 goto out_error;
    1668             :         }
    1669  2031815617 :         if (tmp.rc_domain != XFS_REFC_DOMAIN_SHARED)
    1670     3174644 :                 goto done;
    1671             : 
    1672             :         /* If the extent ends before the start, look at the next one */
    1673  2028640973 :         if (tmp.rc_startblock + tmp.rc_blockcount <= agbno) {
    1674  1517029908 :                 error = xfs_btree_increment(cur, 0, &have);
    1675  1518455720 :                 if (error)
    1676           0 :                         goto out_error;
    1677  1518455720 :                 if (!have)
    1678    29743785 :                         goto done;
    1679  1488711935 :                 error = xfs_refcount_get_rec(cur, &tmp, &i);
    1680  1488258009 :                 if (error)
    1681           0 :                         goto out_error;
    1682  1488258009 :                 if (XFS_IS_CORRUPT(cur->bc_mp, i != 1)) {
    1683           0 :                         xfs_btree_mark_sick(cur);
    1684           0 :                         error = -EFSCORRUPTED;
    1685           0 :                         goto out_error;
    1686             :                 }
    1687  1488258009 :                 if (tmp.rc_domain != XFS_REFC_DOMAIN_SHARED)
    1688    33986020 :                         goto done;
    1689             :         }
    1690             : 
    1691             :         /* If the extent starts after the range we want, bail out */
    1692  1965883054 :         if (tmp.rc_startblock >= agbno + aglen)
    1693  1492932692 :                 goto done;
    1694             : 
    1695             :         /* We found the start of a shared extent! */
    1696   472950362 :         if (tmp.rc_startblock < agbno) {
    1697    48803553 :                 tmp.rc_blockcount -= (agbno - tmp.rc_startblock);
    1698    48803553 :                 tmp.rc_startblock = agbno;
    1699             :         }
    1700             : 
    1701   472950362 :         *fbno = tmp.rc_startblock;
    1702   472950362 :         *flen = min(tmp.rc_blockcount, agbno + aglen - *fbno);
    1703   472950362 :         if (!find_end_of_shared)
    1704   468326754 :                 goto done;
    1705             : 
    1706             :         /* Otherwise, find the end of this shared extent */
    1707     7271378 :         while (*fbno + *flen < agbno + aglen) {
    1708     2635566 :                 error = xfs_btree_increment(cur, 0, &have);
    1709     2782685 :                 if (error)
    1710           0 :                         goto out_error;
    1711     2782685 :                 if (!have)
    1712             :                         break;
    1713     2773615 :                 error = xfs_refcount_get_rec(cur, &tmp, &i);
    1714     2773617 :                 if (error)
    1715           0 :                         goto out_error;
    1716     2773617 :                 if (XFS_IS_CORRUPT(cur->bc_mp, i != 1)) {
    1717           0 :                         xfs_btree_mark_sick(cur);
    1718           0 :                         error = -EFSCORRUPTED;
    1719           0 :                         goto out_error;
    1720             :                 }
    1721     2773617 :                 if (tmp.rc_domain != XFS_REFC_DOMAIN_SHARED ||
    1722     2759207 :                     tmp.rc_startblock >= agbno + aglen ||
    1723     2661927 :                     tmp.rc_startblock != *fbno + *flen)
    1724             :                         break;
    1725     2647770 :                 *flen = min(*flen + tmp.rc_blockcount, agbno + aglen - *fbno);
    1726             :         }
    1727             : 
    1728     4786761 : done:
    1729  2921093033 :         trace_xfs_refcount_find_shared_result(cur, *fbno, *flen);
    1730             : 
    1731  2918769918 : out_error:
    1732  2918769918 :         if (error)
    1733          67 :                 trace_xfs_refcount_find_shared_error(cur, error, _RET_IP_);
    1734  2918769918 :         return error;
    1735             : }
    1736             : 
    1737             : /*
    1738             :  * Recovering CoW Blocks After a Crash
    1739             :  *
    1740             :  * Due to the way that the copy on write mechanism works, there's a window of
    1741             :  * opportunity in which we can lose track of allocated blocks during a crash.
    1742             :  * Because CoW uses delayed allocation in the in-core CoW fork, writeback
    1743             :  * causes blocks to be allocated and stored in the CoW fork.  The blocks are
    1744             :  * no longer in the free space btree but are not otherwise recorded anywhere
    1745             :  * until the write completes and the blocks are mapped into the file.  A crash
    1746             :  * in between allocation and remapping results in the replacement blocks being
    1747             :  * lost.  This situation is exacerbated by the CoW extent size hint because
    1748             :  * allocations can hang around for long time.
    1749             :  *
    1750             :  * However, there is a place where we can record these allocations before they
    1751             :  * become mappings -- the reference count btree.  The btree does not record
    1752             :  * extents with refcount == 1, so we can record allocations with a refcount of
    1753             :  * 1.  Blocks being used for CoW writeout cannot be shared, so there should be
    1754             :  * no conflict with shared block records.  These mappings should be created
    1755             :  * when we allocate blocks to the CoW fork and deleted when they're removed
    1756             :  * from the CoW fork.
    1757             :  *
    1758             :  * Minor nit: records for in-progress CoW allocations and records for shared
    1759             :  * extents must never be merged, to preserve the property that (except for CoW
    1760             :  * allocations) there are no refcount btree entries with refcount == 1.  The
    1761             :  * only time this could potentially happen is when unsharing a block that's
    1762             :  * adjacent to CoW allocations, so we must be careful to avoid this.
    1763             :  *
    1764             :  * At mount time we recover lost CoW allocations by searching the refcount
    1765             :  * btree for these refcount == 1 mappings.  These represent CoW allocations
    1766             :  * that were in progress at the time the filesystem went down, so we can free
    1767             :  * them to get the space back.
    1768             :  *
    1769             :  * This mechanism is superior to creating EFIs for unmapped CoW extents for
    1770             :  * several reasons -- first, EFIs pin the tail of the log and would have to be
    1771             :  * periodically relogged to avoid filling up the log.  Second, CoW completions
    1772             :  * will have to file an EFD and create new EFIs for whatever remains in the
    1773             :  * CoW fork; this partially takes care of (1) but extent-size reservations
    1774             :  * will have to periodically relog even if there's no writeout in progress.
    1775             :  * This can happen if the CoW extent size hint is set, which you really want.
    1776             :  * Third, EFIs cannot currently be automatically relogged into newer
    1777             :  * transactions to advance the log tail.  Fourth, stuffing the log full of
    1778             :  * EFIs places an upper bound on the number of CoW allocations that can be
    1779             :  * held filesystem-wide at any given time.  Recording them in the refcount
    1780             :  * btree doesn't require us to maintain any state in memory and doesn't pin
    1781             :  * the log.
    1782             :  */
    1783             : /*
    1784             :  * Adjust the refcounts of CoW allocations.  These allocations are "magic"
    1785             :  * in that they're not referenced anywhere else in the filesystem, so we
    1786             :  * stash them in the refcount btree with a refcount of 1 until either file
    1787             :  * remapping (or CoW cancellation) happens.
    1788             :  */
    1789             : STATIC int
    1790    26264211 : xfs_refcount_adjust_cow_extents(
    1791             :         struct xfs_btree_cur    *cur,
    1792             :         xfs_agblock_t           agbno,
    1793             :         xfs_extlen_t            aglen,
    1794             :         enum xfs_refc_adjust_op adj)
    1795             : {
    1796    26264211 :         struct xfs_refcount_irec        ext, tmp;
    1797    26264211 :         int                             error;
    1798    26264211 :         int                             found_rec, found_tmp;
    1799             : 
    1800    26264211 :         if (aglen == 0)
    1801             :                 return 0;
    1802             : 
    1803             :         /* Find any overlapping refcount records */
    1804    24245346 :         error = xfs_refcount_lookup_ge(cur, XFS_REFC_DOMAIN_COW, agbno,
    1805             :                         &found_rec);
    1806    24247038 :         if (error)
    1807           0 :                 goto out_error;
    1808    24247038 :         error = xfs_refcount_get_rec(cur, &ext, &found_rec);
    1809    24246687 :         if (error)
    1810           0 :                 goto out_error;
    1811    24246687 :         if (XFS_IS_CORRUPT(cur->bc_mp, found_rec &&
    1812             :                                 ext.rc_domain != XFS_REFC_DOMAIN_COW)) {
    1813           0 :                 xfs_btree_mark_sick(cur);
    1814           0 :                 error = -EFSCORRUPTED;
    1815           0 :                 goto out_error;
    1816             :         }
    1817    24246687 :         if (!found_rec) {
    1818     1570884 :                 ext.rc_startblock = xrefc_max_startblock(cur);
    1819     1570884 :                 ext.rc_blockcount = 0;
    1820     1570884 :                 ext.rc_refcount = 0;
    1821     1570884 :                 ext.rc_domain = XFS_REFC_DOMAIN_COW;
    1822             :         }
    1823             : 
    1824    24246687 :         switch (adj) {
    1825     2904844 :         case XFS_REFCOUNT_ADJUST_COW_ALLOC:
    1826             :                 /* Adding a CoW reservation, there should be nothing here. */
    1827     2904844 :                 if (XFS_IS_CORRUPT(cur->bc_mp,
    1828             :                                    agbno + aglen > ext.rc_startblock)) {
    1829           0 :                         xfs_btree_mark_sick(cur);
    1830           0 :                         error = -EFSCORRUPTED;
    1831           0 :                         goto out_error;
    1832             :                 }
    1833             : 
    1834     2904844 :                 tmp.rc_startblock = agbno;
    1835     2904844 :                 tmp.rc_blockcount = aglen;
    1836     2904844 :                 tmp.rc_refcount = 1;
    1837     2904844 :                 tmp.rc_domain = XFS_REFC_DOMAIN_COW;
    1838             : 
    1839     2904844 :                 trace_xfs_refcount_modify_extent(cur, &tmp);
    1840             : 
    1841     2904786 :                 error = xfs_refcount_insert(cur, &tmp,
    1842             :                                 &found_tmp);
    1843     2904769 :                 if (error)
    1844           0 :                         goto out_error;
    1845     2904769 :                 if (XFS_IS_CORRUPT(cur->bc_mp, found_tmp != 1)) {
    1846           0 :                         xfs_btree_mark_sick(cur);
    1847           0 :                         error = -EFSCORRUPTED;
    1848           0 :                         goto out_error;
    1849             :                 }
    1850             :                 break;
    1851    21341843 :         case XFS_REFCOUNT_ADJUST_COW_FREE:
    1852             :                 /* Removing a CoW reservation, there should be one extent. */
    1853    21341843 :                 if (XFS_IS_CORRUPT(cur->bc_mp, ext.rc_startblock != agbno)) {
    1854           0 :                         xfs_btree_mark_sick(cur);
    1855           0 :                         error = -EFSCORRUPTED;
    1856           0 :                         goto out_error;
    1857             :                 }
    1858    21341843 :                 if (XFS_IS_CORRUPT(cur->bc_mp, ext.rc_blockcount != aglen)) {
    1859           0 :                         xfs_btree_mark_sick(cur);
    1860           0 :                         error = -EFSCORRUPTED;
    1861           0 :                         goto out_error;
    1862             :                 }
    1863    21341843 :                 if (XFS_IS_CORRUPT(cur->bc_mp, ext.rc_refcount != 1)) {
    1864           0 :                         xfs_btree_mark_sick(cur);
    1865           0 :                         error = -EFSCORRUPTED;
    1866           0 :                         goto out_error;
    1867             :                 }
    1868             : 
    1869    21341843 :                 ext.rc_refcount = 0;
    1870    21341843 :                 trace_xfs_refcount_modify_extent(cur, &ext);
    1871    21340316 :                 error = xfs_refcount_delete(cur, &found_rec);
    1872    21341981 :                 if (error)
    1873           0 :                         goto out_error;
    1874    21341981 :                 if (XFS_IS_CORRUPT(cur->bc_mp, found_rec != 1)) {
    1875           0 :                         xfs_btree_mark_sick(cur);
    1876           0 :                         error = -EFSCORRUPTED;
    1877           0 :                         goto out_error;
    1878             :                 }
    1879             :                 break;
    1880           0 :         default:
    1881           0 :                 ASSERT(0);
    1882             :         }
    1883             : 
    1884             :         return error;
    1885           0 : out_error:
    1886           0 :         trace_xfs_refcount_modify_extent_error(cur, error, _RET_IP_);
    1887           0 :         return error;
    1888             : }
    1889             : 
    1890             : /*
    1891             :  * Add or remove refcount btree entries for CoW reservations.
    1892             :  */
    1893             : STATIC int
    1894    26261862 : xfs_refcount_adjust_cow(
    1895             :         struct xfs_btree_cur    *cur,
    1896             :         xfs_agblock_t           agbno,
    1897             :         xfs_extlen_t            aglen,
    1898             :         enum xfs_refc_adjust_op adj)
    1899             : {
    1900    26261862 :         bool                    shape_changed;
    1901    26261862 :         int                     error;
    1902             : 
    1903             :         /*
    1904             :          * Ensure that no rcextents cross the boundary of the adjustment range.
    1905             :          */
    1906    26261862 :         error = xfs_refcount_split_extent(cur, XFS_REFC_DOMAIN_COW,
    1907             :                         agbno, &shape_changed);
    1908    26262737 :         if (error)
    1909           1 :                 goto out_error;
    1910             : 
    1911    26262736 :         error = xfs_refcount_split_extent(cur, XFS_REFC_DOMAIN_COW,
    1912             :                         agbno + aglen, &shape_changed);
    1913    26264994 :         if (error)
    1914           0 :                 goto out_error;
    1915             : 
    1916             :         /*
    1917             :          * Try to merge with the left or right extents of the range.
    1918             :          */
    1919    26264994 :         error = xfs_refcount_merge_extents(cur, XFS_REFC_DOMAIN_COW, &agbno,
    1920             :                         &aglen, adj, &shape_changed);
    1921    26264309 :         if (error)
    1922           0 :                 goto out_error;
    1923             : 
    1924             :         /* Now that we've taken care of the ends, adjust the middle extents */
    1925    26264309 :         error = xfs_refcount_adjust_cow_extents(cur, agbno, aglen, adj);
    1926    26265183 :         if (error)
    1927           0 :                 goto out_error;
    1928             : 
    1929             :         return 0;
    1930             : 
    1931           1 : out_error:
    1932           1 :         trace_xfs_refcount_adjust_cow_error(cur, error, _RET_IP_);
    1933           1 :         return error;
    1934             : }
    1935             : 
    1936             : /*
    1937             :  * Record a CoW allocation in the refcount btree.
    1938             :  */
    1939             : STATIC int
    1940     4923512 : __xfs_refcount_cow_alloc(
    1941             :         struct xfs_btree_cur    *rcur,
    1942             :         xfs_agblock_t           agbno,
    1943             :         xfs_extlen_t            aglen)
    1944             : {
    1945     4923512 :         trace_xfs_refcount_cow_increase(rcur, agbno, aglen);
    1946             : 
    1947             :         /* Add refcount btree reservation */
    1948     4923400 :         return xfs_refcount_adjust_cow(rcur, agbno, aglen,
    1949             :                         XFS_REFCOUNT_ADJUST_COW_ALLOC);
    1950             : }
    1951             : 
    1952             : /*
    1953             :  * Remove a CoW allocation from the refcount btree.
    1954             :  */
    1955             : STATIC int
    1956    21339858 : __xfs_refcount_cow_free(
    1957             :         struct xfs_btree_cur    *rcur,
    1958             :         xfs_agblock_t           agbno,
    1959             :         xfs_extlen_t            aglen)
    1960             : {
    1961    21339858 :         trace_xfs_refcount_cow_decrease(rcur, agbno, aglen);
    1962             : 
    1963             :         /* Remove refcount btree reservation */
    1964    21337398 :         return xfs_refcount_adjust_cow(rcur, agbno, aglen,
    1965             :                         XFS_REFCOUNT_ADJUST_COW_FREE);
    1966             : }
    1967             : 
    1968             : /* Record a CoW staging extent in the refcount btree. */
    1969             : void
    1970     4923414 : xfs_refcount_alloc_cow_extent(
    1971             :         struct xfs_trans                *tp,
    1972             :         bool                            isrt,
    1973             :         xfs_fsblock_t                   fsb,
    1974             :         xfs_extlen_t                    len)
    1975             : {
    1976     4923414 :         struct xfs_mount                *mp = tp->t_mountp;
    1977             : 
    1978     4923414 :         if (!xfs_has_reflink(mp))
    1979             :                 return;
    1980             : 
    1981     4923382 :         __xfs_refcount_add(tp, XFS_REFCOUNT_ALLOC_COW, isrt, fsb, len);
    1982             : 
    1983             :         /* Add rmap entry */
    1984     4923509 :         xfs_rmap_alloc_extent(tp, isrt, fsb, len, XFS_RMAP_OWN_COW);
    1985             : }
    1986             : 
    1987             : /* Forget a CoW staging event in the refcount btree. */
    1988             : void
    1989    21337515 : xfs_refcount_free_cow_extent(
    1990             :         struct xfs_trans                *tp,
    1991             :         bool                            isrt,
    1992             :         xfs_fsblock_t                   fsb,
    1993             :         xfs_extlen_t                    len)
    1994             : {
    1995    21337515 :         struct xfs_mount                *mp = tp->t_mountp;
    1996             : 
    1997    21337515 :         if (!xfs_has_reflink(mp))
    1998             :                 return;
    1999             : 
    2000             :         /* Remove rmap entry */
    2001    21337305 :         xfs_rmap_free_extent(tp, isrt, fsb, len, XFS_RMAP_OWN_COW);
    2002    21339454 :         __xfs_refcount_add(tp, XFS_REFCOUNT_FREE_COW, isrt, fsb, len);
    2003             : }
    2004             : 
    2005             : struct xfs_refcount_recovery {
    2006             :         struct list_head                rr_list;
    2007             :         struct xfs_refcount_irec        rr_rrec;
    2008             : };
    2009             : 
    2010             : /* Stuff an extent on the recovery list. */
    2011             : STATIC int
    2012      310417 : xfs_refcount_recover_extent(
    2013             :         struct xfs_btree_cur            *cur,
    2014             :         const union xfs_btree_rec       *rec,
    2015             :         void                            *priv)
    2016             : {
    2017      310417 :         struct list_head                *debris = priv;
    2018      310417 :         struct xfs_refcount_recovery    *rr;
    2019             : 
    2020      310417 :         if (XFS_IS_CORRUPT(cur->bc_mp,
    2021             :                            be32_to_cpu(rec->refc.rc_refcount) != 1)) {
    2022           0 :                 xfs_btree_mark_sick(cur);
    2023           0 :                 return -EFSCORRUPTED;
    2024             :         }
    2025             : 
    2026      310417 :         rr = kmalloc(sizeof(struct xfs_refcount_recovery),
    2027             :                         GFP_KERNEL | __GFP_NOFAIL);
    2028      310417 :         INIT_LIST_HEAD(&rr->rr_list);
    2029      310417 :         xfs_refcount_btrec_to_irec(rec, &rr->rr_rrec);
    2030             : 
    2031      310417 :         if (xfs_refcount_check_irec(cur, &rr->rr_rrec) != NULL ||
    2032      310417 :             XFS_IS_CORRUPT(cur->bc_mp,
    2033             :                            rr->rr_rrec.rc_domain != XFS_REFC_DOMAIN_COW)) {
    2034           0 :                 xfs_btree_mark_sick(cur);
    2035           0 :                 kfree(rr);
    2036           0 :                 return -EFSCORRUPTED;
    2037             :         }
    2038             : 
    2039      310417 :         list_add_tail(&rr->rr_list, debris);
    2040      310417 :         return 0;
    2041             : }
    2042             : 
    2043             : /* Find and remove leftover CoW reservations. */
    2044             : static int
    2045       62327 : xfs_refcount_recover_group_cow_leftovers(
    2046             :         struct xfs_mount                *mp,
    2047             :         struct xfs_perag                *pag,
    2048             :         struct xfs_rtgroup              *rtg)
    2049             : {
    2050       62327 :         struct xfs_trans                *tp;
    2051       62327 :         struct xfs_btree_cur            *cur;
    2052       62327 :         struct xfs_buf                  *agbp = NULL;
    2053       62327 :         struct xfs_refcount_recovery    *rr, *n;
    2054       62327 :         struct list_head                debris;
    2055       62327 :         union xfs_btree_irec            low = {
    2056             :                 .rc.rc_domain           = XFS_REFC_DOMAIN_COW,
    2057             :         };
    2058       62327 :         union xfs_btree_irec            high = {
    2059             :                 .rc.rc_domain           = XFS_REFC_DOMAIN_COW,
    2060             :                 .rc.rc_startblock       = -1U,
    2061             :         };
    2062       62327 :         xfs_fsblock_t                   fsb;
    2063       62327 :         int                             error;
    2064             : 
    2065             :         /* reflink filesystems mustn't have AGs larger than 2^31-1 blocks */
    2066       62327 :         BUILD_BUG_ON(XFS_MAX_CRC_AG_BLOCKS >= XFS_REFC_COWFLAG);
    2067       62327 :         if (pag && mp->m_sb.sb_agblocks > XFS_MAX_CRC_AG_BLOCKS)
    2068             :                 return -EOPNOTSUPP;
    2069             : 
    2070             :         /* rtreflink filesystems can't have rtgroups larger than 2^31-1 blocks */
    2071       62327 :         BUILD_BUG_ON(XFS_MAX_RGBLOCKS >= XFS_REFC_COWFLAG);
    2072       62327 :         if (rtg && mp->m_sb.sb_rgblocks >= XFS_MAX_RGBLOCKS)
    2073             :                 return -EOPNOTSUPP;
    2074             : 
    2075       62327 :         INIT_LIST_HEAD(&debris);
    2076             : 
    2077             :         /*
    2078             :          * In this first part, we use an empty transaction to gather up
    2079             :          * all the leftover CoW extents so that we can subsequently
    2080             :          * delete them.  The empty transaction is used to avoid
    2081             :          * a buffer lock deadlock if there happens to be a loop in the
    2082             :          * refcountbt because we're allowed to re-grab a buffer that is
    2083             :          * already attached to our transaction.  When we're done
    2084             :          * recording the CoW debris we cancel the (empty) transaction
    2085             :          * and everything goes away cleanly.
    2086             :          */
    2087       62327 :         error = xfs_trans_alloc_empty(mp, &tp);
    2088       62327 :         if (error)
    2089             :                 return error;
    2090             : 
    2091       62327 :         if (rtg) {
    2092        6325 :                 xfs_rtgroup_lock(NULL, rtg, XFS_RTGLOCK_REFCOUNT);
    2093        6325 :                 cur = xfs_rtrefcountbt_init_cursor(mp, tp, rtg,
    2094             :                                 rtg->rtg_refcountip);
    2095             :         } else {
    2096       56002 :                 error = xfs_alloc_read_agf(pag, tp, 0, &agbp);
    2097       56002 :                 if (error)
    2098          10 :                         goto out_trans;
    2099       55992 :                 cur = xfs_refcountbt_init_cursor(mp, tp, agbp, pag);
    2100             :         }
    2101             : 
    2102             :         /* Find all the leftover CoW staging extents. */
    2103       62317 :         error = xfs_btree_query_range(cur, &low, &high,
    2104             :                         xfs_refcount_recover_extent, &debris);
    2105       62317 :         xfs_btree_del_cursor(cur, error);
    2106       62317 :         if (agbp)
    2107       55992 :                 xfs_trans_brelse(tp, agbp);
    2108             :         else
    2109        6325 :                 xfs_rtgroup_unlock(rtg, XFS_RTGLOCK_REFCOUNT);
    2110       62317 :         xfs_trans_cancel(tp);
    2111       62317 :         if (error)
    2112          20 :                 goto out_free;
    2113             : 
    2114             :         /* Now iterate the list to free the leftovers */
    2115      372714 :         list_for_each_entry_safe(rr, n, &debris, rr_list) {
    2116             :                 /* Set up transaction. */
    2117      310417 :                 error = xfs_trans_alloc(mp, &M_RES(mp)->tr_write, 0, 0, 0, &tp);
    2118      310417 :                 if (error)
    2119           0 :                         goto out_free;
    2120             : 
    2121             :                 /* Free the orphan record */
    2122      310417 :                 if (rtg)
    2123         857 :                         fsb = xfs_rgbno_to_rtb(mp, rtg->rtg_rgno,
    2124             :                                         rr->rr_rrec.rc_startblock);
    2125             :                 else
    2126      309560 :                         fsb = XFS_AGB_TO_FSB(mp, pag->pag_agno,
    2127             :                                         rr->rr_rrec.rc_startblock);
    2128      310417 :                 xfs_refcount_free_cow_extent(tp, rtg != NULL, fsb,
    2129             :                                 rr->rr_rrec.rc_blockcount);
    2130             : 
    2131             :                 /* Free the block. */
    2132      310417 :                 error = xfs_free_extent_later(tp, fsb,
    2133      310417 :                                 rr->rr_rrec.rc_blockcount, NULL,
    2134             :                                 XFS_AG_RESV_NONE,
    2135             :                                 rtg != NULL ? XFS_FREE_EXTENT_REALTIME : 0);
    2136      310417 :                 if (error)
    2137           0 :                         goto out_trans;
    2138             : 
    2139      310417 :                 error = xfs_trans_commit(tp);
    2140      310417 :                 if (error)
    2141           0 :                         goto out_free;
    2142             : 
    2143      310417 :                 list_del(&rr->rr_list);
    2144      310417 :                 kfree(rr);
    2145             :         }
    2146             : 
    2147             :         return error;
    2148          10 : out_trans:
    2149          10 :         xfs_trans_cancel(tp);
    2150          30 : out_free:
    2151             :         /* Free the leftover list */
    2152          30 :         list_for_each_entry_safe(rr, n, &debris, rr_list) {
    2153           0 :                 list_del(&rr->rr_list);
    2154           0 :                 kfree(rr);
    2155             :         }
    2156             :         return error;
    2157             : }
    2158             : 
    2159             : int
    2160       56002 : xfs_refcount_recover_cow_leftovers(
    2161             :         struct xfs_mount                *mp,
    2162             :         struct xfs_perag                *pag)
    2163             : {
    2164       56002 :         return xfs_refcount_recover_group_cow_leftovers(mp, pag, NULL);
    2165             : }
    2166             : 
    2167             : int
    2168        6325 : xfs_refcount_recover_rtcow_leftovers(
    2169             :         struct xfs_mount                *mp,
    2170             :         struct xfs_rtgroup              *rtg)
    2171             : {
    2172        6325 :         return xfs_refcount_recover_group_cow_leftovers(mp, NULL, rtg);
    2173             : }
    2174             : 
    2175             : /*
    2176             :  * Scan part of the keyspace of the refcount records and tell us if the area
    2177             :  * has no records, is fully mapped by records, or is partially filled.
    2178             :  */
    2179             : int
    2180  3022608338 : xfs_refcount_has_records(
    2181             :         struct xfs_btree_cur    *cur,
    2182             :         enum xfs_refc_domain    domain,
    2183             :         xfs_agblock_t           bno,
    2184             :         xfs_extlen_t            len,
    2185             :         enum xbtree_recpacking  *outcome)
    2186             : {
    2187  3022608338 :         union xfs_btree_irec    low;
    2188  3022608338 :         union xfs_btree_irec    high;
    2189             : 
    2190  3022608338 :         memset(&low, 0, sizeof(low));
    2191  3022608338 :         low.rc.rc_startblock = bno;
    2192  3022608338 :         memset(&high, 0xFF, sizeof(high));
    2193  3022608338 :         high.rc.rc_startblock = bno + len - 1;
    2194  3022608338 :         low.rc.rc_domain = high.rc.rc_domain = domain;
    2195             : 
    2196  3022608338 :         return xfs_btree_has_records(cur, &low, &high, NULL, outcome);
    2197             : }
    2198             : 
    2199             : struct xfs_refcount_query_range_info {
    2200             :         xfs_refcount_query_range_fn     fn;
    2201             :         void                            *priv;
    2202             : };
    2203             : 
    2204             : /* Format btree record and pass to our callback. */
    2205             : STATIC int
    2206      770736 : xfs_refcount_query_range_helper(
    2207             :         struct xfs_btree_cur            *cur,
    2208             :         const union xfs_btree_rec       *rec,
    2209             :         void                            *priv)
    2210             : {
    2211      770736 :         struct xfs_refcount_query_range_info    *query = priv;
    2212      770736 :         struct xfs_refcount_irec        irec;
    2213      770736 :         xfs_failaddr_t                  fa;
    2214             : 
    2215      770736 :         xfs_refcount_btrec_to_irec(rec, &irec);
    2216      770739 :         fa = xfs_refcount_check_irec(cur, &irec);
    2217      770722 :         if (fa)
    2218           0 :                 return xfs_refcount_complain_bad_rec(cur, fa, &irec);
    2219             : 
    2220      770722 :         return query->fn(cur, &irec, query->priv);
    2221             : }
    2222             : 
    2223             : /* Find all refcount records between two keys. */
    2224             : int
    2225       96704 : xfs_refcount_query_range(
    2226             :         struct xfs_btree_cur            *cur,
    2227             :         const struct xfs_refcount_irec  *low_rec,
    2228             :         const struct xfs_refcount_irec  *high_rec,
    2229             :         xfs_refcount_query_range_fn     fn,
    2230             :         void                            *priv)
    2231             : {
    2232       96704 :         union xfs_btree_irec            low_brec = { .rc = *low_rec };
    2233       96704 :         union xfs_btree_irec            high_brec = { .rc = *high_rec };
    2234       96704 :         struct xfs_refcount_query_range_info query = { .priv = priv, .fn = fn };
    2235             : 
    2236       96704 :         return xfs_btree_query_range(cur, &low_brec, &high_brec,
    2237             :                         xfs_refcount_query_range_helper, &query);
    2238             : }
    2239             : 
    2240             : int __init
    2241          59 : xfs_refcount_intent_init_cache(void)
    2242             : {
    2243          59 :         xfs_refcount_intent_cache = kmem_cache_create("xfs_refc_intent",
    2244             :                         sizeof(struct xfs_refcount_intent),
    2245             :                         0, 0, NULL);
    2246             : 
    2247          59 :         return xfs_refcount_intent_cache != NULL ? 0 : -ENOMEM;
    2248             : }
    2249             : 
    2250             : void
    2251          58 : xfs_refcount_intent_destroy_cache(void)
    2252             : {
    2253          58 :         kmem_cache_destroy(xfs_refcount_intent_cache);
    2254          58 :         xfs_refcount_intent_cache = NULL;
    2255          58 : }

Generated by: LCOV version 1.14