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-xfsa @ Mon Jul 31 20:08:27 PDT 2023 Lines: 743 955 77.8 %
Date: 2023-07-31 20:08:27 Functions: 46 48 95.8 %

          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     8443076 :         if (cur->bc_btnum == XFS_BTNUM_RTREFC)
      52     1101594 :                 return cur->bc_mp->m_sb.sb_rgblocks;
      53     7341497 :         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  2917616436 : 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  2931393680 :         trace_xfs_refcount_lookup(cur,
      68             :                         xfs_refcount_encode_startblock(bno, domain),
      69             :                         XFS_LOOKUP_LE);
      70  2917641774 :         cur->bc_rec.rc.rc_startblock = bno;
      71  2917641774 :         cur->bc_rec.rc.rc_blockcount = 0;
      72  2917641774 :         cur->bc_rec.rc.rc_domain = domain;
      73  2917641774 :         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   330521971 : 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   342993110 :         trace_xfs_refcount_lookup(cur,
      88             :                         xfs_refcount_encode_startblock(bno, domain),
      89             :                         XFS_LOOKUP_GE);
      90   330522035 :         cur->bc_rec.rc.rc_startblock = bno;
      91   330522035 :         cur->bc_rec.rc.rc_blockcount = 0;
      92   330522035 :         cur->bc_rec.rc.rc_domain = domain;
      93   330522035 :         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  4261573877 : xfs_refcount_btrec_to_irec(
     119             :         const union xfs_btree_rec       *rec,
     120             :         struct xfs_refcount_irec        *irec)
     121             : {
     122  4261573877 :         uint32_t                        start;
     123             : 
     124  4261573877 :         start = be32_to_cpu(rec->refc.rc_startblock);
     125  4261573877 :         if (start & XFS_REFC_COWFLAG) {
     126    77825203 :                 start &= ~XFS_REFC_COWFLAG;
     127    77825203 :                 irec->rc_domain = XFS_REFC_DOMAIN_COW;
     128             :         } else {
     129  4183748674 :                 irec->rc_domain = XFS_REFC_DOMAIN_SHARED;
     130             :         }
     131             : 
     132  4261573877 :         irec->rc_startblock = start;
     133  4261573877 :         irec->rc_blockcount = be32_to_cpu(rec->refc.rc_blockcount);
     134  4261573877 :         irec->rc_refcount = be32_to_cpu(rec->refc.rc_refcount);
     135  4261573877 : }
     136             : 
     137             : inline xfs_failaddr_t
     138  2868950555 : xfs_refcount_check_perag_irec(
     139             :         struct xfs_perag                *pag,
     140             :         const struct xfs_refcount_irec  *irec)
     141             : {
     142  2868950555 :         if (irec->rc_blockcount == 0 || irec->rc_blockcount > XFS_REFC_LEN_MAX)
     143           0 :                 return __this_address;
     144             : 
     145  2868950555 :         if (!xfs_refcount_check_domain(irec))
     146           0 :                 return __this_address;
     147             : 
     148             :         /* check for valid extent range, including overflow */
     149  2868950555 :         if (!xfs_verify_agbext(pag, irec->rc_startblock, irec->rc_blockcount))
     150           4 :                 return __this_address;
     151             : 
     152  2868950551 :         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  1399305083 : xfs_refcount_check_rtgroup_irec(
     160             :         struct xfs_rtgroup              *rtg,
     161             :         const struct xfs_refcount_irec  *irec)
     162             : {
     163  1399305083 :         if (irec->rc_blockcount == 0 || irec->rc_blockcount > XFS_REFC_LEN_MAX)
     164           0 :                 return __this_address;
     165             : 
     166  1399305083 :         if (!xfs_refcount_check_domain(irec))
     167           0 :                 return __this_address;
     168             : 
     169             :         /* check for valid extent range, including overflow */
     170  1399305083 :         if (!xfs_verify_rgbext(rtg, irec->rc_startblock, irec->rc_blockcount))
     171           0 :                 return __this_address;
     172             : 
     173  1399305083 :         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  4261599341 : xfs_refcount_check_irec(
     182             :         struct xfs_btree_cur            *cur,
     183             :         const struct xfs_refcount_irec  *irec)
     184             : {
     185  4261599341 :         if (cur->bc_btnum == XFS_BTNUM_RTREFC)
     186  1394118913 :                 return xfs_refcount_check_rtgroup_irec(cur->bc_ino.rtg, irec);
     187  2867480428 :         return xfs_refcount_check_perag_irec(cur->bc_ag.pag, irec);
     188             : }
     189             : 
     190             : static inline int
     191           4 : 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           4 :         struct xfs_mount                *mp = cur->bc_mp;
     197             : 
     198           4 :         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           4 :                 xfs_warn(mp,
     204             :  "Refcount BTree record corruption in AG %d detected at %pS!",
     205             :                                 cur->bc_ag.pag->pag_agno, fa);
     206             :         }
     207           4 :         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           4 :         xfs_btree_mark_sick(cur);
     211           4 :         return -EFSCORRUPTED;
     212             : }
     213             : 
     214             : /*
     215             :  * Get the data from the pointed-to record.
     216             :  */
     217             : int
     218  4203422066 : xfs_refcount_get_rec(
     219             :         struct xfs_btree_cur            *cur,
     220             :         struct xfs_refcount_irec        *irec,
     221             :         int                             *stat)
     222             : {
     223  4203422066 :         union xfs_btree_rec             *rec;
     224  4203422066 :         xfs_failaddr_t                  fa;
     225  4203422066 :         int                             error;
     226             : 
     227  4203422066 :         error = xfs_btree_get_rec(cur, &rec, stat);
     228  4203589369 :         if (error || !*stat)
     229             :                 return error;
     230             : 
     231  4197133689 :         xfs_refcount_btrec_to_irec(rec, irec);
     232  4197215383 :         fa = xfs_refcount_check_irec(cur, irec);
     233  4197312740 :         if (fa)
     234           4 :                 return xfs_refcount_complain_bad_rec(cur, fa, irec);
     235             : 
     236  4197312736 :         trace_xfs_refcount_get(cur, irec);
     237  4197312736 :         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   103010665 : xfs_refcount_update(
     247             :         struct xfs_btree_cur            *cur,
     248             :         struct xfs_refcount_irec        *irec)
     249             : {
     250   103010665 :         union xfs_btree_rec     rec;
     251   103010665 :         uint32_t                start;
     252   103010665 :         int                     error;
     253             : 
     254   103010665 :         trace_xfs_refcount_update(cur, irec);
     255             : 
     256   103010746 :         start = xfs_refcount_encode_startblock(irec->rc_startblock,
     257             :                         irec->rc_domain);
     258   103010746 :         rec.refc.rc_startblock = cpu_to_be32(start);
     259   103010746 :         rec.refc.rc_blockcount = cpu_to_be32(irec->rc_blockcount);
     260   103010746 :         rec.refc.rc_refcount = cpu_to_be32(irec->rc_refcount);
     261             : 
     262   103010746 :         error = xfs_btree_update(cur, &rec);
     263   103010785 :         if (error)
     264           0 :                 trace_xfs_refcount_update_error(cur, error, _RET_IP_);
     265   103010785 :         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    50117641 : xfs_refcount_insert(
     275             :         struct xfs_btree_cur            *cur,
     276             :         struct xfs_refcount_irec        *irec,
     277             :         int                             *i)
     278             : {
     279    50117641 :         int                             error;
     280             : 
     281    50117641 :         trace_xfs_refcount_insert(cur, irec);
     282             : 
     283    50117640 :         cur->bc_rec.rc.rc_startblock = irec->rc_startblock;
     284    50117640 :         cur->bc_rec.rc.rc_blockcount = irec->rc_blockcount;
     285    50117640 :         cur->bc_rec.rc.rc_refcount = irec->rc_refcount;
     286    50117640 :         cur->bc_rec.rc.rc_domain = irec->rc_domain;
     287             : 
     288    50117640 :         error = xfs_btree_insert(cur, i);
     289    50117640 :         if (error)
     290          57 :                 goto out_error;
     291    50117583 :         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    50117640 : out_error:
     298    50117640 :         if (error)
     299          57 :                 trace_xfs_refcount_insert_error(cur, error, _RET_IP_);
     300    50117640 :         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    47099615 : xfs_refcount_delete(
     311             :         struct xfs_btree_cur    *cur,
     312             :         int                     *i)
     313             : {
     314    47099615 :         struct xfs_refcount_irec        irec;
     315    47099615 :         int                     found_rec;
     316    47099615 :         int                     error;
     317             : 
     318    47099615 :         error = xfs_refcount_get_rec(cur, &irec, &found_rec);
     319    47099610 :         if (error)
     320           0 :                 goto out_error;
     321    47099610 :         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    47099610 :         trace_xfs_refcount_delete(cur, &irec);
     327    47099610 :         error = xfs_btree_delete(cur, i);
     328    47099608 :         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    47099608 :         if (error)
     334           0 :                 goto out_error;
     335    47099608 :         error = xfs_refcount_lookup_ge(cur, irec.rc_domain, irec.rc_startblock,
     336             :                         &found_rec);
     337    47099614 : out_error:
     338    47099614 :         if (error)
     339           0 :                 trace_xfs_refcount_delete_error(cur, error, _RET_IP_);
     340    47099614 :         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   359673452 :         return rc->rc_startblock + rc->rc_blockcount;
     426             : }
     427             : 
     428             : /*
     429             :  * Split a refcount extent that crosses agbno.
     430             :  */
     431             : STATIC int
     432   291802318 : 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   291802318 :         struct xfs_refcount_irec        rcext, tmp;
     439   291802318 :         int                             found_rec;
     440   291802318 :         int                             error;
     441             : 
     442   291802318 :         *shape_changed = false;
     443   291802318 :         error = xfs_refcount_lookup_le(cur, domain, agbno, &found_rec);
     444   291802964 :         if (error)
     445          80 :                 goto out_error;
     446   291802884 :         if (!found_rec)
     447             :                 return 0;
     448             : 
     449   285349440 :         error = xfs_refcount_get_rec(cur, &rcext, &found_rec);
     450   285349323 :         if (error)
     451           0 :                 goto out_error;
     452   285349323 :         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   285349323 :         if (rcext.rc_domain != domain)
     458             :                 return 0;
     459   285104290 :         if (rcext.rc_startblock == agbno || xfs_refc_next(&rcext) <= agbno)
     460             :                 return 0;
     461             : 
     462    23803213 :         *shape_changed = true;
     463    23803213 :         trace_xfs_refcount_split_extent(cur, &rcext, agbno);
     464             : 
     465             :         /* Establish the right extent. */
     466    23803213 :         tmp = rcext;
     467    23803213 :         tmp.rc_startblock = agbno;
     468    23803213 :         tmp.rc_blockcount -= (agbno - rcext.rc_startblock);
     469    23803213 :         error = xfs_refcount_update(cur, &tmp);
     470    23803212 :         if (error)
     471           0 :                 goto out_error;
     472             : 
     473             :         /* Insert the left extent. */
     474    23803212 :         tmp = rcext;
     475    23803212 :         tmp.rc_blockcount = agbno - rcext.rc_startblock;
     476    23803212 :         error = xfs_refcount_insert(cur, &tmp, &found_rec);
     477    23803213 :         if (error)
     478          12 :                 goto out_error;
     479    23803201 :         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          92 : out_error:
     487          92 :         trace_xfs_refcount_split_extent_error(cur, error, _RET_IP_);
     488          92 :         return error;
     489             : }
     490             : 
     491             : /*
     492             :  * Merge the left, center, and right extents.
     493             :  */
     494             : STATIC int
     495     2194664 : 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     2194664 :         int                             error;
     504     2194664 :         int                             found_rec;
     505             : 
     506     2194664 :         trace_xfs_refcount_merge_center_extents(cur, left, center, right);
     507             : 
     508     2194664 :         ASSERT(left->rc_domain == center->rc_domain);
     509     2194664 :         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     2194664 :         error = xfs_refcount_lookup_ge(cur, center->rc_domain,
     520             :                         center->rc_startblock, &found_rec);
     521     2194664 :         if (error)
     522           0 :                 goto out_error;
     523     2194664 :         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     2194664 :         error = xfs_refcount_delete(cur, &found_rec);
     530     2194664 :         if (error)
     531           0 :                 goto out_error;
     532     2194664 :         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     2194664 :         if (center->rc_refcount > 1) {
     539      530423 :                 error = xfs_refcount_delete(cur, &found_rec);
     540      530423 :                 if (error)
     541           0 :                         goto out_error;
     542      530423 :                 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     2194664 :         error = xfs_refcount_lookup_le(cur, left->rc_domain,
     551             :                         left->rc_startblock, &found_rec);
     552     2194664 :         if (error)
     553           0 :                 goto out_error;
     554     2194664 :         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     2194664 :         left->rc_blockcount = extlen;
     561     2194664 :         error = xfs_refcount_update(cur, left);
     562     2194664 :         if (error)
     563           0 :                 goto out_error;
     564             : 
     565     2194664 :         *aglen = 0;
     566     2194664 :         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     6697492 : 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     6697492 :         int                             error;
     585     6697492 :         int                             found_rec;
     586             : 
     587     6697492 :         trace_xfs_refcount_merge_left_extent(cur, left, cleft);
     588             : 
     589     6697490 :         ASSERT(left->rc_domain == cleft->rc_domain);
     590             : 
     591             :         /* If the extent at agbno (cleft) wasn't synthesized, remove it. */
     592     6697490 :         if (cleft->rc_refcount > 1) {
     593     2136490 :                 error = xfs_refcount_lookup_le(cur, cleft->rc_domain,
     594             :                                 cleft->rc_startblock, &found_rec);
     595     2136490 :                 if (error)
     596           0 :                         goto out_error;
     597     2136490 :                 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     2136490 :                 error = xfs_refcount_delete(cur, &found_rec);
     604     2136490 :                 if (error)
     605           0 :                         goto out_error;
     606     2136490 :                 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     6697490 :         error = xfs_refcount_lookup_le(cur, left->rc_domain,
     615             :                         left->rc_startblock, &found_rec);
     616     6697491 :         if (error)
     617           0 :                 goto out_error;
     618     6697491 :         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     6697491 :         left->rc_blockcount += cleft->rc_blockcount;
     625     6697491 :         error = xfs_refcount_update(cur, left);
     626     6697489 :         if (error)
     627           0 :                 goto out_error;
     628             : 
     629     6697489 :         *agbno += cleft->rc_blockcount;
     630     6697489 :         *aglen -= cleft->rc_blockcount;
     631     6697489 :         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     4243250 : 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     4243250 :         int                             error;
     649     4243250 :         int                             found_rec;
     650             : 
     651     4243250 :         trace_xfs_refcount_merge_right_extent(cur, cright, right);
     652             : 
     653     4243250 :         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     4243250 :         if (cright->rc_refcount > 1) {
     660     1891080 :                 error = xfs_refcount_lookup_le(cur, cright->rc_domain,
     661             :                                 cright->rc_startblock, &found_rec);
     662     1891079 :                 if (error)
     663           0 :                         goto out_error;
     664     1891079 :                 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     1891079 :                 error = xfs_refcount_delete(cur, &found_rec);
     671     1891080 :                 if (error)
     672           0 :                         goto out_error;
     673     1891080 :                 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     4243250 :         error = xfs_refcount_lookup_le(cur, right->rc_domain,
     682             :                         right->rc_startblock, &found_rec);
     683     4243250 :         if (error)
     684           0 :                 goto out_error;
     685     4243250 :         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     4243250 :         right->rc_startblock -= cright->rc_blockcount;
     692     4243250 :         right->rc_blockcount += cright->rc_blockcount;
     693     4243250 :         error = xfs_refcount_update(cur, right);
     694     4243250 :         if (error)
     695           0 :                 goto out_error;
     696             : 
     697     4243250 :         *aglen -= cright->rc_blockcount;
     698     4243250 :         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   145901343 : 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   145901343 :         struct xfs_refcount_irec        tmp;
     719   145901343 :         int                             error;
     720   145901343 :         int                             found_rec;
     721             : 
     722   145901343 :         left->rc_startblock = cleft->rc_startblock = NULLAGBLOCK;
     723   145901343 :         error = xfs_refcount_lookup_le(cur, domain, agbno - 1, &found_rec);
     724   145901363 :         if (error)
     725           0 :                 goto out_error;
     726   145901363 :         if (!found_rec)
     727             :                 return 0;
     728             : 
     729   134232940 :         error = xfs_refcount_get_rec(cur, &tmp, &found_rec);
     730   134232930 :         if (error)
     731           0 :                 goto out_error;
     732   134232930 :         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   134232930 :         if (tmp.rc_domain != domain)
     739             :                 return 0;
     740   133529218 :         if (xfs_refc_next(&tmp) != agbno)
     741             :                 return 0;
     742             :         /* We have a left extent; retrieve (or invent) the next right one */
     743    25410933 :         *left = tmp;
     744             : 
     745    25410933 :         error = xfs_btree_increment(cur, 0, &found_rec);
     746    25410932 :         if (error)
     747           0 :                 goto out_error;
     748    25410932 :         if (found_rec) {
     749    25215815 :                 error = xfs_refcount_get_rec(cur, &tmp, &found_rec);
     750    25215813 :                 if (error)
     751           0 :                         goto out_error;
     752    25215813 :                 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    25215813 :                 if (tmp.rc_domain != domain)
     759       25801 :                         goto not_found;
     760             : 
     761             :                 /* if tmp starts at the end of our range, just use that */
     762    25190012 :                 if (tmp.rc_startblock == agbno)
     763    18935179 :                         *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     6254833 :                         cleft->rc_startblock = agbno;
     774     6254833 :                         cleft->rc_blockcount = min(aglen,
     775             :                                         tmp.rc_startblock - agbno);
     776     6254833 :                         cleft->rc_refcount = 1;
     777     6254833 :                         cleft->rc_domain = domain;
     778             :                 }
     779             :         } else {
     780      195117 : not_found:
     781             :                 /*
     782             :                  * No extents, so pretend that there's one covering the whole
     783             :                  * range.
     784             :                  */
     785      220918 :                 cleft->rc_startblock = agbno;
     786      220918 :                 cleft->rc_blockcount = aglen;
     787      220918 :                 cleft->rc_refcount = 1;
     788      220918 :                 cleft->rc_domain = domain;
     789             :         }
     790    25410930 :         trace_xfs_refcount_find_left_extent(cur, left, cleft, agbno);
     791    25410930 :         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   145901303 : 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   145901303 :         struct xfs_refcount_irec        tmp;
     812   145901303 :         int                             error;
     813   145901303 :         int                             found_rec;
     814             : 
     815   145901303 :         right->rc_startblock = cright->rc_startblock = NULLAGBLOCK;
     816   145901303 :         error = xfs_refcount_lookup_ge(cur, domain, agbno + aglen, &found_rec);
     817   145901494 :         if (error)
     818           0 :                 goto out_error;
     819   145901494 :         if (!found_rec)
     820             :                 return 0;
     821             : 
     822   131038792 :         error = xfs_refcount_get_rec(cur, &tmp, &found_rec);
     823   131038807 :         if (error)
     824           4 :                 goto out_error;
     825   131038803 :         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   131038803 :         if (tmp.rc_domain != domain)
     832             :                 return 0;
     833   128777230 :         if (tmp.rc_startblock != agbno + aglen)
     834             :                 return 0;
     835             :         /* We have a right extent; retrieve (or invent) the next left one */
     836    23287633 :         *right = tmp;
     837             : 
     838    23287633 :         error = xfs_btree_decrement(cur, 0, &found_rec);
     839    23287635 :         if (error)
     840           0 :                 goto out_error;
     841    23287635 :         if (found_rec) {
     842    23266354 :                 error = xfs_refcount_get_rec(cur, &tmp, &found_rec);
     843    23266351 :                 if (error)
     844           0 :                         goto out_error;
     845    23266351 :                 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    23266351 :                 if (tmp.rc_domain != domain)
     852         373 :                         goto not_found;
     853             : 
     854             :                 /* if tmp ends at the end of our range, just use that */
     855    23265978 :                 if (xfs_refc_next(&tmp) == agbno + aglen)
     856    19055748 :                         *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     4210230 :                         cright->rc_startblock = max(agbno, xfs_refc_next(&tmp));
     867     4210230 :                         cright->rc_blockcount = right->rc_startblock -
     868             :                                         cright->rc_startblock;
     869     4210230 :                         cright->rc_refcount = 1;
     870     4210230 :                         cright->rc_domain = domain;
     871             :                 }
     872             :         } else {
     873       21281 : not_found:
     874             :                 /*
     875             :                  * No extents, so pretend that there's one covering the whole
     876             :                  * range.
     877             :                  */
     878       21654 :                 cright->rc_startblock = agbno;
     879       21654 :                 cright->rc_blockcount = aglen;
     880       21654 :                 cright->rc_refcount = 1;
     881       21654 :                 cright->rc_domain = domain;
     882             :         }
     883    23287632 :         trace_xfs_refcount_find_right_extent(cur, cright, right,
     884             :                         agbno + aglen);
     885    23287632 :         return error;
     886             : 
     887           4 : out_error:
     888           4 :         trace_xfs_refcount_find_right_extent_error(cur, error, _RET_IP_);
     889           4 :         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   465779570 :         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    53505921 :         if (irec->rc_refcount == XFS_REFC_REFCOUNT_MAX)
     907             :                 return XFS_REFC_REFCOUNT_MAX;
     908    53505911 :         return irec->rc_refcount + adjust;
     909             : }
     910             : 
     911             : static inline bool
     912    37858152 : 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    37858152 :         unsigned long long              ulen = left->rc_blockcount;
     922    37858152 :         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    37858152 :         if (!xfs_refc_valid(left)  || !xfs_refc_valid(right) ||
     930    10840417 :             !xfs_refc_valid(cleft) || !xfs_refc_valid(cright))
     931             :                 return false;
     932             : 
     933             :         /* There must only be one record for the entire range. */
     934    10840417 :         if (!cleft_is_cright)
     935             :                 return false;
     936             : 
     937             :         /* The shoulder record refcounts must match the new refcount. */
     938     9795975 :         new_refcount = xfs_refc_merge_refcount(cleft, adjust);
     939     9795975 :         if (left->rc_refcount != new_refcount)
     940             :                 return false;
     941     2793953 :         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     2194664 :         ulen += cleft->rc_blockcount + right->rc_blockcount;
     950     2194664 :         if (ulen >= XFS_REFC_LEN_MAX)
     951             :                 return false;
     952             : 
     953     2194664 :         *ulenp = ulen;
     954     2194664 :         return true;
     955             : }
     956             : 
     957             : static inline bool
     958    35663482 : 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    35663482 :         unsigned long long              ulen = left->rc_blockcount;
     964    35663482 :         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    35663482 :         if (!xfs_refc_valid(left) || !xfs_refc_valid(cleft))
     972             :                 return false;
     973             : 
     974             :         /* Left shoulder record refcount must match the new refcount. */
     975    23216262 :         new_refcount = xfs_refc_merge_refcount(cleft, adjust);
     976    23216262 :         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     6697492 :         ulen += cleft->rc_blockcount;
     985     6697492 :         if (ulen >= XFS_REFC_LEN_MAX)
     986           0 :                 return false;
     987             : 
     988             :         return true;
     989             : }
     990             : 
     991             : static inline bool
     992    35064196 : 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    35064196 :         unsigned long long              ulen = right->rc_blockcount;
     998    35064196 :         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    35064196 :         if (!xfs_refc_valid(right) || !xfs_refc_valid(cright))
    1006             :                 return false;
    1007             : 
    1008             :         /* Right shoulder record refcount must match the new refcount. */
    1009    20493684 :         new_refcount = xfs_refc_merge_refcount(cright, adjust);
    1010    20493684 :         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     4243250 :         ulen += cright->rc_blockcount;
    1019     4243250 :         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   145901259 : 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   145901259 :         struct xfs_refcount_irec        left = {0}, cleft = {0};
    1038   145901259 :         struct xfs_refcount_irec        cright = {0}, right = {0};
    1039   145901259 :         int                             error;
    1040   145901259 :         unsigned long long              ulen;
    1041   145901259 :         bool                            cequal;
    1042             : 
    1043   145901259 :         *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   145901259 :         error = xfs_refcount_find_left_extents(cur, &left, &cleft, domain,
    1050             :                         *agbno, *aglen);
    1051   145901476 :         if (error)
    1052             :                 return error;
    1053   145901492 :         error = xfs_refcount_find_right_extents(cur, &right, &cright, domain,
    1054             :                         *agbno, *aglen);
    1055   145901487 :         if (error)
    1056             :                 return error;
    1057             : 
    1058             :         /* No left or right extent to merge; exit. */
    1059   145901483 :         if (!xfs_refc_valid(&left) && !xfs_refc_valid(&right))
    1060             :                 return 0;
    1061             : 
    1062    37858146 :         cequal = (cleft.rc_startblock == cright.rc_startblock) &&
    1063     9795975 :                  (cleft.rc_blockcount == cright.rc_blockcount);
    1064             : 
    1065             :         /* Try to merge left, cleft, and right.  cleft must == cright. */
    1066    37858146 :         if (xfs_refc_want_merge_center(&left, &cleft, &cright, &right, cequal,
    1067             :                                 adjust, &ulen)) {
    1068     2194664 :                 *shape_changed = true;
    1069     2194664 :                 return xfs_refcount_merge_center_extents(cur, &left, &cleft,
    1070             :                                 &right, ulen, aglen);
    1071             :         }
    1072             : 
    1073             :         /* Try to merge left and cleft. */
    1074    35663480 :         if (xfs_refc_want_merge_left(&left, &cleft, adjust)) {
    1075     6697490 :                 *shape_changed = true;
    1076     6697490 :                 error = xfs_refcount_merge_left_extent(cur, &left, &cleft,
    1077             :                                 agbno, aglen);
    1078     6697489 :                 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     6697489 :                 if (cequal)
    1086             :                         return 0;
    1087             :         }
    1088             : 
    1089             :         /* Try to merge cright and right. */
    1090    35064190 :         if (xfs_refc_want_merge_right(&cright, &right, adjust)) {
    1091     4243250 :                 *shape_changed = true;
    1092     4243250 :                 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   954962068 :         if (cur->bc_btnum == XFS_BTNUM_RTREFC)
    1104   218523015 :                 return &cur->bc_ino.refc;
    1105   736439053 :         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   158969841 : xfs_refcount_still_have_space(
    1116             :         struct xfs_btree_cur            *cur)
    1117             : {
    1118   158969841 :         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   317939682 :         overhead = xfs_allocfree_block_count(cur->bc_mp,
    1125             :                                 xrefc_btree_state(cur)->shape_changes);
    1126   158970019 :         overhead += cur->bc_maxlevels;
    1127   158970019 :         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   338367192 :         if (xrefc_btree_state(cur)->nr_ops > 2 &&
    1134    20427154 :             XFS_TEST_ERROR(false, cur->bc_mp,
    1135             :                         XFS_ERRTAG_REFCOUNT_CONTINUE_UPDATE))
    1136             :                 return false;
    1137             : 
    1138   317939870 :         if (xrefc_btree_state(cur)->nr_ops == 0)
    1139             :                 return true;
    1140    30826299 :         else if (overhead > cur->bc_tp->t_log_res)
    1141             :                 return false;
    1142    30826299 :         return  cur->bc_tp->t_log_res - overhead >
    1143    30826299 :                 xrefc_btree_state(cur)->nr_ops * XFS_REFCOUNT_ITEM_OVERHEAD;
    1144             : }
    1145             : 
    1146             : /* Schedule an extent free. */
    1147             : static int
    1148    30517705 : xrefc_free_extent(
    1149             :         struct xfs_btree_cur            *cur,
    1150             :         struct xfs_refcount_irec        *rec)
    1151             : {
    1152    30517705 :         xfs_fsblock_t                   fsbno;
    1153    30517705 :         unsigned int                    flags = 0;
    1154             : 
    1155    30517705 :         if (cur->bc_btnum == XFS_BTNUM_RTREFC) {
    1156    13709715 :                 flags |= XFS_FREE_EXTENT_REALTIME;
    1157    13709715 :                 fsbno = xfs_rgbno_to_rtb(cur->bc_mp, cur->bc_ino.rtg->rtg_rgno,
    1158             :                                 rec->rc_startblock);
    1159             :         } else {
    1160    16807990 :                 fsbno = XFS_AGB_TO_FSB(cur->bc_mp, cur->bc_ag.pag->pag_agno,
    1161             :                                 rec->rc_startblock);
    1162             :         }
    1163             : 
    1164    30517714 :         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   141474560 : 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   141474560 :         struct xfs_refcount_irec        ext, tmp;
    1182   141474560 :         int                             error;
    1183   141474560 :         int                             found_rec, found_tmp;
    1184             : 
    1185             :         /* Merging did all the work already. */
    1186   141474560 :         if (*aglen == 0)
    1187             :                 return 0;
    1188             : 
    1189   128767141 :         error = xfs_refcount_lookup_ge(cur, XFS_REFC_DOMAIN_SHARED, *agbno,
    1190             :                         &found_rec);
    1191   128767203 :         if (error)
    1192           0 :                 goto out_error;
    1193             : 
    1194   231429862 :         while (*aglen > 0 && xfs_refcount_still_have_space(cur)) {
    1195   156691461 :                 error = xfs_refcount_get_rec(cur, &ext, &found_rec);
    1196   156691675 :                 if (error)
    1197           0 :                         goto out_error;
    1198   156691675 :                 if (!found_rec || ext.rc_domain != XFS_REFC_DOMAIN_SHARED) {
    1199     8248223 :                         ext.rc_startblock = xrefc_max_startblock(cur);
    1200     8248223 :                         ext.rc_blockcount = 0;
    1201     8248223 :                         ext.rc_refcount = 0;
    1202     8248223 :                         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   156691675 :                 if (ext.rc_startblock != *agbno) {
    1211    56306912 :                         tmp.rc_startblock = *agbno;
    1212    56306912 :                         tmp.rc_blockcount = min(*aglen,
    1213             :                                         ext.rc_startblock - *agbno);
    1214    56306912 :                         tmp.rc_refcount = 1 + adj;
    1215    56306912 :                         tmp.rc_domain = XFS_REFC_DOMAIN_SHARED;
    1216             : 
    1217    56306912 :                         trace_xfs_refcount_modify_extent(cur, &tmp);
    1218             : 
    1219             :                         /*
    1220             :                          * Either cover the hole (increment) or
    1221             :                          * delete the range (decrement).
    1222             :                          */
    1223    56306966 :                         xrefc_btree_state(cur)->nr_ops++;
    1224    56306966 :                         if (tmp.rc_refcount) {
    1225    25789251 :                                 error = xfs_refcount_insert(cur, &tmp,
    1226             :                                                 &found_tmp);
    1227    25789252 :                                 if (error)
    1228          45 :                                         goto out_error;
    1229    25789207 :                                 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    30517715 :                                 error = xrefc_free_extent(cur, &tmp);
    1237    30517701 :                                 if (error)
    1238           0 :                                         goto out_error;
    1239             :                         }
    1240             : 
    1241    56306908 :                         (*agbno) += tmp.rc_blockcount;
    1242    56306908 :                         (*aglen) -= tmp.rc_blockcount;
    1243             : 
    1244             :                         /* Stop if there's nothing left to modify */
    1245    56306908 :                         if (*aglen == 0 || !xfs_refcount_still_have_space(cur))
    1246             :                                 break;
    1247             : 
    1248             :                         /* Move the cursor to the start of ext. */
    1249     2277863 :                         error = xfs_refcount_lookup_ge(cur,
    1250             :                                         XFS_REFC_DOMAIN_SHARED, *agbno,
    1251             :                                         &found_rec);
    1252     2277863 :                         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   102662626 :                 if (XFS_IS_CORRUPT(cur->bc_mp, ext.rc_blockcount == 0) ||
    1264   102662626 :                     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   102662626 :                 if (ext.rc_refcount == XFS_REFC_REFCOUNT_MAX)
    1275          16 :                         goto skip;
    1276   102662610 :                 ext.rc_refcount += adj;
    1277   102662610 :                 trace_xfs_refcount_modify_extent(cur, &ext);
    1278   102662638 :                 xrefc_btree_state(cur)->nr_ops++;
    1279   102662638 :                 if (ext.rc_refcount > 1) {
    1280    66072190 :                         error = xfs_refcount_update(cur, &ext);
    1281    66072176 :                         if (error)
    1282           0 :                                 goto out_error;
    1283    36590448 :                 } else if (ext.rc_refcount == 1) {
    1284    36590448 :                         error = xfs_refcount_delete(cur, &found_rec);
    1285    36590448 :                         if (error)
    1286           0 :                                 goto out_error;
    1287    36590448 :                         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    36590448 :                         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    66072192 :                 error = xfs_btree_increment(cur, 0, &found_rec);
    1301    66072211 :                 if (error)
    1302           0 :                         goto out_error;
    1303             : 
    1304    66072211 : advloop:
    1305   102662659 :                 (*agbno) += ext.rc_blockcount;
    1306   102662659 :                 (*aglen) -= ext.rc_blockcount;
    1307             :         }
    1308             : 
    1309             :         return error;
    1310          45 : out_error:
    1311          45 :         trace_xfs_refcount_modify_extent_error(cur, error, _RET_IP_);
    1312          45 :         return error;
    1313             : }
    1314             : 
    1315             : /* Adjust the reference count of a range of AG blocks. */
    1316             : STATIC int
    1317   141474740 : 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   141474740 :         bool                    shape_changed;
    1324   141474740 :         int                     shape_changes = 0;
    1325   141474740 :         int                     error;
    1326             : 
    1327   141474740 :         if (adj == XFS_REFCOUNT_ADJUST_INCREASE)
    1328    61781298 :                 trace_xfs_refcount_increase(cur, *agbno, *aglen);
    1329             :         else
    1330    79693442 :                 trace_xfs_refcount_decrease(cur, *agbno, *aglen);
    1331             : 
    1332             :         /*
    1333             :          * Ensure that no rcextents cross the boundary of the adjustment range.
    1334             :          */
    1335   141474821 :         error = xfs_refcount_split_extent(cur, XFS_REFC_DOMAIN_SHARED,
    1336             :                         *agbno, &shape_changed);
    1337   141474759 :         if (error)
    1338          84 :                 goto out_error;
    1339   141474675 :         if (shape_changed)
    1340    10675335 :                 shape_changes++;
    1341             : 
    1342   141474675 :         error = xfs_refcount_split_extent(cur, XFS_REFC_DOMAIN_SHARED,
    1343   141474675 :                         *agbno + *aglen, &shape_changed);
    1344   141474735 :         if (error)
    1345           8 :                 goto out_error;
    1346   141474727 :         if (shape_changed)
    1347     9891980 :                 shape_changes++;
    1348             : 
    1349             :         /*
    1350             :          * Try to merge with the left or right extents of the range.
    1351             :          */
    1352   141474727 :         error = xfs_refcount_merge_extents(cur, XFS_REFC_DOMAIN_SHARED,
    1353             :                         agbno, aglen, adj, &shape_changed);
    1354   141474709 :         if (error)
    1355           4 :                 goto out_error;
    1356   141474705 :         if (shape_changed)
    1357    12982460 :                 shape_changes++;
    1358   141474705 :         if (shape_changes)
    1359    55993656 :                 xrefc_btree_state(cur)->shape_changes++;
    1360             : 
    1361             :         /* Now that we've taken care of the ends, adjust the middle extents */
    1362   141474705 :         error = xfs_refcount_adjust_extents(cur, agbno, aglen, adj);
    1363   141474581 :         if (error)
    1364          45 :                 goto out_error;
    1365             : 
    1366             :         return 0;
    1367             : 
    1368         141 : out_error:
    1369         141 :         trace_xfs_refcount_adjust_error(cur, error, _RET_IP_);
    1370         141 :         return error;
    1371             : }
    1372             : 
    1373             : /* Clean up after calling xfs_refcount_finish_one. */
    1374             : void
    1375   145348992 : xfs_refcount_finish_one_cleanup(
    1376             :         struct xfs_trans        *tp,
    1377             :         struct xfs_btree_cur    *rcur,
    1378             :         int                     error)
    1379             : {
    1380   145348992 :         struct xfs_buf          *agbp = NULL;
    1381             : 
    1382   145348992 :         if (rcur == NULL)
    1383             :                 return;
    1384   145348762 :         if (rcur->bc_btnum == XFS_BTNUM_REFC)
    1385   117142132 :                 agbp = rcur->bc_ag.agbp;
    1386   145348762 :         xfs_btree_del_cursor(rcur, error);
    1387   145348881 :         if (agbp)
    1388   117142139 :                 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      940809 :         if (cur->bc_btnum == XFS_BTNUM_RTREFC)
    1398      638995 :                 return cur->bc_ino.rtg != ri->ri_rtg;
    1399      301814 :         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         390 : xfs_refcount_continue_op(
    1408             :         struct xfs_btree_cur            *cur,
    1409             :         struct xfs_refcount_intent      *ri,
    1410             :         xfs_agblock_t                   new_agbno)
    1411             : {
    1412         390 :         struct xfs_mount                *mp = cur->bc_mp;
    1413             : 
    1414         390 :         if (ri->ri_realtime) {
    1415           0 :                 struct xfs_rtgroup      *rtg = ri->ri_rtg;
    1416             : 
    1417           0 :                 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           0 :                 ri->ri_startblock = xfs_rgbno_to_rtb(mp, rtg->rtg_rgno, new_agbno);
    1424             : 
    1425           0 :                 ASSERT(xfs_verify_rtbext(mp, ri->ri_startblock, ri->ri_blockcount));
    1426           0 :                 ASSERT(rtg->rtg_rgno == xfs_rtb_to_rgno(mp, ri->ri_startblock));
    1427             :         } else {
    1428         390 :                 struct xfs_perag                *pag = cur->bc_ag.pag;
    1429             : 
    1430         390 :                 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         390 :                 ri->ri_startblock = XFS_AGB_TO_FSB(mp, pag->pag_agno, new_agbno);
    1437             : 
    1438         390 :                 ASSERT(xfs_verify_fsbext(mp, ri->ri_startblock, ri->ri_blockcount));
    1439         390 :                 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   145901343 : xfs_refcount_finish_one(
    1454             :         struct xfs_trans                *tp,
    1455             :         struct xfs_refcount_intent      *ri,
    1456             :         struct xfs_btree_cur            **pcur)
    1457             : {
    1458   145901343 :         struct xfs_mount                *mp = tp->t_mountp;
    1459   145901343 :         struct xfs_btree_cur            *rcur;
    1460   145901343 :         struct xfs_buf                  *agbp = NULL;
    1461   145901343 :         int                             error = 0;
    1462   145901343 :         xfs_agblock_t                   bno;
    1463   145901343 :         unsigned long                   nr_ops = 0;
    1464   145901343 :         int                             shape_changes = 0;
    1465             : 
    1466   145901343 :         trace_xfs_refcount_deferred(mp, ri);
    1467             : 
    1468   145901759 :         if (ri->ri_realtime) {
    1469    28508297 :                 xfs_rgnumber_t          rgno;
    1470             : 
    1471    28508297 :                 bno = xfs_rtb_to_rgbno(mp, ri->ri_startblock, &rgno);
    1472             :         } else {
    1473   117393462 :                 bno = XFS_FSB_TO_AGBNO(mp, ri->ri_startblock);
    1474             :         }
    1475             : 
    1476   145901751 :         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   145901516 :         rcur = *pcur;
    1484   146842325 :         if (rcur != NULL && xfs_refcount_is_wrong_cursor(rcur, ri)) {
    1485      388133 :                 nr_ops = xrefc_btree_state(rcur)->nr_ops;
    1486      388133 :                 shape_changes = xrefc_btree_state(rcur)->shape_changes;
    1487      388133 :                 xfs_refcount_finish_one_cleanup(tp, rcur, 0);
    1488      388133 :                 rcur = NULL;
    1489      388133 :                 *pcur = NULL;
    1490             :         }
    1491   145901516 :         if (rcur == NULL) {
    1492   145348811 :                 if (ri->ri_realtime) {
    1493    28206600 :                         xfs_rtgroup_lock(tp, ri->ri_rtg, XFS_RTGLOCK_REFCOUNT);
    1494    28206751 :                         rcur = xfs_rtrefcountbt_init_cursor(mp, tp, ri->ri_rtg,
    1495             :                                         ri->ri_rtg->rtg_refcountip);
    1496             :                 } else {
    1497   117142211 :                         error = xfs_alloc_read_agf(ri->ri_pag, tp,
    1498             :                                         XFS_ALLOC_FLAG_FREEING, &agbp);
    1499   117142375 :                         if (error)
    1500             :                                 return error;
    1501             : 
    1502   117142146 :                         rcur = xfs_refcountbt_init_cursor(mp, tp, agbp,
    1503             :                                         ri->ri_pag);
    1504             :                 }
    1505   145348854 :                 xrefc_btree_state(rcur)->nr_ops = nr_ops;
    1506   290697708 :                 xrefc_btree_state(rcur)->shape_changes = shape_changes;
    1507             :         }
    1508   145901559 :         *pcur = rcur;
    1509             : 
    1510   145901559 :         switch (ri->ri_type) {
    1511    61781305 :         case XFS_REFCOUNT_INCREASE:
    1512    61781305 :                 error = xfs_refcount_adjust(rcur, &bno, &ri->ri_blockcount,
    1513             :                                 XFS_REFCOUNT_ADJUST_INCREASE);
    1514    61781310 :                 if (error)
    1515             :                         return error;
    1516    61781247 :                 if (ri->ri_blockcount > 0)
    1517          42 :                         error = xfs_refcount_continue_op(rcur, ri, bno);
    1518             :                 break;
    1519    79693519 :         case XFS_REFCOUNT_DECREASE:
    1520    79693519 :                 error = xfs_refcount_adjust(rcur, &bno, &ri->ri_blockcount,
    1521             :                                 XFS_REFCOUNT_ADJUST_DECREASE);
    1522    79693470 :                 if (error)
    1523             :                         return error;
    1524    79693392 :                 if (ri->ri_blockcount > 0)
    1525         348 :                         error = xfs_refcount_continue_op(rcur, ri, bno);
    1526             :                 break;
    1527      670236 :         case XFS_REFCOUNT_ALLOC_COW:
    1528      670236 :                 error = __xfs_refcount_cow_alloc(rcur, bno, ri->ri_blockcount);
    1529      670242 :                 if (error)
    1530             :                         return error;
    1531      670242 :                 ri->ri_blockcount = 0;
    1532      670242 :                 break;
    1533     3756499 :         case XFS_REFCOUNT_FREE_COW:
    1534     3756499 :                 error = __xfs_refcount_cow_free(rcur, bno, ri->ri_blockcount);
    1535     3756513 :                 if (error)
    1536             :                         return error;
    1537     3756513 :                 ri->ri_blockcount = 0;
    1538     3756513 :                 break;
    1539           0 :         default:
    1540           0 :                 ASSERT(0);
    1541           0 :                 return -EFSCORRUPTED;
    1542             :         }
    1543   145901394 :         if (!error && ri->ri_blockcount > 0)
    1544         390 :                 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   145900123 : __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   145900123 :         struct xfs_refcount_intent      *ri;
    1560   145900123 :         enum xfs_defer_ops_type         optype;
    1561             : 
    1562   145900123 :         ri = kmem_cache_alloc(xfs_refcount_intent_cache,
    1563             :                         GFP_NOFS | __GFP_NOFAIL);
    1564   145900186 :         INIT_LIST_HEAD(&ri->ri_list);
    1565   145900186 :         ri->ri_type = type;
    1566   145900186 :         ri->ri_startblock = startblock;
    1567   145900186 :         ri->ri_blockcount = blockcount;
    1568   145900186 :         ri->ri_realtime = isrt;
    1569             : 
    1570   145900186 :         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   145899716 :         if (isrt)
    1580             :                 optype = XFS_DEFER_OPS_TYPE_REFCOUNT_RT;
    1581             :         else
    1582   117392729 :                 optype = XFS_DEFER_OPS_TYPE_REFCOUNT;
    1583             : 
    1584   145899716 :         xfs_refcount_update_get_group(tp->t_mountp, ri);
    1585   145898627 :         xfs_defer_add(tp, optype, &ri->ri_list);
    1586   145899915 : }
    1587             : 
    1588             : /*
    1589             :  * Increase the reference count of the blocks backing a file's extent.
    1590             :  */
    1591             : void
    1592    61781200 : xfs_refcount_increase_extent(
    1593             :         struct xfs_trans                *tp,
    1594             :         bool                            isrt,
    1595             :         struct xfs_bmbt_irec            *PREV)
    1596             : {
    1597    61781200 :         if (!xfs_has_reflink(tp->t_mountp))
    1598             :                 return;
    1599             : 
    1600    61781200 :         __xfs_refcount_add(tp, XFS_REFCOUNT_INCREASE, isrt, PREV->br_startblock,
    1601    61781200 :                         PREV->br_blockcount);
    1602             : }
    1603             : 
    1604             : /*
    1605             :  * Decrease the reference count of the blocks backing a file's extent.
    1606             :  */
    1607             : void
    1608    79692993 : xfs_refcount_decrease_extent(
    1609             :         struct xfs_trans                *tp,
    1610             :         bool                            isrt,
    1611             :         struct xfs_bmbt_irec            *PREV)
    1612             : {
    1613    79692993 :         if (!xfs_has_reflink(tp->t_mountp))
    1614             :                 return;
    1615             : 
    1616    79692400 :         __xfs_refcount_add(tp, XFS_REFCOUNT_DECREASE, isrt, PREV->br_startblock,
    1617    79692400 :                         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  2462461382 : 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  2462461382 :         struct xfs_refcount_irec        tmp;
    1638  2462461382 :         int                             i;
    1639  2462461382 :         int                             have;
    1640  2462461382 :         int                             error;
    1641             : 
    1642  2462461382 :         trace_xfs_refcount_find_shared(cur, agbno, aglen);
    1643             : 
    1644             :         /* By default, skip the whole range */
    1645  2462475942 :         *fbno = NULLAGBLOCK;
    1646  2462475942 :         *flen = 0;
    1647             : 
    1648             :         /* Try to find a refcount extent that crosses the start */
    1649  2462475942 :         error = xfs_refcount_lookup_le(cur, XFS_REFC_DOMAIN_SHARED, agbno,
    1650             :                         &have);
    1651  2462499100 :         if (error)
    1652          18 :                 goto out_error;
    1653  2462499082 :         if (!have) {
    1654             :                 /* No left extent, look at the next one */
    1655   708102168 :                 error = xfs_btree_increment(cur, 0, &have);
    1656   708106970 :                 if (error)
    1657           0 :                         goto out_error;
    1658   708106970 :                 if (!have)
    1659   670532933 :                         goto done;
    1660             :         }
    1661  1791970951 :         error = xfs_refcount_get_rec(cur, &tmp, &i);
    1662  1792035886 :         if (error)
    1663           0 :                 goto out_error;
    1664  1792035886 :         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  1792035886 :         if (tmp.rc_domain != XFS_REFC_DOMAIN_SHARED)
    1670      595832 :                 goto done;
    1671             : 
    1672             :         /* If the extent ends before the start, look at the next one */
    1673  1791440054 :         if (tmp.rc_startblock + tmp.rc_blockcount <= agbno) {
    1674  1612181699 :                 error = xfs_btree_increment(cur, 0, &have);
    1675  1612117260 :                 if (error)
    1676           0 :                         goto out_error;
    1677  1612117260 :                 if (!have)
    1678     9095275 :                         goto done;
    1679  1603021985 :                 error = xfs_refcount_get_rec(cur, &tmp, &i);
    1680  1602934076 :                 if (error)
    1681           0 :                         goto out_error;
    1682  1602934076 :                 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  1602934076 :                 if (tmp.rc_domain != XFS_REFC_DOMAIN_SHARED)
    1688    35834045 :                         goto done;
    1689             :         }
    1690             : 
    1691             :         /* If the extent starts after the range we want, bail out */
    1692  1746358386 :         if (tmp.rc_startblock >= agbno + aglen)
    1693  1600421402 :                 goto done;
    1694             : 
    1695             :         /* We found the start of a shared extent! */
    1696   145936984 :         if (tmp.rc_startblock < agbno) {
    1697     1646130 :                 tmp.rc_blockcount -= (agbno - tmp.rc_startblock);
    1698     1646130 :                 tmp.rc_startblock = agbno;
    1699             :         }
    1700             : 
    1701   145936984 :         *fbno = tmp.rc_startblock;
    1702   145936984 :         *flen = min(tmp.rc_blockcount, agbno + aglen - *fbno);
    1703   145936984 :         if (!find_end_of_shared)
    1704   144002499 :                 goto done;
    1705             : 
    1706             :         /* Otherwise, find the end of this shared extent */
    1707     3358150 :         while (*fbno + *flen < agbno + aglen) {
    1708     1476851 :                 error = xfs_btree_increment(cur, 0, &have);
    1709     1476930 :                 if (error)
    1710           0 :                         goto out_error;
    1711     1476930 :                 if (!have)
    1712             :                         break;
    1713     1470980 :                 error = xfs_refcount_get_rec(cur, &tmp, &i);
    1714     1470980 :                 if (error)
    1715           0 :                         goto out_error;
    1716     1470980 :                 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     1470980 :                 if (tmp.rc_domain != XFS_REFC_DOMAIN_SHARED ||
    1722     1467999 :                     tmp.rc_startblock >= agbno + aglen ||
    1723     1427123 :                     tmp.rc_startblock != *fbno + *flen)
    1724             :                         break;
    1725     1423665 :                 *flen = min(*flen + tmp.rc_blockcount, agbno + aglen - *fbno);
    1726             :         }
    1727             : 
    1728     1934564 : done:
    1729  2462416550 :         trace_xfs_refcount_find_shared_result(cur, *fbno, *flen);
    1730             : 
    1731  2462309373 : out_error:
    1732  2462309373 :         if (error)
    1733          18 :                 trace_xfs_refcount_find_shared_error(cur, error, _RET_IP_);
    1734  2462309373 :         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     4426750 : 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     4426750 :         struct xfs_refcount_irec        ext, tmp;
    1797     4426750 :         int                             error;
    1798     4426750 :         int                             found_rec, found_tmp;
    1799             : 
    1800     4426750 :         if (aglen == 0)
    1801             :                 return 0;
    1802             : 
    1803             :         /* Find any overlapping refcount records */
    1804     4281687 :         error = xfs_refcount_lookup_ge(cur, XFS_REFC_DOMAIN_COW, agbno,
    1805             :                         &found_rec);
    1806     4281687 :         if (error)
    1807           0 :                 goto out_error;
    1808     4281687 :         error = xfs_refcount_get_rec(cur, &ext, &found_rec);
    1809     4281681 :         if (error)
    1810           0 :                 goto out_error;
    1811     4281681 :         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     4281681 :         if (!found_rec) {
    1818      194853 :                 ext.rc_startblock = xrefc_max_startblock(cur);
    1819      194853 :                 ext.rc_blockcount = 0;
    1820      194853 :                 ext.rc_refcount = 0;
    1821      194853 :                 ext.rc_domain = XFS_REFC_DOMAIN_COW;
    1822             :         }
    1823             : 
    1824     4281681 :         switch (adj) {
    1825      525176 :         case XFS_REFCOUNT_ADJUST_COW_ALLOC:
    1826             :                 /* Adding a CoW reservation, there should be nothing here. */
    1827      525176 :                 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      525176 :                 tmp.rc_startblock = agbno;
    1835      525176 :                 tmp.rc_blockcount = aglen;
    1836      525176 :                 tmp.rc_refcount = 1;
    1837      525176 :                 tmp.rc_domain = XFS_REFC_DOMAIN_COW;
    1838             : 
    1839      525176 :                 trace_xfs_refcount_modify_extent(cur, &tmp);
    1840             : 
    1841      525176 :                 error = xfs_refcount_insert(cur, &tmp,
    1842             :                                 &found_tmp);
    1843      525176 :                 if (error)
    1844           0 :                         goto out_error;
    1845      525176 :                 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     3756505 :         case XFS_REFCOUNT_ADJUST_COW_FREE:
    1852             :                 /* Removing a CoW reservation, there should be one extent. */
    1853     3756505 :                 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     3756505 :                 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     3756505 :                 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     3756505 :                 ext.rc_refcount = 0;
    1870     3756505 :                 trace_xfs_refcount_modify_extent(cur, &ext);
    1871     3756502 :                 error = xfs_refcount_delete(cur, &found_rec);
    1872     3756513 :                 if (error)
    1873           0 :                         goto out_error;
    1874     3756513 :                 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     4426727 : 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     4426727 :         bool                    shape_changed;
    1901     4426727 :         int                     error;
    1902             : 
    1903             :         /*
    1904             :          * Ensure that no rcextents cross the boundary of the adjustment range.
    1905             :          */
    1906     4426727 :         error = xfs_refcount_split_extent(cur, XFS_REFC_DOMAIN_COW,
    1907             :                         agbno, &shape_changed);
    1908     4426733 :         if (error)
    1909           0 :                 goto out_error;
    1910             : 
    1911     4426733 :         error = xfs_refcount_split_extent(cur, XFS_REFC_DOMAIN_COW,
    1912             :                         agbno + aglen, &shape_changed);
    1913     4426752 :         if (error)
    1914           0 :                 goto out_error;
    1915             : 
    1916             :         /*
    1917             :          * Try to merge with the left or right extents of the range.
    1918             :          */
    1919     4426752 :         error = xfs_refcount_merge_extents(cur, XFS_REFC_DOMAIN_COW, &agbno,
    1920             :                         &aglen, adj, &shape_changed);
    1921     4426752 :         if (error)
    1922           0 :                 goto out_error;
    1923             : 
    1924             :         /* Now that we've taken care of the ends, adjust the middle extents */
    1925     4426752 :         error = xfs_refcount_adjust_cow_extents(cur, agbno, aglen, adj);
    1926     4426752 :         if (error)
    1927           0 :                 goto out_error;
    1928             : 
    1929             :         return 0;
    1930             : 
    1931           0 : out_error:
    1932           0 :         trace_xfs_refcount_adjust_cow_error(cur, error, _RET_IP_);
    1933           0 :         return error;
    1934             : }
    1935             : 
    1936             : /*
    1937             :  * Record a CoW allocation in the refcount btree.
    1938             :  */
    1939             : STATIC int
    1940      670241 : __xfs_refcount_cow_alloc(
    1941             :         struct xfs_btree_cur    *rcur,
    1942             :         xfs_agblock_t           agbno,
    1943             :         xfs_extlen_t            aglen)
    1944             : {
    1945      670241 :         trace_xfs_refcount_cow_increase(rcur, agbno, aglen);
    1946             : 
    1947             :         /* Add refcount btree reservation */
    1948      670241 :         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     3756507 : __xfs_refcount_cow_free(
    1957             :         struct xfs_btree_cur    *rcur,
    1958             :         xfs_agblock_t           agbno,
    1959             :         xfs_extlen_t            aglen)
    1960             : {
    1961     3756507 :         trace_xfs_refcount_cow_decrease(rcur, agbno, aglen);
    1962             : 
    1963             :         /* Remove refcount btree reservation */
    1964     3756496 :         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      670240 : 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      670240 :         struct xfs_mount                *mp = tp->t_mountp;
    1977             : 
    1978      670240 :         if (!xfs_has_reflink(mp))
    1979             :                 return;
    1980             : 
    1981      670239 :         __xfs_refcount_add(tp, XFS_REFCOUNT_ALLOC_COW, isrt, fsb, len);
    1982             : 
    1983             :         /* Add rmap entry */
    1984      670233 :         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     3756509 : 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     3756509 :         struct xfs_mount                *mp = tp->t_mountp;
    1996             : 
    1997     3756509 :         if (!xfs_has_reflink(mp))
    1998             :                 return;
    1999             : 
    2000             :         /* Remove rmap entry */
    2001     3756514 :         xfs_rmap_free_extent(tp, isrt, fsb, len, XFS_RMAP_OWN_COW);
    2002     3756509 :         __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      291717 : xfs_refcount_recover_extent(
    2013             :         struct xfs_btree_cur            *cur,
    2014             :         const union xfs_btree_rec       *rec,
    2015             :         void                            *priv)
    2016             : {
    2017      291717 :         struct list_head                *debris = priv;
    2018      291717 :         struct xfs_refcount_recovery    *rr;
    2019             : 
    2020      291717 :         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      291717 :         rr = kmalloc(sizeof(struct xfs_refcount_recovery),
    2027             :                         GFP_KERNEL | __GFP_NOFAIL);
    2028      291717 :         INIT_LIST_HEAD(&rr->rr_list);
    2029      291717 :         xfs_refcount_btrec_to_irec(rec, &rr->rr_rrec);
    2030             : 
    2031      291717 :         if (xfs_refcount_check_irec(cur, &rr->rr_rrec) != NULL ||
    2032      291717 :             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      291717 :         list_add_tail(&rr->rr_list, debris);
    2040      291717 :         return 0;
    2041             : }
    2042             : 
    2043             : /* Find and remove leftover CoW reservations. */
    2044             : static int
    2045       45426 : xfs_refcount_recover_group_cow_leftovers(
    2046             :         struct xfs_mount                *mp,
    2047             :         struct xfs_perag                *pag,
    2048             :         struct xfs_rtgroup              *rtg)
    2049             : {
    2050       45426 :         struct xfs_trans                *tp;
    2051       45426 :         struct xfs_btree_cur            *cur;
    2052       45426 :         struct xfs_buf                  *agbp = NULL;
    2053       45426 :         struct xfs_refcount_recovery    *rr, *n;
    2054       45426 :         struct list_head                debris;
    2055       45426 :         union xfs_btree_irec            low = {
    2056             :                 .rc.rc_domain           = XFS_REFC_DOMAIN_COW,
    2057             :         };
    2058       45426 :         union xfs_btree_irec            high = {
    2059             :                 .rc.rc_domain           = XFS_REFC_DOMAIN_COW,
    2060             :                 .rc.rc_startblock       = -1U,
    2061             :         };
    2062       45426 :         xfs_fsblock_t                   fsb;
    2063       45426 :         int                             error;
    2064             : 
    2065             :         /* reflink filesystems mustn't have AGs larger than 2^31-1 blocks */
    2066       45426 :         BUILD_BUG_ON(XFS_MAX_CRC_AG_BLOCKS >= XFS_REFC_COWFLAG);
    2067       45426 :         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       45426 :         BUILD_BUG_ON(XFS_MAX_RGBLOCKS >= XFS_REFC_COWFLAG);
    2072       45426 :         if (rtg && mp->m_sb.sb_rgblocks >= XFS_MAX_RGBLOCKS)
    2073             :                 return -EOPNOTSUPP;
    2074             : 
    2075       45426 :         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       45426 :         error = xfs_trans_alloc_empty(mp, &tp);
    2088       45426 :         if (error)
    2089             :                 return error;
    2090             : 
    2091       45426 :         if (rtg) {
    2092           0 :                 xfs_rtgroup_lock(NULL, rtg, XFS_RTGLOCK_REFCOUNT);
    2093           0 :                 cur = xfs_rtrefcountbt_init_cursor(mp, tp, rtg,
    2094             :                                 rtg->rtg_refcountip);
    2095             :         } else {
    2096       45426 :                 error = xfs_alloc_read_agf(pag, tp, 0, &agbp);
    2097       45426 :                 if (error)
    2098           4 :                         goto out_trans;
    2099       45422 :                 cur = xfs_refcountbt_init_cursor(mp, tp, agbp, pag);
    2100             :         }
    2101             : 
    2102             :         /* Find all the leftover CoW staging extents. */
    2103       45422 :         error = xfs_btree_query_range(cur, &low, &high,
    2104             :                         xfs_refcount_recover_extent, &debris);
    2105       45422 :         xfs_btree_del_cursor(cur, error);
    2106       45422 :         if (agbp)
    2107       45422 :                 xfs_trans_brelse(tp, agbp);
    2108             :         else
    2109           0 :                 xfs_rtgroup_unlock(rtg, XFS_RTGLOCK_REFCOUNT);
    2110       45422 :         xfs_trans_cancel(tp);
    2111       45422 :         if (error)
    2112           4 :                 goto out_free;
    2113             : 
    2114             :         /* Now iterate the list to free the leftovers */
    2115      337135 :         list_for_each_entry_safe(rr, n, &debris, rr_list) {
    2116             :                 /* Set up transaction. */
    2117      291717 :                 error = xfs_trans_alloc(mp, &M_RES(mp)->tr_write, 0, 0, 0, &tp);
    2118      291717 :                 if (error)
    2119           0 :                         goto out_free;
    2120             : 
    2121             :                 /* Free the orphan record */
    2122      291717 :                 if (rtg)
    2123           0 :                         fsb = xfs_rgbno_to_rtb(mp, rtg->rtg_rgno,
    2124             :                                         rr->rr_rrec.rc_startblock);
    2125             :                 else
    2126      291717 :                         fsb = XFS_AGB_TO_FSB(mp, pag->pag_agno,
    2127             :                                         rr->rr_rrec.rc_startblock);
    2128      291717 :                 xfs_refcount_free_cow_extent(tp, rtg != NULL, fsb,
    2129             :                                 rr->rr_rrec.rc_blockcount);
    2130             : 
    2131             :                 /* Free the block. */
    2132      291717 :                 error = xfs_free_extent_later(tp, fsb,
    2133      291717 :                                 rr->rr_rrec.rc_blockcount, NULL,
    2134             :                                 XFS_AG_RESV_NONE,
    2135             :                                 rtg != NULL ? XFS_FREE_EXTENT_REALTIME : 0);
    2136      291717 :                 if (error)
    2137           0 :                         goto out_trans;
    2138             : 
    2139      291717 :                 error = xfs_trans_commit(tp);
    2140      291717 :                 if (error)
    2141           0 :                         goto out_free;
    2142             : 
    2143      291717 :                 list_del(&rr->rr_list);
    2144      291717 :                 kfree(rr);
    2145             :         }
    2146             : 
    2147             :         return error;
    2148           4 : out_trans:
    2149           4 :         xfs_trans_cancel(tp);
    2150           8 : out_free:
    2151             :         /* Free the leftover list */
    2152           8 :         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       45426 : xfs_refcount_recover_cow_leftovers(
    2161             :         struct xfs_mount                *mp,
    2162             :         struct xfs_perag                *pag)
    2163             : {
    2164       45426 :         return xfs_refcount_recover_group_cow_leftovers(mp, pag, NULL);
    2165             : }
    2166             : 
    2167             : int
    2168           0 : xfs_refcount_recover_rtcow_leftovers(
    2169             :         struct xfs_mount                *mp,
    2170             :         struct xfs_rtgroup              *rtg)
    2171             : {
    2172           0 :         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  2540896822 : 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  2540896822 :         union xfs_btree_irec    low;
    2188  2540896822 :         union xfs_btree_irec    high;
    2189             : 
    2190  2540896822 :         memset(&low, 0, sizeof(low));
    2191  2540896822 :         low.rc.rc_startblock = bno;
    2192  2540896822 :         memset(&high, 0xFF, sizeof(high));
    2193  2540896822 :         high.rc.rc_startblock = bno + len - 1;
    2194  2540896822 :         low.rc.rc_domain = high.rc.rc_domain = domain;
    2195             : 
    2196  2540896822 :         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       42062 : xfs_refcount_query_range_helper(
    2207             :         struct xfs_btree_cur            *cur,
    2208             :         const union xfs_btree_rec       *rec,
    2209             :         void                            *priv)
    2210             : {
    2211       42062 :         struct xfs_refcount_query_range_info    *query = priv;
    2212       42062 :         struct xfs_refcount_irec        irec;
    2213       42062 :         xfs_failaddr_t                  fa;
    2214             : 
    2215       42062 :         xfs_refcount_btrec_to_irec(rec, &irec);
    2216       42062 :         fa = xfs_refcount_check_irec(cur, &irec);
    2217       42062 :         if (fa)
    2218           0 :                 return xfs_refcount_complain_bad_rec(cur, fa, &irec);
    2219             : 
    2220       42062 :         return query->fn(cur, &irec, query->priv);
    2221             : }
    2222             : 
    2223             : /* Find all refcount records between two keys. */
    2224             : int
    2225       21116 : 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       21116 :         union xfs_btree_irec            low_brec = { .rc = *low_rec };
    2233       21116 :         union xfs_btree_irec            high_brec = { .rc = *high_rec };
    2234       21116 :         struct xfs_refcount_query_range_info query = { .priv = priv, .fn = fn };
    2235             : 
    2236       21116 :         return xfs_btree_query_range(cur, &low_brec, &high_brec,
    2237             :                         xfs_refcount_query_range_helper, &query);
    2238             : }
    2239             : 
    2240             : int __init
    2241          12 : xfs_refcount_intent_init_cache(void)
    2242             : {
    2243          12 :         xfs_refcount_intent_cache = kmem_cache_create("xfs_refc_intent",
    2244             :                         sizeof(struct xfs_refcount_intent),
    2245             :                         0, 0, NULL);
    2246             : 
    2247          12 :         return xfs_refcount_intent_cache != NULL ? 0 : -ENOMEM;
    2248             : }
    2249             : 
    2250             : void
    2251          12 : xfs_refcount_intent_destroy_cache(void)
    2252             : {
    2253          12 :         kmem_cache_destroy(xfs_refcount_intent_cache);
    2254          12 :         xfs_refcount_intent_cache = NULL;
    2255          12 : }

Generated by: LCOV version 1.14