LCOV - code coverage report
Current view: top level - fs/xfs/libxfs - xfs_rtgroup.c (source / functions) Hit Total Coverage
Test: fstests of 6.5.0-rc4-xfsx @ Mon Jul 31 20:08:34 PDT 2023 Lines: 239 284 84.2 %
Date: 2023-07-31 20:08:34 Functions: 20 20 100.0 %

          Line data    Source code
       1             : // SPDX-License-Identifier: GPL-2.0-or-later
       2             : /*
       3             :  * Copyright (C) 2022-2023 Oracle.  All Rights Reserved.
       4             :  * Author: Darrick J. Wong <djwong@kernel.org>
       5             :  */
       6             : #include "xfs.h"
       7             : #include "xfs_fs.h"
       8             : #include "xfs_shared.h"
       9             : #include "xfs_format.h"
      10             : #include "xfs_trans_resv.h"
      11             : #include "xfs_bit.h"
      12             : #include "xfs_sb.h"
      13             : #include "xfs_mount.h"
      14             : #include "xfs_btree.h"
      15             : #include "xfs_alloc_btree.h"
      16             : #include "xfs_rmap_btree.h"
      17             : #include "xfs_alloc.h"
      18             : #include "xfs_ialloc.h"
      19             : #include "xfs_rmap.h"
      20             : #include "xfs_ag.h"
      21             : #include "xfs_ag_resv.h"
      22             : #include "xfs_health.h"
      23             : #include "xfs_error.h"
      24             : #include "xfs_bmap.h"
      25             : #include "xfs_defer.h"
      26             : #include "xfs_log_format.h"
      27             : #include "xfs_trans.h"
      28             : #include "xfs_trace.h"
      29             : #include "xfs_inode.h"
      30             : #include "xfs_icache.h"
      31             : #include "xfs_buf_item.h"
      32             : #include "xfs_rtgroup.h"
      33             : #include "xfs_rtbitmap.h"
      34             : 
      35             : /*
      36             :  * Passive reference counting access wrappers to the rtgroup structures.  If
      37             :  * the rtgroup structure is to be freed, the freeing code is responsible for
      38             :  * cleaning up objects with passive references before freeing the structure.
      39             :  */
      40             : struct xfs_rtgroup *
      41   874887674 : xfs_rtgroup_get(
      42             :         struct xfs_mount        *mp,
      43             :         xfs_rgnumber_t          rgno)
      44             : {
      45   874887674 :         struct xfs_rtgroup      *rtg;
      46             : 
      47   874887674 :         rcu_read_lock();
      48   874796838 :         rtg = radix_tree_lookup(&mp->m_rtgroup_tree, rgno);
      49   874921856 :         if (rtg) {
      50   874821162 :                 trace_xfs_rtgroup_get(rtg, _RET_IP_);
      51   874904171 :                 ASSERT(atomic_read(&rtg->rtg_ref) >= 0);
      52   874904171 :                 atomic_inc(&rtg->rtg_ref);
      53             :         }
      54   875221834 :         rcu_read_unlock();
      55   875212963 :         return rtg;
      56             : }
      57             : 
      58             : /* Get a passive reference to the given rtgroup. */
      59             : struct xfs_rtgroup *
      60  1114287341 : xfs_rtgroup_hold(
      61             :         struct xfs_rtgroup      *rtg)
      62             : {
      63  1114287341 :         ASSERT(atomic_read(&rtg->rtg_ref) > 0 ||
      64             :                atomic_read(&rtg->rtg_active_ref) > 0);
      65             : 
      66  1114287341 :         trace_xfs_rtgroup_hold(rtg, _RET_IP_);
      67  1109159295 :         atomic_inc(&rtg->rtg_ref);
      68  1116107584 :         return rtg;
      69             : }
      70             : 
      71             : void
      72  1989366735 : xfs_rtgroup_put(
      73             :         struct xfs_rtgroup      *rtg)
      74             : {
      75  1989366735 :         trace_xfs_rtgroup_put(rtg, _RET_IP_);
      76  1988486122 :         ASSERT(atomic_read(&rtg->rtg_ref) > 0);
      77  1988486122 :         atomic_dec(&rtg->rtg_ref);
      78  1992879326 : }
      79             : 
      80             : /*
      81             :  * Active references for rtgroup structures. This is for short term access to
      82             :  * the rtgroup structures for walking trees or accessing state. If an rtgroup
      83             :  * is being shrunk or is offline, then this will fail to find that group and
      84             :  * return NULL instead.
      85             :  */
      86             : struct xfs_rtgroup *
      87   483637892 : xfs_rtgroup_grab(
      88             :         struct xfs_mount        *mp,
      89             :         xfs_agnumber_t          agno)
      90             : {
      91   483637892 :         struct xfs_rtgroup      *rtg;
      92             : 
      93   483637892 :         rcu_read_lock();
      94   482635078 :         rtg = radix_tree_lookup(&mp->m_rtgroup_tree, agno);
      95   481116536 :         if (rtg) {
      96   479342816 :                 trace_xfs_rtgroup_grab(rtg, _RET_IP_);
      97  1010429763 :                 if (!atomic_inc_not_zero(&rtg->rtg_active_ref))
      98           0 :                         rtg = NULL;
      99             :         }
     100   539742914 :         rcu_read_unlock();
     101   541114358 :         return rtg;
     102             : }
     103             : 
     104             : void
     105   475136111 : xfs_rtgroup_rele(
     106             :         struct xfs_rtgroup      *rtg)
     107             : {
     108   475136111 :         trace_xfs_rtgroup_rele(rtg, _RET_IP_);
     109   462526091 :         if (atomic_dec_and_test(&rtg->rtg_active_ref))
     110      100714 :                 wake_up(&rtg->rtg_active_wq);
     111   529277883 : }
     112             : 
     113             : int
     114       80462 : xfs_initialize_rtgroups(
     115             :         struct xfs_mount        *mp,
     116             :         xfs_rgnumber_t          rgcount)
     117             : {
     118       80462 :         struct xfs_rtgroup      *rtg;
     119       80462 :         xfs_rgnumber_t          index;
     120       80462 :         xfs_rgnumber_t          first_initialised = NULLRGNUMBER;
     121       80462 :         int                     error;
     122             : 
     123       80462 :         if (!xfs_has_rtgroups(mp))
     124             :                 return 0;
     125             : 
     126             :         /*
     127             :          * Walk the current rtgroup tree so we don't try to initialise rt
     128             :          * groups that already exist (growfs case). Allocate and insert all the
     129             :          * rtgroups we don't find ready for initialisation.
     130             :          */
     131      180504 :         for (index = 0; index < rgcount; index++) {
     132      107120 :                 rtg = xfs_rtgroup_get(mp, index);
     133      107120 :                 if (rtg) {
     134        6426 :                         xfs_rtgroup_put(rtg);
     135        6426 :                         continue;
     136             :                 }
     137             : 
     138      100694 :                 rtg = kmem_zalloc(sizeof(struct xfs_rtgroup), KM_MAYFAIL);
     139      100694 :                 if (!rtg) {
     140           0 :                         error = -ENOMEM;
     141           0 :                         goto out_unwind_new_rtgs;
     142             :                 }
     143      100694 :                 rtg->rtg_rgno = index;
     144      100694 :                 rtg->rtg_mount = mp;
     145             : 
     146      100694 :                 error = radix_tree_preload(GFP_NOFS);
     147      100694 :                 if (error)
     148           0 :                         goto out_free_rtg;
     149             : 
     150      100694 :                 spin_lock(&mp->m_rtgroup_lock);
     151      100694 :                 if (radix_tree_insert(&mp->m_rtgroup_tree, index, rtg)) {
     152           0 :                         WARN_ON_ONCE(1);
     153           0 :                         spin_unlock(&mp->m_rtgroup_lock);
     154           0 :                         radix_tree_preload_end();
     155           0 :                         error = -EEXIST;
     156           0 :                         goto out_free_rtg;
     157             :                 }
     158      100694 :                 spin_unlock(&mp->m_rtgroup_lock);
     159      100694 :                 radix_tree_preload_end();
     160             : 
     161             : #ifdef __KERNEL__
     162             :                 /* Place kernel structure only init below this point. */
     163      100694 :                 spin_lock_init(&rtg->rtg_state_lock);
     164      100694 :                 init_waitqueue_head(&rtg->rtg_active_wq);
     165      100694 :                 xfs_defer_drain_init(&rtg->rtg_intents_drain);
     166      100694 :                 xfs_hooks_init(&rtg->rtg_rmap_update_hooks);
     167             : #endif /* __KERNEL__ */
     168             : 
     169             :                 /* Active ref owned by mount indicates rtgroup is online. */
     170      100694 :                 atomic_set(&rtg->rtg_active_ref, 1);
     171             : 
     172             :                 /* first new rtg is fully initialized */
     173      100694 :                 if (first_initialised == NULLRGNUMBER)
     174       18727 :                         first_initialised = index;
     175             :         }
     176             : 
     177             :         return 0;
     178             : 
     179           0 : out_free_rtg:
     180           0 :         kmem_free(rtg);
     181           0 : out_unwind_new_rtgs:
     182             :         /* unwind any prior newly initialized rtgs */
     183           0 :         for (index = first_initialised; index < rgcount; index++) {
     184           0 :                 rtg = radix_tree_delete(&mp->m_rtgroup_tree, index);
     185           0 :                 if (!rtg)
     186             :                         break;
     187           0 :                 kmem_free(rtg);
     188             :         }
     189             :         return error;
     190             : }
     191             : 
     192             : STATIC void
     193      100714 : __xfs_free_rtgroups(
     194             :         struct rcu_head         *head)
     195             : {
     196      100714 :         struct xfs_rtgroup      *rtg;
     197             : 
     198      100714 :         rtg = container_of(head, struct xfs_rtgroup, rcu_head);
     199      100714 :         kmem_free(rtg);
     200      100714 : }
     201             : 
     202             : /*
     203             :  * Free up the rtgroup resources associated with the mount structure.
     204             :  */
     205             : void
     206       66867 : xfs_free_rtgroups(
     207             :         struct xfs_mount        *mp)
     208             : {
     209       66867 :         struct xfs_rtgroup      *rtg;
     210       66867 :         xfs_rgnumber_t          rgno;
     211             : 
     212       66867 :         if (!xfs_has_rtgroups(mp))
     213             :                 return;
     214             : 
     215      161160 :         for (rgno = 0; rgno < mp->m_sb.sb_rgcount; rgno++) {
     216      100714 :                 spin_lock(&mp->m_rtgroup_lock);
     217      100714 :                 rtg = radix_tree_delete(&mp->m_rtgroup_tree, rgno);
     218      100714 :                 spin_unlock(&mp->m_rtgroup_lock);
     219      100714 :                 ASSERT(rtg);
     220      100714 :                 XFS_IS_CORRUPT(mp, atomic_read(&rtg->rtg_ref) != 0);
     221      100714 :                 xfs_defer_drain_free(&rtg->rtg_intents_drain);
     222             : 
     223             :                 /* drop the mount's active reference */
     224      100714 :                 xfs_rtgroup_rele(rtg);
     225      100714 :                 XFS_IS_CORRUPT(mp, atomic_read(&rtg->rtg_active_ref) != 0);
     226             : 
     227      100714 :                 call_rcu(&rtg->rcu_head, __xfs_free_rtgroups);
     228             :         }
     229             : }
     230             : 
     231             : /* Find the size of the rtgroup, in blocks. */
     232             : static xfs_rgblock_t
     233  2946438659 : __xfs_rtgroup_block_count(
     234             :         struct xfs_mount        *mp,
     235             :         xfs_rgnumber_t          rgno,
     236             :         xfs_rgnumber_t          rgcount,
     237             :         xfs_rfsblock_t          rblocks)
     238             : {
     239  2946438659 :         ASSERT(rgno < rgcount);
     240             : 
     241  2946438659 :         if (rgno < rgcount - 1)
     242  2574528381 :                 return mp->m_sb.sb_rgblocks;
     243   371908074 :         return xfs_rtb_rounddown_rtx(mp,
     244   371910278 :                         rblocks - (rgno * mp->m_sb.sb_rgblocks));
     245             : }
     246             : 
     247             : /* Compute the number of blocks in this realtime group. */
     248             : xfs_rgblock_t
     249  2946154016 : xfs_rtgroup_block_count(
     250             :         struct xfs_mount        *mp,
     251             :         xfs_rgnumber_t          rgno)
     252             : {
     253  2946154016 :         return __xfs_rtgroup_block_count(mp, rgno, mp->m_sb.sb_rgcount,
     254             :                         mp->m_sb.sb_rblocks);
     255             : }
     256             : 
     257             : static xfs_failaddr_t
     258      232580 : xfs_rtsb_verify(
     259             :         struct xfs_buf          *bp)
     260             : {
     261      232580 :         struct xfs_mount        *mp = bp->b_mount;
     262      232580 :         struct xfs_rtsb         *rsb = bp->b_addr;
     263             : 
     264      232580 :         if (!xfs_verify_magic(bp, rsb->rsb_magicnum))
     265           0 :                 return __this_address;
     266      232577 :         if (be32_to_cpu(rsb->rsb_blocksize) != mp->m_sb.sb_blocksize)
     267           0 :                 return __this_address;
     268      232577 :         if (be64_to_cpu(rsb->rsb_rblocks) != mp->m_sb.sb_rblocks)
     269           0 :                 return __this_address;
     270             : 
     271      232577 :         if (be64_to_cpu(rsb->rsb_rextents) != mp->m_sb.sb_rextents)
     272           0 :                 return __this_address;
     273             : 
     274      232577 :         if (!uuid_equal(&rsb->rsb_uuid, &mp->m_sb.sb_uuid))
     275           0 :                 return __this_address;
     276             : 
     277      232576 :         if (be32_to_cpu(rsb->rsb_rgcount) != mp->m_sb.sb_rgcount)
     278           0 :                 return __this_address;
     279             : 
     280      232576 :         if (be32_to_cpu(rsb->rsb_rextsize) != mp->m_sb.sb_rextsize)
     281           0 :                 return __this_address;
     282      232576 :         if (be32_to_cpu(rsb->rsb_rbmblocks) != mp->m_sb.sb_rbmblocks)
     283           0 :                 return __this_address;
     284             : 
     285      232576 :         if (be32_to_cpu(rsb->rsb_rgblocks) != mp->m_sb.sb_rgblocks)
     286           0 :                 return __this_address;
     287      232576 :         if (rsb->rsb_blocklog != mp->m_sb.sb_blocklog)
     288           0 :                 return __this_address;
     289      232576 :         if (rsb->rsb_sectlog != mp->m_sb.sb_sectlog)
     290           0 :                 return __this_address;
     291      232576 :         if (rsb->rsb_rextslog != mp->m_sb.sb_rextslog)
     292           0 :                 return __this_address;
     293      232576 :         if (rsb->rsb_pad)
     294           0 :                 return __this_address;
     295             : 
     296      232576 :         if (rsb->rsb_pad2)
     297           0 :                 return __this_address;
     298             : 
     299      232576 :         if (!uuid_equal(&rsb->rsb_meta_uuid, &mp->m_sb.sb_meta_uuid))
     300           0 :                 return __this_address;
     301             : 
     302             :         /* Everything to the end of the fs block must be zero */
     303      465158 :         if (memchr_inv(rsb + 1, 0, BBTOB(bp->b_length) - sizeof(*rsb)))
     304           0 :                 return __this_address;
     305             : 
     306             :         return NULL;
     307             : }
     308             : 
     309             : static void
     310       68570 : xfs_rtsb_read_verify(
     311             :         struct xfs_buf  *bp)
     312             : {
     313       68570 :         xfs_failaddr_t  fa;
     314             : 
     315       68570 :         if (!xfs_buf_verify_cksum(bp, XFS_RTSB_CRC_OFF))
     316           0 :                 xfs_verifier_error(bp, -EFSBADCRC, __this_address);
     317             :         else {
     318       68570 :                 fa = xfs_rtsb_verify(bp);
     319       68570 :                 if (fa)
     320           0 :                         xfs_verifier_error(bp, -EFSCORRUPTED, fa);
     321             :         }
     322       68570 : }
     323             : 
     324             : static void
     325      164011 : xfs_rtsb_write_verify(
     326             :         struct xfs_buf          *bp)
     327             : {
     328      164011 :         struct xfs_rtsb         *rsb = bp->b_addr;
     329      164011 :         struct xfs_buf_log_item *bip = bp->b_log_item;
     330      164011 :         xfs_failaddr_t          fa;
     331             : 
     332      164011 :         fa = xfs_rtsb_verify(bp);
     333      164001 :         if (fa) {
     334           0 :                 xfs_verifier_error(bp, -EFSCORRUPTED, fa);
     335           0 :                 return;
     336             :         }
     337             : 
     338      164001 :         if (bip)
     339      152506 :                 rsb->rsb_lsn = cpu_to_be64(bip->bli_item.li_lsn);
     340             : 
     341      164001 :         xfs_buf_update_cksum(bp, XFS_RTSB_CRC_OFF);
     342             : }
     343             : 
     344             : const struct xfs_buf_ops xfs_rtsb_buf_ops = {
     345             :         .name = "xfs_rtsb",
     346             :         .magic = { 0, cpu_to_be32(XFS_RTSB_MAGIC) },
     347             :         .verify_read = xfs_rtsb_read_verify,
     348             :         .verify_write = xfs_rtsb_write_verify,
     349             :         .verify_struct = xfs_rtsb_verify,
     350             : };
     351             : 
     352             : /* Update a realtime superblock from the primary fs super */
     353             : void
     354      209155 : xfs_rtgroup_update_super(
     355             :         struct xfs_buf          *rtsb_bp,
     356             :         const struct xfs_buf    *sb_bp)
     357             : {
     358      209155 :         const struct xfs_dsb    *dsb = sb_bp->b_addr;
     359      209155 :         struct xfs_rtsb         *rsb = rtsb_bp->b_addr;
     360      209155 :         const uuid_t            *meta_uuid;
     361             : 
     362      209155 :         rsb->rsb_magicnum = cpu_to_be32(XFS_RTSB_MAGIC);
     363      209155 :         rsb->rsb_blocksize = dsb->sb_blocksize;
     364      209155 :         rsb->rsb_rblocks = dsb->sb_rblocks;
     365             : 
     366      209155 :         rsb->rsb_rextents = dsb->sb_rextents;
     367      209155 :         rsb->rsb_lsn = 0;
     368             : 
     369      418310 :         memcpy(&rsb->rsb_uuid, &dsb->sb_uuid, sizeof(rsb->rsb_uuid));
     370             : 
     371      209155 :         rsb->rsb_rgcount = dsb->sb_rgcount;
     372      418310 :         memcpy(&rsb->rsb_fname, &dsb->sb_fname, XFSLABEL_MAX);
     373             : 
     374      209155 :         rsb->rsb_rextsize = dsb->sb_rextsize;
     375      209155 :         rsb->rsb_rbmblocks = dsb->sb_rbmblocks;
     376             : 
     377      209155 :         rsb->rsb_rgblocks = dsb->sb_rgblocks;
     378      209155 :         rsb->rsb_blocklog = dsb->sb_blocklog;
     379      209155 :         rsb->rsb_sectlog = dsb->sb_sectlog;
     380      209155 :         rsb->rsb_rextslog = dsb->sb_rextslog;
     381      209155 :         rsb->rsb_pad = 0;
     382      209155 :         rsb->rsb_pad2 = 0;
     383             : 
     384             :         /*
     385             :          * The metadata uuid is the fs uuid if the metauuid feature is not
     386             :          * enabled.
     387             :          */
     388      209155 :         if (dsb->sb_features_incompat &
     389             :                                 cpu_to_be32(XFS_SB_FEAT_INCOMPAT_META_UUID))
     390           0 :                 meta_uuid = &dsb->sb_meta_uuid;
     391             :         else
     392             :                 meta_uuid = &dsb->sb_uuid;
     393      418310 :         memcpy(&rsb->rsb_meta_uuid, meta_uuid, sizeof(rsb->rsb_meta_uuid));
     394      209155 : }
     395             : 
     396             : /*
     397             :  * Update the primary realtime superblock from a filesystem superblock and
     398             :  * log it to the given transaction.
     399             :  */
     400             : void
     401      493518 : xfs_rtgroup_log_super(
     402             :         struct xfs_trans        *tp,
     403             :         const struct xfs_buf    *sb_bp)
     404             : {
     405      493518 :         struct xfs_buf          *rtsb_bp;
     406             : 
     407      493518 :         if (!xfs_has_rtgroups(tp->t_mountp))
     408             :                 return;
     409             : 
     410      471453 :         rtsb_bp = xfs_trans_getrtsb(tp);
     411      471453 :         if (!rtsb_bp) {
     412             :                 /*
     413             :                  * It's possible for the rtgroups feature to be enabled but
     414             :                  * there is no incore rt superblock buffer if the rt geometry
     415             :                  * was specified at mkfs time but the rt section has not yet
     416             :                  * been attached.  In this case, rblocks must be zero.
     417             :                  */
     418      263514 :                 ASSERT(tp->t_mountp->m_sb.sb_rblocks == 0);
     419      263514 :                 return;
     420             :         }
     421             : 
     422      207939 :         xfs_rtgroup_update_super(rtsb_bp, sb_bp);
     423      207939 :         xfs_trans_ordered_buf(tp, rtsb_bp);
     424             : }
     425             : 
     426             : /* Initialize a secondary realtime superblock. */
     427             : int
     428       10293 : xfs_rtgroup_init_secondary_super(
     429             :         struct xfs_mount        *mp,
     430             :         xfs_rgnumber_t          rgno,
     431             :         struct xfs_buf          **bpp)
     432             : {
     433       10293 :         struct xfs_buf          *bp;
     434       10293 :         struct xfs_rtsb         *rsb;
     435       10293 :         xfs_rtblock_t           rtbno;
     436       10293 :         int                     error;
     437             : 
     438       10293 :         ASSERT(rgno != 0);
     439             : 
     440       10293 :         error = xfs_buf_get_uncached(mp->m_rtdev_targp, XFS_FSB_TO_BB(mp, 1),
     441             :                         0, &bp);
     442       10293 :         if (error)
     443             :                 return error;
     444             : 
     445       10290 :         rtbno = xfs_rgbno_to_rtb(mp, rgno, 0);
     446       10282 :         bp->b_maps[0].bm_bn = xfs_rtb_to_daddr(mp, rtbno);
     447       10281 :         bp->b_ops = &xfs_rtsb_buf_ops;
     448       10281 :         xfs_buf_zero(bp, 0, BBTOB(bp->b_length));
     449             : 
     450       10279 :         rsb = bp->b_addr;
     451       10279 :         rsb->rsb_magicnum = cpu_to_be32(XFS_RTSB_MAGIC);
     452       10279 :         rsb->rsb_blocksize = cpu_to_be32(mp->m_sb.sb_blocksize);
     453       10279 :         rsb->rsb_rblocks = cpu_to_be64(mp->m_sb.sb_rblocks);
     454             : 
     455       10279 :         rsb->rsb_rextents = cpu_to_be64(mp->m_sb.sb_rextents);
     456             : 
     457       20558 :         memcpy(&rsb->rsb_uuid, &mp->m_sb.sb_uuid, sizeof(rsb->rsb_uuid));
     458             : 
     459       10279 :         rsb->rsb_rgcount = cpu_to_be32(mp->m_sb.sb_rgcount);
     460       20558 :         memcpy(&rsb->rsb_fname, &mp->m_sb.sb_fname, XFSLABEL_MAX);
     461             : 
     462       10279 :         rsb->rsb_rextsize = cpu_to_be32(mp->m_sb.sb_rextsize);
     463       10279 :         rsb->rsb_rbmblocks = cpu_to_be32(mp->m_sb.sb_rbmblocks);
     464             : 
     465       10279 :         rsb->rsb_rgblocks = cpu_to_be32(mp->m_sb.sb_rgblocks);
     466       10279 :         rsb->rsb_blocklog = mp->m_sb.sb_blocklog;
     467       10279 :         rsb->rsb_sectlog = mp->m_sb.sb_sectlog;
     468       10279 :         rsb->rsb_rextslog = mp->m_sb.sb_rextslog;
     469             : 
     470       20558 :         memcpy(&rsb->rsb_meta_uuid, &mp->m_sb.sb_meta_uuid,
     471             :                         sizeof(rsb->rsb_meta_uuid));
     472             : 
     473       10279 :         *bpp = bp;
     474       10279 :         return 0;
     475             : }
     476             : 
     477             : /*
     478             :  * Update all the realtime superblocks to match the new state of the primary.
     479             :  * Because we are completely overwriting all the existing fields in the
     480             :  * secondary superblock buffers, there is no need to read them in from disk.
     481             :  * Just get a new buffer, stamp it and write it.
     482             :  *
     483             :  * The rt super buffers do not need to be kept them in memory once they are
     484             :  * written so we mark them as a one-shot buffer.
     485             :  */
     486             : int
     487         993 : xfs_rtgroup_update_secondary_sbs(
     488             :         struct xfs_mount        *mp)
     489             : {
     490         993 :         LIST_HEAD               (buffer_list);
     491         993 :         struct xfs_rtgroup      *rtg;
     492         993 :         xfs_rgnumber_t          start_rgno = 1;
     493         993 :         int                     saved_error = 0;
     494         993 :         int                     error = 0;
     495             : 
     496        4844 :         for_each_rtgroup_from(mp, start_rgno, rtg) {
     497        3851 :                 struct xfs_buf          *bp;
     498             : 
     499        3851 :                 error = xfs_rtgroup_init_secondary_super(mp, rtg->rtg_rgno,
     500             :                                 &bp);
     501             :                 /*
     502             :                  * If we get an error reading or writing alternate superblocks,
     503             :                  * continue.  If we break early, we'll leave more superblocks
     504             :                  * un-updated than updated.
     505             :                  */
     506        3851 :                 if (error) {
     507           0 :                         xfs_warn(mp,
     508             :                 "error allocating secondary superblock for rt group %d",
     509             :                                 rtg->rtg_rgno);
     510           0 :                         if (!saved_error)
     511           0 :                                 saved_error = error;
     512        3664 :                         continue;
     513             :                 }
     514             : 
     515        3851 :                 xfs_buf_oneshot(bp);
     516        3851 :                 xfs_buf_delwri_queue(bp, &buffer_list);
     517        3851 :                 xfs_buf_relse(bp);
     518             : 
     519             :                 /* don't hold too many buffers at once */
     520        3851 :                 if (rtg->rtg_rgno % 16)
     521        3664 :                         continue;
     522             : 
     523         187 :                 error = xfs_buf_delwri_submit(&buffer_list);
     524         187 :                 if (error) {
     525           0 :                         xfs_warn(mp,
     526             :         "write error %d updating a secondary superblock near rt group %u",
     527             :                                 error, rtg->rtg_rgno);
     528           0 :                         if (!saved_error)
     529           0 :                                 saved_error = error;
     530           0 :                         continue;
     531             :                 }
     532             :         }
     533         993 :         error = xfs_buf_delwri_submit(&buffer_list);
     534         993 :         if (error) {
     535           0 :                 xfs_warn(mp,
     536             :         "write error %d updating a secondary superblock near rt group %u",
     537             :                         error, start_rgno);
     538             :         }
     539             : 
     540         993 :         return saved_error ? saved_error : error;
     541             : }
     542             : 
     543             : /* Lock metadata inodes associated with this rt group. */
     544             : void
     545   640127933 : xfs_rtgroup_lock(
     546             :         struct xfs_trans        *tp,
     547             :         struct xfs_rtgroup      *rtg,
     548             :         unsigned int            rtglock_flags)
     549             : {
     550   640127933 :         ASSERT(!(rtglock_flags & ~XFS_RTGLOCK_ALL_FLAGS));
     551   640127933 :         ASSERT(!(rtglock_flags & XFS_RTGLOCK_BITMAP_SHARED) ||
     552             :                !(rtglock_flags & XFS_RTGLOCK_BITMAP));
     553             : 
     554   640127933 :         if (rtglock_flags & XFS_RTGLOCK_BITMAP)
     555       64711 :                 xfs_rtbitmap_lock(tp, rtg->rtg_mount);
     556   640063222 :         else if (rtglock_flags & XFS_RTGLOCK_BITMAP_SHARED)
     557   188574341 :                 xfs_rtbitmap_lock_shared(rtg->rtg_mount, XFS_RBMLOCK_BITMAP);
     558             : 
     559   640093626 :         if ((rtglock_flags & XFS_RTGLOCK_RMAP) && rtg->rtg_rmapip) {
     560   474134975 :                 xfs_ilock(rtg->rtg_rmapip, XFS_ILOCK_EXCL);
     561   474269682 :                 if (tp)
     562   284440202 :                         xfs_trans_ijoin(tp, rtg->rtg_rmapip, XFS_ILOCK_EXCL);
     563             :         }
     564             : 
     565   640228690 :         if ((rtglock_flags & XFS_RTGLOCK_REFCOUNT) && rtg->rtg_refcountip) {
     566   354744551 :                 xfs_ilock(rtg->rtg_refcountip, XFS_ILOCK_EXCL);
     567   354856181 :                 if (tp)
     568   103679849 :                         xfs_trans_ijoin(tp, rtg->rtg_refcountip,
     569             :                                         XFS_ILOCK_EXCL);
     570             :         }
     571   640340638 : }
     572             : 
     573             : /* Unlock metadata inodes associated with this rt group. */
     574             : void
     575   252207532 : xfs_rtgroup_unlock(
     576             :         struct xfs_rtgroup      *rtg,
     577             :         unsigned int            rtglock_flags)
     578             : {
     579   252207532 :         ASSERT(!(rtglock_flags & ~XFS_RTGLOCK_ALL_FLAGS));
     580   252207532 :         ASSERT(!(rtglock_flags & XFS_RTGLOCK_BITMAP_SHARED) ||
     581             :                !(rtglock_flags & XFS_RTGLOCK_BITMAP));
     582             : 
     583   252207532 :         if ((rtglock_flags & XFS_RTGLOCK_REFCOUNT) && rtg->rtg_refcountip)
     584   251160781 :                 xfs_iunlock(rtg->rtg_refcountip, XFS_ILOCK_EXCL);
     585             : 
     586   251986624 :         if ((rtglock_flags & XFS_RTGLOCK_RMAP) && rtg->rtg_rmapip)
     587   189648750 :                 xfs_iunlock(rtg->rtg_rmapip, XFS_ILOCK_EXCL);
     588             : 
     589   252270855 :         if (rtglock_flags & XFS_RTGLOCK_BITMAP)
     590       64711 :                 xfs_rtbitmap_unlock(rtg->rtg_mount);
     591   252206144 :         else if (rtglock_flags & XFS_RTGLOCK_BITMAP_SHARED)
     592   188743535 :                 xfs_rtbitmap_unlock_shared(rtg->rtg_mount, XFS_RBMLOCK_BITMAP);
     593   252231651 : }
     594             : 
     595             : /* Retrieve rt group geometry. */
     596             : int
     597       19471 : xfs_rtgroup_get_geometry(
     598             :         struct xfs_rtgroup      *rtg,
     599             :         struct xfs_rtgroup_geometry *rgeo)
     600             : {
     601             :         /* Fill out form. */
     602       19471 :         memset(rgeo, 0, sizeof(*rgeo));
     603       19471 :         rgeo->rg_number = rtg->rtg_rgno;
     604       19471 :         rgeo->rg_length = rtg->rtg_blockcount;
     605       19471 :         xfs_rtgroup_geom_health(rtg, rgeo);
     606       19471 :         return 0;
     607             : }

Generated by: LCOV version 1.14