LCOV - code coverage report
Current view: top level - fs/xfs/libxfs - xfs_rtbitmap.c (source / functions) Hit Total Coverage
Test: fstests of 6.5.0-rc4-xfsa @ Mon Jul 31 20:08:27 PDT 2023 Lines: 475 523 90.8 %
Date: 2023-07-31 20:08:27 Functions: 29 29 100.0 %

          Line data    Source code
       1             : // SPDX-License-Identifier: GPL-2.0
       2             : /*
       3             :  * Copyright (c) 2000-2005 Silicon Graphics, Inc.
       4             :  * All Rights Reserved.
       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_bit.h"
      13             : #include "xfs_mount.h"
      14             : #include "xfs_inode.h"
      15             : #include "xfs_bmap.h"
      16             : #include "xfs_trans.h"
      17             : #include "xfs_rtalloc.h"
      18             : #include "xfs_error.h"
      19             : #include "xfs_health.h"
      20             : #include "xfs_rtbitmap.h"
      21             : #include "xfs_log.h"
      22             : #include "xfs_buf_item.h"
      23             : #include "xfs_errortag.h"
      24             : 
      25             : /*
      26             :  * Realtime allocator bitmap functions shared with userspace.
      27             :  */
      28             : 
      29             : static xfs_failaddr_t
      30     2973225 : xfs_rtbuf_verify(
      31             :         struct xfs_buf                  *bp)
      32             : {
      33     2973225 :         struct xfs_mount                *mp = bp->b_mount;
      34     2973225 :         struct xfs_rtbuf_blkinfo        *hdr = bp->b_addr;
      35             : 
      36     2973225 :         if (!xfs_verify_magic(bp, hdr->rt_magic))
      37           0 :                 return __this_address;
      38     2973225 :         if (!xfs_has_rtgroups(mp))
      39           0 :                 return __this_address;
      40     2973225 :         if (!xfs_has_crc(mp))
      41           0 :                 return __this_address;
      42     2973225 :         if (!uuid_equal(&hdr->rt_uuid, &mp->m_sb.sb_meta_uuid))
      43           0 :                 return __this_address;
      44     2973225 :         if (hdr->rt_blkno != cpu_to_be64(xfs_buf_daddr(bp)))
      45           0 :                 return __this_address;
      46             :         return NULL;
      47             : }
      48             : 
      49             : static void
      50      161293 : xfs_rtbuf_verify_read(
      51             :         struct xfs_buf                  *bp)
      52             : {
      53      161293 :         struct xfs_mount                *mp = bp->b_mount;
      54      161293 :         struct xfs_rtbuf_blkinfo        *hdr = bp->b_addr;
      55      161293 :         xfs_failaddr_t                  fa;
      56             : 
      57      161293 :         if (!xfs_has_rtgroups(mp))
      58             :                 return;
      59             : 
      60      161293 :         if (!xfs_log_check_lsn(mp, be64_to_cpu(hdr->rt_lsn))) {
      61           0 :                 fa = __this_address;
      62           0 :                 goto fail;
      63             :         }
      64             : 
      65      161293 :         if (!xfs_buf_verify_cksum(bp, XFS_RTBUF_CRC_OFF)) {
      66           0 :                 fa = __this_address;
      67           0 :                 goto fail;
      68             :         }
      69             : 
      70      161293 :         fa = xfs_rtbuf_verify(bp);
      71      161293 :         if (fa)
      72           0 :                 goto fail;
      73             : 
      74             :         return;
      75           0 : fail:
      76           0 :         xfs_verifier_error(bp, -EFSCORRUPTED, fa);
      77             : }
      78             : 
      79             : static void
      80     2811941 : xfs_rtbuf_verify_write(
      81             :         struct xfs_buf  *bp)
      82             : {
      83     2811941 :         struct xfs_mount                *mp = bp->b_mount;
      84     2811941 :         struct xfs_rtbuf_blkinfo        *hdr = bp->b_addr;
      85     2811941 :         struct xfs_buf_log_item         *bip = bp->b_log_item;
      86     2811941 :         xfs_failaddr_t                  fa;
      87             : 
      88     2811941 :         if (!xfs_has_rtgroups(mp))
      89             :                 return;
      90             : 
      91     2811932 :         fa = xfs_rtbuf_verify(bp);
      92     2811932 :         if (fa) {
      93           0 :                 xfs_verifier_error(bp, -EFSCORRUPTED, fa);
      94           0 :                 return;
      95             :         }
      96             : 
      97     2811932 :         if (bip)
      98      856371 :                 hdr->rt_lsn = cpu_to_be64(bip->bli_item.li_lsn);
      99     2811932 :         xfs_buf_update_cksum(bp, XFS_RTBUF_CRC_OFF);
     100             : }
     101             : 
     102             : const struct xfs_buf_ops xfs_rtbuf_ops = {
     103             :         .name = "rtbuf",
     104             :         .verify_read = xfs_rtbuf_verify_read,
     105             :         .verify_write = xfs_rtbuf_verify_write,
     106             : };
     107             : 
     108             : const struct xfs_buf_ops xfs_rtbitmap_buf_ops = {
     109             :         .name           = "xfs_rtbitmap",
     110             :         .magic          = { 0, cpu_to_be32(XFS_RTBITMAP_MAGIC) },
     111             :         .verify_read    = xfs_rtbuf_verify_read,
     112             :         .verify_write   = xfs_rtbuf_verify_write,
     113             :         .verify_struct  = xfs_rtbuf_verify,
     114             : };
     115             : 
     116             : const struct xfs_buf_ops xfs_rtsummary_buf_ops = {
     117             :         .name           = "xfs_rtsummary",
     118             :         .magic          = { 0, cpu_to_be32(XFS_RTSUMMARY_MAGIC) },
     119             :         .verify_read    = xfs_rtbuf_verify_read,
     120             :         .verify_write   = xfs_rtbuf_verify_write,
     121             :         .verify_struct  = xfs_rtbuf_verify,
     122             : };
     123             : 
     124             : /*
     125             :  * Get a buffer for the bitmap or summary file block specified.
     126             :  * The buffer is returned read and locked.
     127             :  */
     128             : int
     129  2069118291 : xfs_rtbuf_get(
     130             :         xfs_mount_t     *mp,            /* file system mount structure */
     131             :         xfs_trans_t     *tp,            /* transaction pointer */
     132             :         xfs_fileoff_t   block,          /* block number in bitmap or summary */
     133             :         int             issum,          /* is summary not bitmap */
     134             :         struct xfs_buf  **bpp)          /* output: buffer for the block */
     135             : {
     136  2069118291 :         struct xfs_buf  *bp;            /* block buffer, result */
     137  2069118291 :         xfs_inode_t     *ip;            /* bitmap or summary inode */
     138  2069118291 :         xfs_bmbt_irec_t map;
     139  2069118291 :         int             nmap = 1;
     140  2069118291 :         int             error;          /* error value */
     141             : 
     142  2069118291 :         ip = issum ? mp->m_rsumip : mp->m_rbmip;
     143             : 
     144  2069118291 :         error = xfs_bmapi_read(ip, block, 1, &map, &nmap, 0);
     145  2069117762 :         if (error)
     146             :                 return error;
     147             : 
     148  2069117762 :         if (XFS_IS_CORRUPT(mp, nmap == 0 || !xfs_bmap_is_written_extent(&map))) {
     149           0 :                 xfs_rt_mark_sick(mp, issum ? XFS_SICK_RT_SUMMARY :
     150             :                                              XFS_SICK_RT_BITMAP);
     151           0 :                 return -EFSCORRUPTED;
     152             :         }
     153             : 
     154  2069117762 :         ASSERT(map.br_startblock != NULLFSBLOCK);
     155  2069117762 :         error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp,
     156  2069117762 :                                    XFS_FSB_TO_DADDR(mp, map.br_startblock),
     157             :                                    mp->m_bsize, 0, &bp,
     158             :                                    xfs_rtblock_ops(mp, issum));
     159  2069135059 :         if (xfs_metadata_is_sick(error))
     160           0 :                 xfs_rt_mark_sick(mp, issum ? XFS_SICK_RT_SUMMARY :
     161             :                                              XFS_SICK_RT_BITMAP);
     162  2069135059 :         if (error)
     163             :                 return error;
     164             : 
     165  2069135059 :         if (xfs_has_rtgroups(mp)) {
     166  2069135826 :                 struct xfs_rtbuf_blkinfo *hdr = bp->b_addr;
     167             : 
     168  2069135826 :                 if (hdr->rt_owner != cpu_to_be64(ip->i_ino)) {
     169           0 :                         xfs_buf_mark_corrupt(bp);
     170           0 :                         xfs_trans_brelse(tp, bp);
     171           0 :                         xfs_rt_mark_sick(mp, issum ? XFS_SICK_RT_SUMMARY :
     172             :                                                      XFS_SICK_RT_BITMAP);
     173           0 :                         return -EFSCORRUPTED;
     174             :                 }
     175             :         }
     176             : 
     177  4042737876 :         xfs_trans_buf_set_type(tp, bp, issum ? XFS_BLFT_RTSUMMARY_BUF
     178             :                                              : XFS_BLFT_RTBITMAP_BUF);
     179  2069137333 :         *bpp = bp;
     180  2069137333 :         return 0;
     181             : }
     182             : 
     183             : /* Convert an ondisk bitmap word to its incore representation. */
     184             : inline xfs_rtword_t
     185      839620 : xfs_rtbitmap_getword(
     186             :         struct xfs_mount        *mp,
     187             :         union xfs_rtword_ondisk *wordptr)
     188             : {
     189      839620 :         if (xfs_has_rtgroups(mp))
     190 >19251*10^7 :                 return le32_to_cpu(wordptr->rtg);
     191             : 
     192           0 :         return wordptr->raw;
     193             : }
     194             : 
     195             : /* Set an ondisk bitmap word from an incore representation. */
     196             : inline void
     197      839620 : xfs_rtbitmap_setword(
     198             :         struct xfs_mount        *mp,
     199             :         union xfs_rtword_ondisk *wordptr,
     200             :         xfs_rtword_t            incore)
     201             : {
     202      839620 :         if (xfs_has_rtgroups(mp))
     203    54076703 :                 wordptr->rtg = cpu_to_le32(incore);
     204             :         else
     205           0 :                 wordptr->raw = incore;
     206      839620 : }
     207             : 
     208             : /*
     209             :  * Searching backward from start to limit, find the first block whose
     210             :  * allocated/free state is different from start's.
     211             :  */
     212             : int
     213    39592179 : xfs_rtfind_back(
     214             :         xfs_mount_t     *mp,            /* file system mount point */
     215             :         xfs_trans_t     *tp,            /* transaction pointer */
     216             :         xfs_rtxnum_t    start,          /* starting rtext to look at */
     217             :         xfs_rtxnum_t    limit,          /* last rtext to look at */
     218             :         xfs_rtxnum_t    *rtx)           /* out: start rtext found */
     219             : {
     220    39592179 :         union xfs_rtword_ondisk *b;             /* current word in buffer */
     221    39592179 :         int             bit;            /* bit number in the word */
     222    39592179 :         xfs_fileoff_t   block;          /* bitmap block number */
     223    39592179 :         struct xfs_buf  *bp;            /* buf for the block */
     224    39592179 :         int             error;          /* error value */
     225    39592179 :         xfs_rtxnum_t    firstbit;       /* first useful bit in the word */
     226    39592179 :         xfs_rtxnum_t    i;              /* current bit number rel. to start */
     227    39592179 :         xfs_rtxnum_t    len;            /* length of inspected area */
     228    39592179 :         xfs_rtword_t    mask;           /* mask of relevant bits for value */
     229    39592179 :         xfs_rtword_t    want;           /* mask for "good" values */
     230    39592179 :         xfs_rtword_t    wdiff;          /* difference from wanted value */
     231    39592179 :         xfs_rtword_t    incore;
     232    39592179 :         int             word;           /* word number in the buffer */
     233             : 
     234             :         /*
     235             :          * Compute and read in starting bitmap block for starting block.
     236             :          */
     237    39592179 :         block = xfs_rtx_to_rbmblock(mp, start);
     238    39592179 :         error = xfs_rtbuf_get(mp, tp, block, 0, &bp);
     239    39592179 :         if (error) {
     240             :                 return error;
     241             :         }
     242             : 
     243             :         /*
     244             :          * Get the first word's index & point to it.
     245             :          */
     246    39592179 :         word = xfs_rtx_to_rbmword(mp, start);
     247    39592179 :         b = xfs_rbmblock_wordptr(bp, word);
     248    39592179 :         bit = (int)(start & (XFS_NBWORD - 1));
     249    39592179 :         len = start - limit + 1;
     250             :         /*
     251             :          * Compute match value, based on the bit at start: if 1 (free)
     252             :          * then all-ones, else all-zeroes.
     253             :          */
     254    39592179 :         incore = xfs_rtbitmap_getword(mp, b);
     255    39592179 :         want = (incore & ((xfs_rtword_t)1 << bit)) ? -1 : 0;
     256             :         /*
     257             :          * If the starting position is not word-aligned, deal with the
     258             :          * partial word.
     259             :          */
     260    39592179 :         if (bit < XFS_NBWORD - 1) {
     261             :                 /*
     262             :                  * Calculate first (leftmost) bit number to look at,
     263             :                  * and mask for all the relevant bits in this word.
     264             :                  */
     265    38364154 :                 firstbit = XFS_RTMAX((xfs_srtblock_t)(bit - len + 1), 0);
     266    38364154 :                 mask = (((xfs_rtword_t)1 << (bit - firstbit + 1)) - 1) <<
     267             :                         firstbit;
     268             :                 /*
     269             :                  * Calculate the difference between the value there
     270             :                  * and what we're looking for.
     271             :                  */
     272    38364154 :                 if ((wdiff = (incore ^ want) & mask)) {
     273             :                         /*
     274             :                          * Different.  Mark where we are and return.
     275             :                          */
     276    36572906 :                         xfs_trans_brelse(tp, bp);
     277    36572906 :                         i = bit - XFS_RTHIBIT(wdiff);
     278    36572906 :                         *rtx = start - i + 1;
     279    36572906 :                         return 0;
     280             :                 }
     281     1791248 :                 i = bit - firstbit + 1;
     282             :                 /*
     283             :                  * Go on to previous block if that's where the previous word is
     284             :                  * and we need the previous word.
     285             :                  */
     286     1791248 :                 if (--word == -1 && i < len) {
     287             :                         /*
     288             :                          * If done with this block, get the previous one.
     289             :                          */
     290      113896 :                         xfs_trans_brelse(tp, bp);
     291      113896 :                         error = xfs_rtbuf_get(mp, tp, --block, 0, &bp);
     292      113896 :                         if (error) {
     293             :                                 return error;
     294             :                         }
     295             : 
     296      113896 :                         word = mp->m_blockwsize - 1;
     297      227792 :                         b = xfs_rbmblock_wordptr(bp, word);
     298             :                 } else {
     299             :                         /*
     300             :                          * Go on to the previous word in the buffer.
     301             :                          */
     302     1677352 :                         b--;
     303             :                 }
     304             :         } else {
     305             :                 /*
     306             :                  * Starting on a word boundary, no partial word.
     307             :                  */
     308             :                 i = 0;
     309             :         }
     310             :         /*
     311             :          * Loop over whole words in buffers.  When we use up one buffer
     312             :          * we move on to the previous one.
     313             :          */
     314  5232166026 :         while (len - i >= XFS_NBWORD) {
     315             :                 /*
     316             :                  * Compute difference between actual and desired value.
     317             :                  */
     318  5232166026 :                 incore = xfs_rtbitmap_getword(mp, b);
     319  5232166026 :                 if ((wdiff = incore ^ want)) {
     320             :                         /*
     321             :                          * Different, mark where we are and return.
     322             :                          */
     323     3019273 :                         xfs_trans_brelse(tp, bp);
     324     3019273 :                         i += XFS_NBWORD - 1 - XFS_RTHIBIT(wdiff);
     325     3019273 :                         *rtx = start - i + 1;
     326     3019273 :                         return 0;
     327             :                 }
     328  5229146753 :                 i += XFS_NBWORD;
     329             :                 /*
     330             :                  * Go on to previous block if that's where the previous word is
     331             :                  * and we need the previous word.
     332             :                  */
     333  5229146753 :                 if (--word == -1 && i < len) {
     334             :                         /*
     335             :                          * If done with this block, get the previous one.
     336             :                          */
     337     5094883 :                         xfs_trans_brelse(tp, bp);
     338     5094883 :                         error = xfs_rtbuf_get(mp, tp, --block, 0, &bp);
     339     5094883 :                         if (error) {
     340           0 :                                 return error;
     341             :                         }
     342             : 
     343     5094883 :                         word = mp->m_blockwsize - 1;
     344    10189766 :                         b = xfs_rbmblock_wordptr(bp, word);
     345             :                 } else {
     346             :                         /*
     347             :                          * Go on to the previous word in the buffer.
     348             :                          */
     349  5224051870 :                         b--;
     350             :                 }
     351             :         }
     352             :         /*
     353             :          * If not ending on a word boundary, deal with the last
     354             :          * (partial) word.
     355             :          */
     356           0 :         if (len - i) {
     357             :                 /*
     358             :                  * Calculate first (leftmost) bit number to look at,
     359             :                  * and mask for all the relevant bits in this word.
     360             :                  */
     361           0 :                 firstbit = XFS_NBWORD - (len - i);
     362           0 :                 mask = (((xfs_rtword_t)1 << (len - i)) - 1) << firstbit;
     363             :                 /*
     364             :                  * Compute difference between actual and desired value.
     365             :                  */
     366           0 :                 incore = xfs_rtbitmap_getword(mp, b);
     367           0 :                 if ((wdiff = (incore ^ want) & mask)) {
     368             :                         /*
     369             :                          * Different, mark where we are and return.
     370             :                          */
     371           0 :                         xfs_trans_brelse(tp, bp);
     372           0 :                         i += XFS_NBWORD - 1 - XFS_RTHIBIT(wdiff);
     373           0 :                         *rtx = start - i + 1;
     374           0 :                         return 0;
     375             :                 } else
     376             :                         i = len;
     377             :         }
     378             :         /*
     379             :          * No match, return that we scanned the whole area.
     380             :          */
     381           0 :         xfs_trans_brelse(tp, bp);
     382           0 :         *rtx = start - i + 1;
     383           0 :         return 0;
     384             : }
     385             : 
     386             : /*
     387             :  * Searching forward from start to limit, find the first block whose
     388             :  * allocated/free state is different from start's.
     389             :  */
     390             : int
     391   528791815 : xfs_rtfind_forw(
     392             :         xfs_mount_t     *mp,            /* file system mount point */
     393             :         xfs_trans_t     *tp,            /* transaction pointer */
     394             :         xfs_rtxnum_t    start,          /* starting rtext to look at */
     395             :         xfs_rtxnum_t    limit,          /* last rtext to look at */
     396             :         xfs_rtxnum_t    *rtx)           /* out: start rtext found */
     397             : {
     398   528791815 :         union xfs_rtword_ondisk *b;             /* current word in buffer */
     399   528791815 :         int             bit;            /* bit number in the word */
     400   528791815 :         xfs_fileoff_t   block;          /* bitmap block number */
     401   528791815 :         struct xfs_buf  *bp;            /* buf for the block */
     402   528791815 :         int             error;          /* error value */
     403   528791815 :         xfs_rtxnum_t    i;              /* current bit number rel. to start */
     404   528791815 :         xfs_rtxnum_t    lastbit;        /* last useful bit in the word */
     405   528791815 :         xfs_rtxnum_t    len;            /* length of inspected area */
     406   528791815 :         xfs_rtword_t    mask;           /* mask of relevant bits for value */
     407   528791815 :         xfs_rtword_t    want;           /* mask for "good" values */
     408   528791815 :         xfs_rtword_t    wdiff;          /* difference from wanted value */
     409   528791815 :         xfs_rtword_t    incore;
     410   528791815 :         int             word;           /* word number in the buffer */
     411             : 
     412             :         /*
     413             :          * Compute and read in starting bitmap block for starting block.
     414             :          */
     415   528791815 :         block = xfs_rtx_to_rbmblock(mp, start);
     416   528791815 :         error = xfs_rtbuf_get(mp, tp, block, 0, &bp);
     417   528791806 :         if (error) {
     418             :                 return error;
     419             :         }
     420             : 
     421             :         /*
     422             :          * Get the first word's index & point to it.
     423             :          */
     424   528791806 :         word = xfs_rtx_to_rbmword(mp, start);
     425   528791806 :         b = xfs_rbmblock_wordptr(bp, word);
     426   528791806 :         bit = (int)(start & (XFS_NBWORD - 1));
     427   528791806 :         len = limit - start + 1;
     428             :         /*
     429             :          * Compute match value, based on the bit at start: if 1 (free)
     430             :          * then all-ones, else all-zeroes.
     431             :          */
     432   528791806 :         incore = xfs_rtbitmap_getword(mp, b);
     433   528791806 :         want = (incore & ((xfs_rtword_t)1 << bit)) ? -1 : 0;
     434             :         /*
     435             :          * If the starting position is not word-aligned, deal with the
     436             :          * partial word.
     437             :          */
     438   528791806 :         if (bit) {
     439             :                 /*
     440             :                  * Calculate last (rightmost) bit number to look at,
     441             :                  * and mask for all the relevant bits in this word.
     442             :                  */
     443   444177016 :                 lastbit = XFS_RTMIN(bit + len, XFS_NBWORD);
     444   444177016 :                 mask = (((xfs_rtword_t)1 << (lastbit - bit)) - 1) << bit;
     445             :                 /*
     446             :                  * Calculate the difference between the value there
     447             :                  * and what we're looking for.
     448             :                  */
     449   444177016 :                 if ((wdiff = (incore ^ want) & mask)) {
     450             :                         /*
     451             :                          * Different.  Mark where we are and return.
     452             :                          */
     453   151229296 :                         xfs_trans_brelse(tp, bp);
     454   151229294 :                         i = XFS_RTLOBIT(wdiff) - bit;
     455   151229294 :                         *rtx = start + i - 1;
     456   151229294 :                         return 0;
     457             :                 }
     458   292947720 :                 i = lastbit - bit;
     459             :                 /*
     460             :                  * Go on to next block if that's where the next word is
     461             :                  * and we need the next word.
     462             :                  */
     463   292947720 :                 if (++word == mp->m_blockwsize && i < len) {
     464             :                         /*
     465             :                          * If done with this block, get the previous one.
     466             :                          */
     467      493879 :                         xfs_trans_brelse(tp, bp);
     468      493879 :                         error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp);
     469      493879 :                         if (error) {
     470             :                                 return error;
     471             :                         }
     472             : 
     473      493879 :                         word = 0;
     474      493879 :                         b = xfs_rbmblock_wordptr(bp, word);
     475             :                 } else {
     476             :                         /*
     477             :                          * Go on to the previous word in the buffer.
     478             :                          */
     479   292453841 :                         b++;
     480             :                 }
     481             :         } else {
     482             :                 /*
     483             :                  * Starting on a word boundary, no partial word.
     484             :                  */
     485             :                 i = 0;
     486             :         }
     487             :         /*
     488             :          * Loop over whole words in buffers.  When we use up one buffer
     489             :          * we move on to the next one.
     490             :          */
     491 >18545*10^7 :         while (len - i >= XFS_NBWORD) {
     492             :                 /*
     493             :                  * Compute difference between actual and desired value.
     494             :                  */
     495 >18539*10^7 :                 incore = xfs_rtbitmap_getword(mp, b);
     496 >18539*10^7 :                 if ((wdiff = incore ^ want)) {
     497             :                         /*
     498             :                          * Different, mark where we are and return.
     499             :                          */
     500   320200426 :                         xfs_trans_brelse(tp, bp);
     501   320200464 :                         i += XFS_RTLOBIT(wdiff);
     502   320200464 :                         *rtx = start + i - 1;
     503   320200464 :                         return 0;
     504             :                 }
     505 >18507*10^7 :                 i += XFS_NBWORD;
     506             :                 /*
     507             :                  * Go on to next block if that's where the next word is
     508             :                  * and we need the next word.
     509             :                  */
     510 >18507*10^7 :                 if (++word == mp->m_blockwsize && i < len) {
     511             :                         /*
     512             :                          * If done with this block, get the next one.
     513             :                          */
     514   122246324 :                         xfs_trans_brelse(tp, bp);
     515   122246350 :                         error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp);
     516   122246302 :                         if (error) {
     517           0 :                                 return error;
     518             :                         }
     519             : 
     520   122246302 :                         word = 0;
     521   122246302 :                         b = xfs_rbmblock_wordptr(bp, word);
     522             :                 } else {
     523             :                         /*
     524             :                          * Go on to the next word in the buffer.
     525             :                          */
     526 >18495*10^7 :                         b++;
     527             :                 }
     528             :         }
     529             :         /*
     530             :          * If not ending on a word boundary, deal with the last
     531             :          * (partial) word.
     532             :          */
     533    57362062 :         if ((lastbit = len - i)) {
     534             :                 /*
     535             :                  * Calculate mask for all the relevant bits in this word.
     536             :                  */
     537          12 :                 mask = ((xfs_rtword_t)1 << lastbit) - 1;
     538             :                 /*
     539             :                  * Compute difference between actual and desired value.
     540             :                  */
     541          12 :                 incore = xfs_rtbitmap_getword(mp, b);
     542          12 :                 if ((wdiff = (incore ^ want) & mask)) {
     543             :                         /*
     544             :                          * Different, mark where we are and return.
     545             :                          */
     546           6 :                         xfs_trans_brelse(tp, bp);
     547           6 :                         i += XFS_RTLOBIT(wdiff);
     548           6 :                         *rtx = start + i - 1;
     549           6 :                         return 0;
     550             :                 } else
     551             :                         i = len;
     552             :         }
     553             :         /*
     554             :          * No match, return that we scanned the whole area.
     555             :          */
     556    57362056 :         xfs_trans_brelse(tp, bp);
     557    57362056 :         *rtx = start + i - 1;
     558    57362056 :         return 0;
     559             : }
     560             : 
     561             : inline xfs_suminfo_t
     562  1740854650 : xfs_suminfo_get(
     563             :         struct xfs_mount        *mp,
     564             :         union xfs_suminfo_ondisk *infoptr)
     565             : {
     566  1740854650 :         if (xfs_has_rtgroups(mp))
     567  1740854650 :                 return be32_to_cpu(infoptr->rtg);
     568             : 
     569           0 :         return infoptr->raw;
     570             : }
     571             : 
     572             : inline void
     573    58989117 : xfs_suminfo_add(
     574             :         struct xfs_mount        *mp,
     575             :         union xfs_suminfo_ondisk *infoptr,
     576             :         int                     delta)
     577             : {
     578    58989117 :         if (xfs_has_rtgroups(mp))
     579    58989117 :                 be32_add_cpu(&infoptr->rtg, delta);
     580             :         else
     581           0 :                 infoptr->raw += delta;
     582    58989117 : }
     583             : 
     584             : /*
     585             :  * Read and/or modify the summary information for a given extent size,
     586             :  * bitmap block combination.
     587             :  * Keeps track of a current summary block, so we don't keep reading
     588             :  * it from the buffer cache.
     589             :  *
     590             :  * Summary information is returned in *sum if specified.
     591             :  * If no delta is specified, returns summary only.
     592             :  */
     593             : int
     594  1792461337 : xfs_rtmodify_summary_int(
     595             :         xfs_mount_t     *mp,            /* file system mount structure */
     596             :         xfs_trans_t     *tp,            /* transaction pointer */
     597             :         int             log,            /* log2 of extent size */
     598             :         xfs_fileoff_t   bbno,           /* bitmap block number */
     599             :         int             delta,          /* change to make to summary info */
     600             :         struct xfs_buf  **rbpp,         /* in/out: summary block buffer */
     601             :         xfs_fileoff_t   *rsb,           /* in/out: summary block number */
     602             :         xfs_suminfo_t   *sum)           /* out: summary info for this block */
     603             : {
     604  1792461337 :         struct xfs_buf  *bp;            /* buffer for the summary block */
     605  1792461337 :         int             error;          /* error value */
     606  1792461337 :         xfs_fileoff_t   sb;             /* summary fsblock */
     607  1792461337 :         xfs_rtsumoff_t  so;             /* index into the summary file */
     608  1792461337 :         union xfs_suminfo_ondisk *sp;           /* pointer to returned data */
     609  1792461337 :         unsigned int    infoword;
     610             : 
     611             :         /*
     612             :          * Compute entry number in the summary file.
     613             :          */
     614  1792461337 :         so = xfs_rtsumoffs(mp, log, bbno);
     615             :         /*
     616             :          * Compute the block number in the summary file.
     617             :          */
     618  1792461337 :         sb = xfs_rtsumoffs_to_block(mp, so);
     619             :         /*
     620             :          * If we have an old buffer, and the block number matches, use that.
     621             :          */
     622  1792461337 :         if (*rbpp && *rsb == sb)
     623  1697401713 :                 bp = *rbpp;
     624             :         /*
     625             :          * Otherwise we have to get the buffer.
     626             :          */
     627             :         else {
     628             :                 /*
     629             :                  * If there was an old one, get rid of it first.
     630             :                  */
     631    95059624 :                 if (*rbpp)
     632    55467441 :                         xfs_trans_brelse(tp, *rbpp);
     633    95059624 :                 error = xfs_rtbuf_get(mp, tp, sb, 1, &bp);
     634    95059624 :                 if (error) {
     635             :                         return error;
     636             :                 }
     637             :                 /*
     638             :                  * Remember this buffer and block for the next call.
     639             :                  */
     640    95059624 :                 *rbpp = bp;
     641    95059624 :                 *rsb = sb;
     642             :         }
     643             :         /*
     644             :          * Point to the summary information, modify/log it, and/or copy it out.
     645             :          */
     646  1792461337 :         infoword = xfs_rtsumoffs_to_infoword(mp, so);
     647  1792461337 :         sp = xfs_rsumblock_infoptr(bp, infoword);
     648  1792461337 :         if (delta) {
     649    51606687 :                 uint first = (uint)((char *)sp - (char *)bp->b_addr);
     650             : 
     651    51606687 :                 xfs_suminfo_add(mp, sp, delta);
     652    51606687 :                 if (mp->m_rsum_cache) {
     653    51606687 :                         if (sp->raw == 0 && log == mp->m_rsum_cache[bbno])
     654    10472918 :                                 mp->m_rsum_cache[bbno]++;
     655    51606687 :                         if (sp->raw != 0 && log < mp->m_rsum_cache[bbno])
     656    11769546 :                                 mp->m_rsum_cache[bbno] = log;
     657             :                 }
     658    51606687 :                 xfs_trans_log_buf(tp, bp, first, first + sizeof(*sp) - 1);
     659             :         }
     660  1792461337 :         if (sum)
     661  1740854650 :                 *sum = xfs_suminfo_get(mp, sp);
     662             :         return 0;
     663             : }
     664             : 
     665             : int
     666    33784901 : xfs_rtmodify_summary(
     667             :         xfs_mount_t     *mp,            /* file system mount structure */
     668             :         xfs_trans_t     *tp,            /* transaction pointer */
     669             :         int             log,            /* log2 of extent size */
     670             :         xfs_fileoff_t   bbno,           /* bitmap block number */
     671             :         int             delta,          /* change to make to summary info */
     672             :         struct xfs_buf  **rbpp,         /* in/out: summary block buffer */
     673             :         xfs_fileoff_t   *rsb)           /* in/out: summary block number */
     674             : {
     675    35784282 :         return xfs_rtmodify_summary_int(mp, tp, log, bbno,
     676             :                                         delta, rbpp, rsb, NULL);
     677             : }
     678             : 
     679             : /*
     680             :  * Set the given range of bitmap bits to the given value.
     681             :  * Do whatever I/O and logging is required.
     682             :  */
     683             : int
     684    39592179 : xfs_rtmodify_range(
     685             :         xfs_mount_t     *mp,            /* file system mount point */
     686             :         xfs_trans_t     *tp,            /* transaction pointer */
     687             :         xfs_rtxnum_t    start,          /* starting rtext to modify */
     688             :         xfs_rtxlen_t    len,            /* length of extent to modify */
     689             :         int             val)            /* 1 for free, 0 for allocated */
     690             : {
     691    39592179 :         union xfs_rtword_ondisk *b;             /* current word in buffer */
     692    39592179 :         int             bit;            /* bit number in the word */
     693    39592179 :         xfs_fileoff_t   block;          /* bitmap block number */
     694    39592179 :         struct xfs_buf  *bp;            /* buf for the block */
     695    39592179 :         int             error;          /* error value */
     696    39592179 :         union xfs_rtword_ondisk *first;         /* first used word in the buffer */
     697    39592179 :         int             i;              /* current bit number rel. to start */
     698    39592179 :         int             lastbit;        /* last useful bit in word */
     699    39592179 :         xfs_rtword_t    mask;           /* mask o frelevant bits for value */
     700    39592179 :         xfs_rtword_t    incore;
     701    39592179 :         int             word;           /* word number in the buffer */
     702             : 
     703             :         /*
     704             :          * Compute starting bitmap block number.
     705             :          */
     706    39592179 :         block = xfs_rtx_to_rbmblock(mp, start);
     707             :         /*
     708             :          * Read the bitmap block, and point to its data.
     709             :          */
     710    39592179 :         error = xfs_rtbuf_get(mp, tp, block, 0, &bp);
     711    39592179 :         if (error) {
     712             :                 return error;
     713             :         }
     714             : 
     715             :         /*
     716             :          * Compute the starting word's address, and starting bit.
     717             :          */
     718    39592179 :         word = xfs_rtx_to_rbmword(mp, start);
     719    39592179 :         first = b = xfs_rbmblock_wordptr(bp, word);
     720    39592179 :         bit = (int)(start & (XFS_NBWORD - 1));
     721             :         /*
     722             :          * 0 (allocated) => all zeroes; 1 (free) => all ones.
     723             :          */
     724    39592179 :         val = -val;
     725             :         /*
     726             :          * If not starting on a word boundary, deal with the first
     727             :          * (partial) word.
     728             :          */
     729    39592179 :         if (bit) {
     730             :                 /*
     731             :                  * Compute first bit not changed and mask of relevant bits.
     732             :                  */
     733    38270484 :                 lastbit = XFS_RTMIN(bit + len, XFS_NBWORD);
     734    38270484 :                 mask = (((xfs_rtword_t)1 << (lastbit - bit)) - 1) << bit;
     735             :                 /*
     736             :                  * Set/clear the active bits.
     737             :                  */
     738    38270484 :                 incore = xfs_rtbitmap_getword(mp, b);
     739    38270484 :                 if (val)
     740    15289984 :                         incore |= mask;
     741             :                 else
     742    22980500 :                         incore &= ~mask;
     743    38270484 :                 xfs_rtbitmap_setword(mp, b, incore);
     744    38270484 :                 i = lastbit - bit;
     745             :                 /*
     746             :                  * Go on to the next block if that's where the next word is
     747             :                  * and we need the next word.
     748             :                  */
     749    38270484 :                 if (++word == mp->m_blockwsize && i < len) {
     750             :                         /*
     751             :                          * Log the changed part of this block.
     752             :                          * Get the next one.
     753             :                          */
     754        8481 :                         xfs_trans_log_buf(tp, bp,
     755        8481 :                                 (uint)((char *)first - (char *)bp->b_addr),
     756             :                                 (uint)((char *)b - (char *)bp->b_addr));
     757        8481 :                         error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp);
     758        8481 :                         if (error) {
     759             :                                 return error;
     760             :                         }
     761             : 
     762        8481 :                         word = 0;
     763        8481 :                         first = b = xfs_rbmblock_wordptr(bp, word);
     764             :                 } else {
     765             :                         /*
     766             :                          * Go on to the next word in the buffer
     767             :                          */
     768    38262003 :                         b++;
     769             :                 }
     770             :         } else {
     771             :                 /*
     772             :                  * Starting on a word boundary, no partial word.
     773             :                  */
     774             :                 i = 0;
     775             :         }
     776             :         /*
     777             :          * Loop over whole words in buffers.  When we use up one buffer
     778             :          * we move on to the next one.
     779             :          */
     780    43521434 :         while (len - i >= XFS_NBWORD) {
     781             :                 /*
     782             :                  * Set the word value correctly.
     783             :                  */
     784     3929255 :                 xfs_rtbitmap_setword(mp, b, val);
     785     3929255 :                 i += XFS_NBWORD;
     786             :                 /*
     787             :                  * Go on to the next block if that's where the next word is
     788             :                  * and we need the next word.
     789             :                  */
     790     3929255 :                 if (++word == mp->m_blockwsize && i < len) {
     791             :                         /*
     792             :                          * Log the changed part of this block.
     793             :                          * Get the next one.
     794             :                          */
     795        1656 :                         xfs_trans_log_buf(tp, bp,
     796        1656 :                                 (uint)((char *)first - (char *)bp->b_addr),
     797        1656 :                                 (uint)((char *)b - (char *)bp->b_addr));
     798        1656 :                         error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp);
     799        1656 :                         if (error) {
     800           0 :                                 return error;
     801             :                         }
     802             : 
     803        1656 :                         word = 0;
     804        1656 :                         first = b = xfs_rbmblock_wordptr(bp, word);
     805             :                 } else {
     806             :                         /*
     807             :                          * Go on to the next word in the buffer
     808             :                          */
     809     3927599 :                         b++;
     810             :                 }
     811             :         }
     812             :         /*
     813             :          * If not ending on a word boundary, deal with the last
     814             :          * (partial) word.
     815             :          */
     816    39592179 :         if ((lastbit = len - i)) {
     817             :                 /*
     818             :                  * Compute a mask of relevant bits.
     819             :                  */
     820    11037344 :                 mask = ((xfs_rtword_t)1 << lastbit) - 1;
     821             :                 /*
     822             :                  * Set/clear the active bits.
     823             :                  */
     824    11037344 :                 incore = xfs_rtbitmap_getword(mp, b);
     825    11037344 :                 if (val)
     826     3813116 :                         incore |= mask;
     827             :                 else
     828     7224228 :                         incore &= ~mask;
     829    11037344 :                 xfs_rtbitmap_setword(mp, b, incore);
     830    11037344 :                 b++;
     831             :         }
     832             :         /*
     833             :          * Log any remaining changed bytes.
     834             :          */
     835    39592179 :         if (b > first)
     836    39592179 :                 xfs_trans_log_buf(tp, bp,
     837    39592179 :                         (uint)((char *)first - (char *)bp->b_addr),
     838    39592179 :                         (uint)((char *)b - (char *)bp->b_addr - 1));
     839             :         return 0;
     840             : }
     841             : 
     842             : /*
     843             :  * Mark an extent specified by start and len freed.
     844             :  * Updates all the summary information as well as the bitmap.
     845             :  */
     846             : int
     847    15822405 : xfs_rtfree_range(
     848             :         xfs_mount_t     *mp,            /* file system mount point */
     849             :         xfs_trans_t     *tp,            /* transaction pointer */
     850             :         xfs_rtxnum_t    start,          /* starting rtext to free */
     851             :         xfs_rtxlen_t    len,            /* length to free */
     852             :         struct xfs_buf  **rbpp,         /* in/out: summary block buffer */
     853             :         xfs_fileoff_t   *rsb)           /* in/out: summary block number */
     854             : {
     855    15822405 :         xfs_rtxnum_t    end;            /* end of the freed extent */
     856    15822405 :         int             error;          /* error value */
     857    15822405 :         xfs_rtxnum_t    postblock;      /* first rtext freed > end */
     858    15822405 :         xfs_rtxnum_t    preblock;       /* first rtext freed < start */
     859             : 
     860    15822405 :         end = start + len - 1;
     861             :         /*
     862             :          * Modify the bitmap to mark this extent freed.
     863             :          */
     864    15822405 :         error = xfs_rtmodify_range(mp, tp, start, len, 1);
     865    15822405 :         if (error) {
     866             :                 return error;
     867             :         }
     868             :         /*
     869             :          * Assume we're freeing out of the middle of an allocated extent.
     870             :          * We need to find the beginning and end of the extent so we can
     871             :          * properly update the summary.
     872             :          */
     873    15822405 :         error = xfs_rtfind_back(mp, tp, start, 0, &preblock);
     874    15822405 :         if (error) {
     875             :                 return error;
     876             :         }
     877             :         /*
     878             :          * Find the next allocated block (end of allocated extent).
     879             :          */
     880    15822405 :         error = xfs_rtfind_forw(mp, tp, end, mp->m_sb.sb_rextents - 1,
     881             :                 &postblock);
     882    15822405 :         if (error)
     883             :                 return error;
     884             :         /*
     885             :          * If there are blocks not being freed at the front of the
     886             :          * old extent, add summary data for them to be allocated.
     887             :          */
     888    15822405 :         if (preblock < start) {
     889     1069303 :                 error = xfs_rtmodify_summary(mp, tp,
     890             :                         XFS_RTBLOCKLOG(start - preblock),
     891             :                         xfs_rtx_to_rbmblock(mp, preblock), -1, rbpp, rsb);
     892     1069303 :                 if (error) {
     893             :                         return error;
     894             :                 }
     895             :         }
     896             :         /*
     897             :          * If there are blocks not being freed at the end of the
     898             :          * old extent, add summary data for them to be allocated.
     899             :          */
     900    15822405 :         if (postblock > end) {
     901      930078 :                 error = xfs_rtmodify_summary(mp, tp,
     902             :                         XFS_RTBLOCKLOG(postblock - end),
     903             :                         xfs_rtx_to_rbmblock(mp, end + 1), -1, rbpp, rsb);
     904      930078 :                 if (error) {
     905             :                         return error;
     906             :                 }
     907             :         }
     908             :         /*
     909             :          * Increment the summary information corresponding to the entire
     910             :          * (new) free extent.
     911             :          */
     912    15822405 :         error = xfs_rtmodify_summary(mp, tp,
     913    15822405 :                 XFS_RTBLOCKLOG(postblock + 1 - preblock),
     914             :                 xfs_rtx_to_rbmblock(mp, preblock), 1, rbpp, rsb);
     915    15822405 :         return error;
     916             : }
     917             : 
     918             : /*
     919             :  * Check that the given range is either all allocated (val = 0) or
     920             :  * all free (val = 1).
     921             :  */
     922             : int
     923  1237556449 : xfs_rtcheck_range(
     924             :         xfs_mount_t     *mp,            /* file system mount point */
     925             :         xfs_trans_t     *tp,            /* transaction pointer */
     926             :         xfs_rtxnum_t    start,          /* starting rtext number of extent */
     927             :         xfs_rtxlen_t    len,            /* length of extent */
     928             :         int             val,            /* 1 for free, 0 for allocated */
     929             :         xfs_rtxnum_t    *new,           /* out: first rtext not matching */
     930             :         int             *stat)          /* out: 1 for matches, 0 for not */
     931             : {
     932  1237556449 :         union xfs_rtword_ondisk *b;             /* current word in buffer */
     933  1237556449 :         int             bit;            /* bit number in the word */
     934  1237556449 :         xfs_fileoff_t   block;          /* bitmap block number */
     935  1237556449 :         struct xfs_buf  *bp;            /* buf for the block */
     936  1237556449 :         int             error;          /* error value */
     937  1237556449 :         xfs_rtxnum_t    i;              /* current bit number rel. to start */
     938  1237556449 :         xfs_rtxnum_t    lastbit;        /* last useful bit in word */
     939  1237556449 :         xfs_rtword_t    mask;           /* mask of relevant bits for value */
     940  1237556449 :         xfs_rtword_t    wdiff;          /* difference from wanted value */
     941  1237556449 :         xfs_rtword_t    incore;
     942  1237556449 :         int             word;           /* word number in the buffer */
     943             : 
     944             :         /*
     945             :          * Compute starting bitmap block number
     946             :          */
     947  1237556449 :         block = xfs_rtx_to_rbmblock(mp, start);
     948             :         /*
     949             :          * Read the bitmap block.
     950             :          */
     951  1237556449 :         error = xfs_rtbuf_get(mp, tp, block, 0, &bp);
     952  1237579296 :         if (error) {
     953             :                 return error;
     954             :         }
     955             : 
     956             :         /*
     957             :          * Compute the starting word's address, and starting bit.
     958             :          */
     959  1237579296 :         word = xfs_rtx_to_rbmword(mp, start);
     960  1237579296 :         b = xfs_rbmblock_wordptr(bp, word);
     961  1237579296 :         bit = (int)(start & (XFS_NBWORD - 1));
     962             :         /*
     963             :          * 0 (allocated) => all zero's; 1 (free) => all one's.
     964             :          */
     965  1237579296 :         val = -val;
     966             :         /*
     967             :          * If not starting on a word boundary, deal with the first
     968             :          * (partial) word.
     969             :          */
     970  1237579296 :         if (bit) {
     971             :                 /*
     972             :                  * Compute first bit not examined.
     973             :                  */
     974  1131656807 :                 lastbit = XFS_RTMIN(bit + len, XFS_NBWORD);
     975             :                 /*
     976             :                  * Mask of relevant bits.
     977             :                  */
     978  1131656807 :                 mask = (((xfs_rtword_t)1 << (lastbit - bit)) - 1) << bit;
     979             :                 /*
     980             :                  * Compute difference between actual and desired value.
     981             :                  */
     982  1131656807 :                 incore = xfs_rtbitmap_getword(mp, b);
     983  1131656807 :                 if ((wdiff = (incore ^ val) & mask)) {
     984             :                         /*
     985             :                          * Different, compute first wrong bit and return.
     986             :                          */
     987   971525849 :                         xfs_trans_brelse(tp, bp);
     988   971532552 :                         i = XFS_RTLOBIT(wdiff) - bit;
     989   971532552 :                         *new = start + i;
     990   971532552 :                         *stat = 0;
     991   971532552 :                         return 0;
     992             :                 }
     993   160130958 :                 i = lastbit - bit;
     994             :                 /*
     995             :                  * Go on to next block if that's where the next word is
     996             :                  * and we need the next word.
     997             :                  */
     998   160130958 :                 if (++word == mp->m_blockwsize && i < len) {
     999             :                         /*
    1000             :                          * If done with this block, get the next one.
    1001             :                          */
    1002       32600 :                         xfs_trans_brelse(tp, bp);
    1003       32600 :                         error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp);
    1004       32600 :                         if (error) {
    1005             :                                 return error;
    1006             :                         }
    1007             : 
    1008       32600 :                         word = 0;
    1009       32600 :                         b = xfs_rbmblock_wordptr(bp, word);
    1010             :                 } else {
    1011             :                         /*
    1012             :                          * Go on to the next word in the buffer.
    1013             :                          */
    1014   160098358 :                         b++;
    1015             :                 }
    1016             :         } else {
    1017             :                 /*
    1018             :                  * Starting on a word boundary, no partial word.
    1019             :                  */
    1020             :                 i = 0;
    1021             :         }
    1022             :         /*
    1023             :          * Loop over whole words in buffers.  When we use up one buffer
    1024             :          * we move on to the next one.
    1025             :          */
    1026   270191715 :         while (len - i >= XFS_NBWORD) {
    1027             :                 /*
    1028             :                  * Compute difference between actual and desired value.
    1029             :                  */
    1030    28376891 :                 incore = xfs_rtbitmap_getword(mp, b);
    1031    28376891 :                 if ((wdiff = incore ^ val)) {
    1032             :                         /*
    1033             :                          * Different, compute first wrong bit and return.
    1034             :                          */
    1035    24238479 :                         xfs_trans_brelse(tp, bp);
    1036    24238479 :                         i += XFS_RTLOBIT(wdiff);
    1037    24238479 :                         *new = start + i;
    1038    24238479 :                         *stat = 0;
    1039    24238479 :                         return 0;
    1040             :                 }
    1041     4138412 :                 i += XFS_NBWORD;
    1042             :                 /*
    1043             :                  * Go on to next block if that's where the next word is
    1044             :                  * and we need the next word.
    1045             :                  */
    1046     4138412 :                 if (++word == mp->m_blockwsize && i < len) {
    1047             :                         /*
    1048             :                          * If done with this block, get the next one.
    1049             :                          */
    1050        3368 :                         xfs_trans_brelse(tp, bp);
    1051        3224 :                         error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp);
    1052        3224 :                         if (error) {
    1053           0 :                                 return error;
    1054             :                         }
    1055             : 
    1056        3224 :                         word = 0;
    1057        3224 :                         b = xfs_rbmblock_wordptr(bp, word);
    1058             :                 } else {
    1059             :                         /*
    1060             :                          * Go on to the next word in the buffer.
    1061             :                          */
    1062     4135044 :                         b++;
    1063             :                 }
    1064             :         }
    1065             :         /*
    1066             :          * If not ending on a word boundary, deal with the last
    1067             :          * (partial) word.
    1068             :          */
    1069   241814824 :         if ((lastbit = len - i)) {
    1070             :                 /*
    1071             :                  * Mask of relevant bits.
    1072             :                  */
    1073   108278256 :                 mask = ((xfs_rtword_t)1 << lastbit) - 1;
    1074             :                 /*
    1075             :                  * Compute difference between actual and desired value.
    1076             :                  */
    1077   108278256 :                 incore = xfs_rtbitmap_getword(mp, b);
    1078   108278256 :                 if ((wdiff = (incore ^ val) & mask)) {
    1079             :                         /*
    1080             :                          * Different, compute first wrong bit and return.
    1081             :                          */
    1082    95467160 :                         xfs_trans_brelse(tp, bp);
    1083    95467171 :                         i += XFS_RTLOBIT(wdiff);
    1084    95467171 :                         *new = start + i;
    1085    95467171 :                         *stat = 0;
    1086    95467171 :                         return 0;
    1087             :                 } else
    1088             :                         i = len;
    1089             :         }
    1090             :         /*
    1091             :          * Successful, return.
    1092             :          */
    1093   146347664 :         xfs_trans_brelse(tp, bp);
    1094   146347669 :         *new = start + i;
    1095   146347669 :         *stat = 1;
    1096   146347669 :         return 0;
    1097             : }
    1098             : 
    1099             : #ifdef DEBUG
    1100             : /*
    1101             :  * Check that the given extent (block range) is allocated already.
    1102             :  */
    1103             : STATIC int                              /* error */
    1104    15822390 : xfs_rtcheck_alloc_range(
    1105             :         xfs_mount_t     *mp,            /* file system mount point */
    1106             :         xfs_trans_t     *tp,            /* transaction pointer */
    1107             :         xfs_rtxnum_t    start,          /* starting rtext number of extent */
    1108             :         xfs_rtxlen_t    len)            /* length of extent */
    1109             : {
    1110    15822390 :         xfs_rtxnum_t    new;            /* dummy for xfs_rtcheck_range */
    1111    15822390 :         int             stat;
    1112    15822390 :         int             error;
    1113             : 
    1114    15822390 :         error = xfs_rtcheck_range(mp, tp, start, len, 0, &new, &stat);
    1115    15822390 :         if (error)
    1116             :                 return error;
    1117    15822390 :         ASSERT(stat);
    1118             :         return 0;
    1119             : }
    1120             : #else
    1121             : #define xfs_rtcheck_alloc_range(m,t,b,l)        (0)
    1122             : #endif
    1123             : /*
    1124             :  * Free an extent in the realtime subvolume.  Length is expressed in
    1125             :  * realtime extents, as is the block number.
    1126             :  */
    1127             : int                                     /* error */
    1128    15822390 : xfs_rtfree_extent(
    1129             :         xfs_trans_t     *tp,            /* transaction pointer */
    1130             :         xfs_rtxnum_t    start,          /* starting rtext number to free */
    1131             :         xfs_rtxlen_t    len)            /* length of extent freed */
    1132             : {
    1133    15822390 :         int             error;          /* error value */
    1134    15822390 :         xfs_mount_t     *mp;            /* file system mount structure */
    1135    15822390 :         xfs_fsblock_t   sb;             /* summary file block number */
    1136    15822390 :         struct xfs_buf  *sumbp = NULL;  /* summary file block buffer */
    1137             : 
    1138    15822390 :         mp = tp->t_mountp;
    1139             : 
    1140    15822390 :         ASSERT(mp->m_rbmip->i_itemp != NULL);
    1141    15822390 :         ASSERT(xfs_isilocked(mp->m_rbmip, XFS_ILOCK_EXCL));
    1142             : 
    1143    15822390 :         if (XFS_TEST_ERROR(false, mp, XFS_ERRTAG_FREE_EXTENT))
    1144             :                 return -EIO;
    1145             : 
    1146    15822390 :         error = xfs_rtcheck_alloc_range(mp, tp, start, len);
    1147    15822390 :         if (error)
    1148             :                 return error;
    1149             : 
    1150             :         /*
    1151             :          * Free the range of realtime blocks.
    1152             :          */
    1153    15822390 :         error = xfs_rtfree_range(mp, tp, start, len, &sumbp, &sb);
    1154    15822390 :         if (error) {
    1155             :                 return error;
    1156             :         }
    1157             :         /*
    1158             :          * Mark more blocks free in the superblock.
    1159             :          */
    1160    15822390 :         xfs_trans_mod_sb(tp, XFS_TRANS_SB_FREXTENTS, (long)len);
    1161             :         /*
    1162             :          * If we've now freed all the blocks, reset the file sequence
    1163             :          * number to 0.
    1164             :          */
    1165    15822390 :         if (tp->t_frextents_delta + mp->m_sb.sb_frextents ==
    1166    15822390 :             mp->m_sb.sb_rextents) {
    1167      894259 :                 if (!(mp->m_rbmip->i_diflags & XFS_DIFLAG_NEWRTBM))
    1168           0 :                         mp->m_rbmip->i_diflags |= XFS_DIFLAG_NEWRTBM;
    1169      894259 :                 *(uint64_t *)&VFS_I(mp->m_rbmip)->i_atime = 0;
    1170      894259 :                 xfs_trans_log_inode(tp, mp->m_rbmip, XFS_ILOG_CORE);
    1171             :         }
    1172             :         return 0;
    1173             : }
    1174             : 
    1175             : /*
    1176             :  * Free some blocks in the realtime subvolume.  rtbno and rtlen are in units of
    1177             :  * rt blocks, not rt extents; must be aligned to the rt extent size; and rtlen
    1178             :  * cannot exceed XFS_MAX_BMBT_EXTLEN.
    1179             :  */
    1180             : int
    1181    15822390 : xfs_rtfree_blocks(
    1182             :         struct xfs_trans        *tp,
    1183             :         xfs_fsblock_t           rtbno,
    1184             :         xfs_filblks_t           rtlen)
    1185             : {
    1186    15822390 :         struct xfs_mount        *mp = tp->t_mountp;
    1187    15822390 :         xfs_rtxnum_t            start;
    1188    15822390 :         xfs_filblks_t           len;
    1189    15822390 :         xfs_extlen_t            mod;
    1190             : 
    1191    15822390 :         ASSERT(rtlen <= XFS_MAX_BMBT_EXTLEN);
    1192             : 
    1193    15822390 :         len = xfs_rtb_to_rtx(mp, rtlen, &mod);
    1194    15822390 :         if (mod) {
    1195           0 :                 ASSERT(mod == 0);
    1196           0 :                 return -EIO;
    1197             :         }
    1198             : 
    1199    15822390 :         start = xfs_rtb_to_rtx(mp, rtbno, &mod);
    1200    15822390 :         if (mod) {
    1201           0 :                 ASSERT(mod == 0);
    1202           0 :                 return -EIO;
    1203             :         }
    1204             : 
    1205    15822390 :         return xfs_rtfree_extent(tp, start, len);
    1206             : }
    1207             : 
    1208             : /* Find all the free records within a given range. */
    1209             : int
    1210      258091 : xfs_rtalloc_query_range(
    1211             :         struct xfs_mount                *mp,
    1212             :         struct xfs_trans                *tp,
    1213             :         const struct xfs_rtalloc_rec    *low_rec,
    1214             :         const struct xfs_rtalloc_rec    *high_rec,
    1215             :         xfs_rtalloc_query_range_fn      fn,
    1216             :         void                            *priv)
    1217             : {
    1218      258091 :         struct xfs_rtalloc_rec          rec;
    1219      258091 :         xfs_rtxnum_t                    rtstart;
    1220      258091 :         xfs_rtxnum_t                    rtend;
    1221      258091 :         xfs_rtxnum_t                    high_key;
    1222      258091 :         int                             is_free;
    1223      258091 :         int                             error = 0;
    1224             : 
    1225      258091 :         if (low_rec->ar_startext > high_rec->ar_startext)
    1226             :                 return -EINVAL;
    1227      258091 :         if (low_rec->ar_startext >= mp->m_sb.sb_rextents ||
    1228             :             low_rec->ar_startext == high_rec->ar_startext)
    1229             :                 return 0;
    1230             : 
    1231      257453 :         high_key = min(high_rec->ar_startext, mp->m_sb.sb_rextents - 1);
    1232             : 
    1233             :         /* Iterate the bitmap, looking for discrepancies. */
    1234      257453 :         rtstart = low_rec->ar_startext;
    1235   238993808 :         while (rtstart <= high_key) {
    1236             :                 /* Is the first block free? */
    1237   238736356 :                 error = xfs_rtcheck_range(mp, tp, rtstart, 1, 1, &rtend,
    1238             :                                 &is_free);
    1239   238737183 :                 if (error)
    1240             :                         break;
    1241             : 
    1242             :                 /* How long does the extent go for? */
    1243   238737183 :                 error = xfs_rtfind_forw(mp, tp, rtstart, high_key, &rtend);
    1244   238736597 :                 if (error)
    1245             :                         break;
    1246             : 
    1247   238736597 :                 if (is_free) {
    1248   119306737 :                         rec.ar_startext = rtstart;
    1249   119306737 :                         rec.ar_extcount = rtend - rtstart + 1;
    1250             : 
    1251   119306737 :                         error = fn(mp, tp, &rec, priv);
    1252   119306495 :                         if (error)
    1253             :                                 break;
    1254             :                 }
    1255             : 
    1256   238736355 :                 rtstart = rtend + 1;
    1257             :         }
    1258             : 
    1259             :         return error;
    1260             : }
    1261             : 
    1262             : /* Find all the free records. */
    1263             : int
    1264      116770 : xfs_rtalloc_query_all(
    1265             :         struct xfs_mount                *mp,
    1266             :         struct xfs_trans                *tp,
    1267             :         xfs_rtalloc_query_range_fn      fn,
    1268             :         void                            *priv)
    1269             : {
    1270      116770 :         struct xfs_rtalloc_rec          keys[2];
    1271             : 
    1272      116770 :         keys[0].ar_startext = 0;
    1273      116770 :         keys[1].ar_startext = mp->m_sb.sb_rextents - 1;
    1274      116770 :         keys[0].ar_extcount = keys[1].ar_extcount = 0;
    1275             : 
    1276      116770 :         return xfs_rtalloc_query_range(mp, tp, &keys[0], &keys[1], fn, priv);
    1277             : }
    1278             : 
    1279             : /* Is the given extent all free? */
    1280             : int
    1281   699644454 : xfs_rtalloc_extent_is_free(
    1282             :         struct xfs_mount                *mp,
    1283             :         struct xfs_trans                *tp,
    1284             :         xfs_rtxnum_t                    start,
    1285             :         xfs_rtxlen_t                    len,
    1286             :         bool                            *is_free)
    1287             : {
    1288   699644454 :         xfs_rtxnum_t                    end;
    1289   699644454 :         int                             matches;
    1290   699644454 :         int                             error;
    1291             : 
    1292   699644454 :         error = xfs_rtcheck_range(mp, tp, start, len, 1, &end, &matches);
    1293   699695761 :         if (error)
    1294             :                 return error;
    1295             : 
    1296   699695761 :         *is_free = matches;
    1297   699695761 :         return 0;
    1298             : }
    1299             : 
    1300             : /*
    1301             :  * Compute the number of rtbitmap blocks needed to track the given number of rt
    1302             :  * extents.
    1303             :  */
    1304             : xfs_filblks_t
    1305       68998 : xfs_rtbitmap_blockcount(
    1306             :         struct xfs_mount        *mp,
    1307             :         xfs_rtbxlen_t           rtextents)
    1308             : {
    1309      106457 :         unsigned int            rbmblock_bytes = mp->m_sb.sb_blocksize;
    1310             : 
    1311       68998 :         if (xfs_has_rtgroups(mp))
    1312      106429 :                 rbmblock_bytes -= sizeof(struct xfs_rtbuf_blkinfo);
    1313             : 
    1314      106457 :         return howmany_64(rtextents, NBBY * rbmblock_bytes);
    1315             : }
    1316             : 
    1317             : /*
    1318             :  * Compute the number of rtbitmap words needed to populate every block of a
    1319             :  * bitmap that is large enough to track the given number of rt extents.
    1320             :  */
    1321             : unsigned long long
    1322       37459 : xfs_rtbitmap_wordcount(
    1323             :         struct xfs_mount        *mp,
    1324             :         xfs_rtbxlen_t           rtextents)
    1325             : {
    1326       37459 :         xfs_filblks_t           blocks;
    1327             : 
    1328       37459 :         blocks = xfs_rtbitmap_blockcount(mp, rtextents);
    1329       37459 :         return XFS_FSB_TO_B(mp, blocks) >> XFS_WORDLOG;
    1330             : }
    1331             : 
    1332             : /* Compute the number of rtsummary blocks needed to track the given rt space. */
    1333             : xfs_filblks_t
    1334       67771 : xfs_rtsummary_blockcount(
    1335             :         struct xfs_mount        *mp,
    1336             :         unsigned int            rsumlevels,
    1337             :         xfs_extlen_t            rbmblocks)
    1338             : {
    1339       67771 :         unsigned long long      rsumwords;
    1340             : 
    1341       67771 :         rsumwords = (unsigned long long)rsumlevels * rbmblocks;
    1342             : 
    1343       67771 :         if (xfs_has_rtgroups(mp))
    1344       67768 :                 return howmany_64(rsumwords, mp->m_blockwsize);
    1345             : 
    1346           3 :         return XFS_B_TO_FSB(mp, rsumwords << XFS_WORDLOG);
    1347             : }
    1348             : 
    1349             : /*
    1350             :  * Compute the number of rtsummary info words needed to populate every block of
    1351             :  * a summary file that is large enough to track the given rt space.
    1352             :  */
    1353             : unsigned long long
    1354       67522 : xfs_rtsummary_wordcount(
    1355             :         struct xfs_mount        *mp,
    1356             :         unsigned int            rsumlevels,
    1357             :         xfs_extlen_t            rbmblocks)
    1358             : {
    1359       67522 :         xfs_filblks_t           blocks;
    1360             : 
    1361       67522 :         blocks = xfs_rtsummary_blockcount(mp, rsumlevels, rbmblocks);
    1362       67522 :         return XFS_FSB_TO_B(mp, blocks) >> XFS_WORDLOG;
    1363             : }
    1364             : 
    1365             : /*
    1366             :  * Lock both realtime free space metadata inodes for a freespace update.  If a
    1367             :  * transaction is given, the inodes will be joined to the transaction and the
    1368             :  * ILOCKs will be released on transaction commit.
    1369             :  */
    1370             : void
    1371    58250662 : xfs_rtbitmap_lock(
    1372             :         struct xfs_trans        *tp,
    1373             :         struct xfs_mount        *mp)
    1374             : {
    1375    58250662 :         xfs_ilock(mp->m_rbmip, XFS_ILOCK_EXCL);
    1376    58253660 :         if (tp)
    1377    58209897 :                 xfs_trans_ijoin(tp, mp->m_rbmip, XFS_ILOCK_EXCL);
    1378             : 
    1379    58253660 :         xfs_ilock(mp->m_rsumip, XFS_ILOCK_EXCL);
    1380    58253660 :         if (tp)
    1381    58209897 :                 xfs_trans_ijoin(tp, mp->m_rsumip, XFS_ILOCK_EXCL);
    1382    58253660 : }
    1383             : 
    1384             : /* Unlock both realtime free space metadata inodes after a freespace update. */
    1385             : void
    1386       43763 : xfs_rtbitmap_unlock(
    1387             :         struct xfs_mount        *mp)
    1388             : {
    1389       43763 :         xfs_iunlock(mp->m_rsumip, XFS_ILOCK_EXCL);
    1390       43763 :         xfs_iunlock(mp->m_rbmip, XFS_ILOCK_EXCL);
    1391       43763 : }
    1392             : 
    1393             : /*
    1394             :  * Lock the realtime free space metadata inodes for a freespace scan.  Callers
    1395             :  * must walk metadata blocks in order of increasing file offset.
    1396             :  */
    1397             : void
    1398    29274509 : xfs_rtbitmap_lock_shared(
    1399             :         struct xfs_mount        *mp,
    1400             :         unsigned int            rbmlock_flags)
    1401             : {
    1402    29274509 :         if (rbmlock_flags & XFS_RBMLOCK_BITMAP)
    1403    29274620 :                 xfs_ilock(mp->m_rbmip, XFS_ILOCK_SHARED);
    1404             : 
    1405    29275552 :         if (rbmlock_flags & XFS_RBMLOCK_SUMMARY)
    1406           0 :                 xfs_ilock(mp->m_rsumip, XFS_ILOCK_SHARED);
    1407    29275552 : }
    1408             : 
    1409             : /* Unlock the realtime free space metadata inodes after a freespace scan. */
    1410             : void
    1411    29276590 : xfs_rtbitmap_unlock_shared(
    1412             :         struct xfs_mount        *mp,
    1413             :         unsigned int            rbmlock_flags)
    1414             : {
    1415    29276590 :         if (rbmlock_flags & XFS_RBMLOCK_SUMMARY)
    1416           0 :                 xfs_iunlock(mp->m_rsumip, XFS_ILOCK_SHARED);
    1417             : 
    1418    29276590 :         if (rbmlock_flags & XFS_RBMLOCK_BITMAP)
    1419    29276606 :                 xfs_iunlock(mp->m_rbmip, XFS_ILOCK_SHARED);
    1420    29276851 : }

Generated by: LCOV version 1.14