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-rc3-achx @ Mon Jul 31 20:08:12 PDT 2023 Lines: 390 408 95.6 %
Date: 2023-07-31 20:08:12 Functions: 16 16 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             : 
      21             : /*
      22             :  * Realtime allocator bitmap functions shared with userspace.
      23             :  */
      24             : 
      25             : /*
      26             :  * Real time buffers need verifiers to avoid runtime warnings during IO.
      27             :  * We don't have anything to verify, however, so these are just dummy
      28             :  * operations.
      29             :  */
      30             : static void
      31     1565457 : xfs_rtbuf_verify_read(
      32             :         struct xfs_buf  *bp)
      33             : {
      34     1565457 :         return;
      35             : }
      36             : 
      37             : static void
      38      509609 : xfs_rtbuf_verify_write(
      39             :         struct xfs_buf  *bp)
      40             : {
      41      509609 :         return;
      42             : }
      43             : 
      44             : const struct xfs_buf_ops xfs_rtbuf_ops = {
      45             :         .name = "rtbuf",
      46             :         .verify_read = xfs_rtbuf_verify_read,
      47             :         .verify_write = xfs_rtbuf_verify_write,
      48             : };
      49             : 
      50             : /*
      51             :  * Get a buffer for the bitmap or summary file block specified.
      52             :  * The buffer is returned read and locked.
      53             :  */
      54             : int
      55  2734906810 : xfs_rtbuf_get(
      56             :         xfs_mount_t     *mp,            /* file system mount structure */
      57             :         xfs_trans_t     *tp,            /* transaction pointer */
      58             :         xfs_rtblock_t   block,          /* block number in bitmap or summary */
      59             :         int             issum,          /* is summary not bitmap */
      60             :         struct xfs_buf  **bpp)          /* output: buffer for the block */
      61             : {
      62  2734906810 :         struct xfs_buf  *bp;            /* block buffer, result */
      63  2734906810 :         xfs_inode_t     *ip;            /* bitmap or summary inode */
      64  2734906810 :         xfs_bmbt_irec_t map;
      65  2734906810 :         int             nmap = 1;
      66  2734906810 :         int             error;          /* error value */
      67             : 
      68  2734906810 :         ip = issum ? mp->m_rsumip : mp->m_rbmip;
      69             : 
      70  2734906810 :         error = xfs_bmapi_read(ip, block, 1, &map, &nmap, 0);
      71  2734837375 :         if (error)
      72             :                 return error;
      73             : 
      74  2734837367 :         if (XFS_IS_CORRUPT(mp, nmap == 0 || !xfs_bmap_is_written_extent(&map))) {
      75           0 :                 xfs_rt_mark_sick(mp, issum ? XFS_SICK_RT_SUMMARY :
      76             :                                              XFS_SICK_RT_BITMAP);
      77           0 :                 return -EFSCORRUPTED;
      78             :         }
      79             : 
      80  2734837367 :         ASSERT(map.br_startblock != NULLFSBLOCK);
      81  8204529331 :         error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp,
      82  2734837367 :                                    XFS_FSB_TO_DADDR(mp, map.br_startblock),
      83             :                                    mp->m_bsize, 0, &bp, &xfs_rtbuf_ops);
      84  2734920141 :         if (xfs_metadata_is_sick(error))
      85           0 :                 xfs_rt_mark_sick(mp, issum ? XFS_SICK_RT_SUMMARY :
      86             :                                              XFS_SICK_RT_BITMAP);
      87  2734920141 :         if (error)
      88             :                 return error;
      89             : 
      90  5350484005 :         xfs_trans_buf_set_type(tp, bp, issum ? XFS_BLFT_RTSUMMARY_BUF
      91             :                                              : XFS_BLFT_RTBITMAP_BUF);
      92  2734919951 :         *bpp = bp;
      93  2734919951 :         return 0;
      94             : }
      95             : 
      96             : /*
      97             :  * Searching backward from start to limit, find the first block whose
      98             :  * allocated/free state is different from start's.
      99             :  */
     100             : int
     101    92199052 : xfs_rtfind_back(
     102             :         xfs_mount_t     *mp,            /* file system mount point */
     103             :         xfs_trans_t     *tp,            /* transaction pointer */
     104             :         xfs_rtblock_t   start,          /* starting block to look at */
     105             :         xfs_rtblock_t   limit,          /* last block to look at */
     106             :         xfs_rtblock_t   *rtblock)       /* out: start block found */
     107             : {
     108    92199052 :         xfs_rtword_t    *b;             /* current word in buffer */
     109    92199052 :         int             bit;            /* bit number in the word */
     110    92199052 :         xfs_rtblock_t   block;          /* bitmap block number */
     111    92199052 :         struct xfs_buf  *bp;            /* buf for the block */
     112    92199052 :         xfs_rtword_t    *bufp;          /* starting word in buffer */
     113    92199052 :         int             error;          /* error value */
     114    92199052 :         xfs_rtblock_t   firstbit;       /* first useful bit in the word */
     115    92199052 :         xfs_rtblock_t   i;              /* current bit number rel. to start */
     116    92199052 :         xfs_rtblock_t   len;            /* length of inspected area */
     117    92199052 :         xfs_rtword_t    mask;           /* mask of relevant bits for value */
     118    92199052 :         xfs_rtword_t    want;           /* mask for "good" values */
     119    92199052 :         xfs_rtword_t    wdiff;          /* difference from wanted value */
     120    92199052 :         int             word;           /* word number in the buffer */
     121             : 
     122             :         /*
     123             :          * Compute and read in starting bitmap block for starting block.
     124             :          */
     125    92199052 :         block = XFS_BITTOBLOCK(mp, start);
     126    92199052 :         error = xfs_rtbuf_get(mp, tp, block, 0, &bp);
     127    92199052 :         if (error) {
     128             :                 return error;
     129             :         }
     130    92199052 :         bufp = bp->b_addr;
     131             :         /*
     132             :          * Get the first word's index & point to it.
     133             :          */
     134    92199052 :         word = XFS_BITTOWORD(mp, start);
     135    92199052 :         b = &bufp[word];
     136    92199052 :         bit = (int)(start & (XFS_NBWORD - 1));
     137    92199052 :         len = start - limit + 1;
     138             :         /*
     139             :          * Compute match value, based on the bit at start: if 1 (free)
     140             :          * then all-ones, else all-zeroes.
     141             :          */
     142    92199052 :         want = (*b & ((xfs_rtword_t)1 << bit)) ? -1 : 0;
     143             :         /*
     144             :          * If the starting position is not word-aligned, deal with the
     145             :          * partial word.
     146             :          */
     147    92199052 :         if (bit < XFS_NBWORD - 1) {
     148             :                 /*
     149             :                  * Calculate first (leftmost) bit number to look at,
     150             :                  * and mask for all the relevant bits in this word.
     151             :                  */
     152    89342563 :                 firstbit = XFS_RTMAX((xfs_srtblock_t)(bit - len + 1), 0);
     153    89342563 :                 mask = (((xfs_rtword_t)1 << (bit - firstbit + 1)) - 1) <<
     154             :                         firstbit;
     155             :                 /*
     156             :                  * Calculate the difference between the value there
     157             :                  * and what we're looking for.
     158             :                  */
     159    89342563 :                 if ((wdiff = (*b ^ want) & mask)) {
     160             :                         /*
     161             :                          * Different.  Mark where we are and return.
     162             :                          */
     163    77399982 :                         xfs_trans_brelse(tp, bp);
     164    77399982 :                         i = bit - XFS_RTHIBIT(wdiff);
     165    77399982 :                         *rtblock = start - i + 1;
     166    77399982 :                         return 0;
     167             :                 }
     168    11942581 :                 i = bit - firstbit + 1;
     169             :                 /*
     170             :                  * Go on to previous block if that's where the previous word is
     171             :                  * and we need the previous word.
     172             :                  */
     173    11942581 :                 if (--word == -1 && i < len) {
     174             :                         /*
     175             :                          * If done with this block, get the previous one.
     176             :                          */
     177      183568 :                         xfs_trans_brelse(tp, bp);
     178      183568 :                         error = xfs_rtbuf_get(mp, tp, --block, 0, &bp);
     179      183568 :                         if (error) {
     180             :                                 return error;
     181             :                         }
     182      183568 :                         bufp = bp->b_addr;
     183      183568 :                         word = XFS_BLOCKWMASK(mp);
     184      183568 :                         b = &bufp[word];
     185             :                 } else {
     186             :                         /*
     187             :                          * Go on to the previous word in the buffer.
     188             :                          */
     189    11759013 :                         b--;
     190             :                 }
     191             :         } else {
     192             :                 /*
     193             :                  * Starting on a word boundary, no partial word.
     194             :                  */
     195             :                 i = 0;
     196             :         }
     197             :         /*
     198             :          * Loop over whole words in buffers.  When we use up one buffer
     199             :          * we move on to the previous one.
     200             :          */
     201  3856207210 :         while (len - i >= XFS_NBWORD) {
     202             :                 /*
     203             :                  * Compute difference between actual and desired value.
     204             :                  */
     205  3856035132 :                 if ((wdiff = *b ^ want)) {
     206             :                         /*
     207             :                          * Different, mark where we are and return.
     208             :                          */
     209    14626992 :                         xfs_trans_brelse(tp, bp);
     210    14626992 :                         i += XFS_NBWORD - 1 - XFS_RTHIBIT(wdiff);
     211    14626992 :                         *rtblock = start - i + 1;
     212    14626992 :                         return 0;
     213             :                 }
     214  3841408140 :                 i += XFS_NBWORD;
     215             :                 /*
     216             :                  * Go on to previous block if that's where the previous word is
     217             :                  * and we need the previous word.
     218             :                  */
     219  3841408140 :                 if (--word == -1 && i < len) {
     220             :                         /*
     221             :                          * If done with this block, get the previous one.
     222             :                          */
     223     3668389 :                         xfs_trans_brelse(tp, bp);
     224     3668389 :                         error = xfs_rtbuf_get(mp, tp, --block, 0, &bp);
     225     3668389 :                         if (error) {
     226           0 :                                 return error;
     227             :                         }
     228     3668389 :                         bufp = bp->b_addr;
     229     3668389 :                         word = XFS_BLOCKWMASK(mp);
     230     3668389 :                         b = &bufp[word];
     231             :                 } else {
     232             :                         /*
     233             :                          * Go on to the previous word in the buffer.
     234             :                          */
     235  3837739751 :                         b--;
     236             :                 }
     237             :         }
     238             :         /*
     239             :          * If not ending on a word boundary, deal with the last
     240             :          * (partial) word.
     241             :          */
     242      172078 :         if (len - i) {
     243             :                 /*
     244             :                  * Calculate first (leftmost) bit number to look at,
     245             :                  * and mask for all the relevant bits in this word.
     246             :                  */
     247           0 :                 firstbit = XFS_NBWORD - (len - i);
     248           0 :                 mask = (((xfs_rtword_t)1 << (len - i)) - 1) << firstbit;
     249             :                 /*
     250             :                  * Compute difference between actual and desired value.
     251             :                  */
     252           0 :                 if ((wdiff = (*b ^ want) & mask)) {
     253             :                         /*
     254             :                          * Different, mark where we are and return.
     255             :                          */
     256           0 :                         xfs_trans_brelse(tp, bp);
     257           0 :                         i += XFS_NBWORD - 1 - XFS_RTHIBIT(wdiff);
     258           0 :                         *rtblock = start - i + 1;
     259           0 :                         return 0;
     260             :                 } else
     261             :                         i = len;
     262             :         }
     263             :         /*
     264             :          * No match, return that we scanned the whole area.
     265             :          */
     266      172078 :         xfs_trans_brelse(tp, bp);
     267      172078 :         *rtblock = start - i + 1;
     268      172078 :         return 0;
     269             : }
     270             : 
     271             : /*
     272             :  * Searching forward from start to limit, find the first block whose
     273             :  * allocated/free state is different from start's.
     274             :  */
     275             : int
     276   503308712 : xfs_rtfind_forw(
     277             :         xfs_mount_t     *mp,            /* file system mount point */
     278             :         xfs_trans_t     *tp,            /* transaction pointer */
     279             :         xfs_rtblock_t   start,          /* starting block to look at */
     280             :         xfs_rtblock_t   limit,          /* last block to look at */
     281             :         xfs_rtblock_t   *rtblock)       /* out: start block found */
     282             : {
     283   503308712 :         xfs_rtword_t    *b;             /* current word in buffer */
     284   503308712 :         int             bit;            /* bit number in the word */
     285   503308712 :         xfs_rtblock_t   block;          /* bitmap block number */
     286   503308712 :         struct xfs_buf  *bp;            /* buf for the block */
     287   503308712 :         xfs_rtword_t    *bufp;          /* starting word in buffer */
     288   503308712 :         int             error;          /* error value */
     289   503308712 :         xfs_rtblock_t   i;              /* current bit number rel. to start */
     290   503308712 :         xfs_rtblock_t   lastbit;        /* last useful bit in the word */
     291   503308712 :         xfs_rtblock_t   len;            /* length of inspected area */
     292   503308712 :         xfs_rtword_t    mask;           /* mask of relevant bits for value */
     293   503308712 :         xfs_rtword_t    want;           /* mask for "good" values */
     294   503308712 :         xfs_rtword_t    wdiff;          /* difference from wanted value */
     295   503308712 :         int             word;           /* word number in the buffer */
     296             : 
     297             :         /*
     298             :          * Compute and read in starting bitmap block for starting block.
     299             :          */
     300   503308712 :         block = XFS_BITTOBLOCK(mp, start);
     301   503308712 :         error = xfs_rtbuf_get(mp, tp, block, 0, &bp);
     302   503308712 :         if (error) {
     303             :                 return error;
     304             :         }
     305   503308712 :         bufp = bp->b_addr;
     306             :         /*
     307             :          * Get the first word's index & point to it.
     308             :          */
     309   503308712 :         word = XFS_BITTOWORD(mp, start);
     310   503308712 :         b = &bufp[word];
     311   503308712 :         bit = (int)(start & (XFS_NBWORD - 1));
     312   503308712 :         len = limit - start + 1;
     313             :         /*
     314             :          * Compute match value, based on the bit at start: if 1 (free)
     315             :          * then all-ones, else all-zeroes.
     316             :          */
     317   503308712 :         want = (*b & ((xfs_rtword_t)1 << bit)) ? -1 : 0;
     318             :         /*
     319             :          * If the starting position is not word-aligned, deal with the
     320             :          * partial word.
     321             :          */
     322   503308712 :         if (bit) {
     323             :                 /*
     324             :                  * Calculate last (rightmost) bit number to look at,
     325             :                  * and mask for all the relevant bits in this word.
     326             :                  */
     327   446142907 :                 lastbit = XFS_RTMIN(bit + len, XFS_NBWORD);
     328   446142907 :                 mask = (((xfs_rtword_t)1 << (lastbit - bit)) - 1) << bit;
     329             :                 /*
     330             :                  * Calculate the difference between the value there
     331             :                  * and what we're looking for.
     332             :                  */
     333   446142907 :                 if ((wdiff = (*b ^ want) & mask)) {
     334             :                         /*
     335             :                          * Different.  Mark where we are and return.
     336             :                          */
     337   256789168 :                         xfs_trans_brelse(tp, bp);
     338   256789168 :                         i = XFS_RTLOBIT(wdiff) - bit;
     339   256789168 :                         *rtblock = start + i - 1;
     340   256789168 :                         return 0;
     341             :                 }
     342   189353739 :                 i = lastbit - bit;
     343             :                 /*
     344             :                  * Go on to next block if that's where the next word is
     345             :                  * and we need the next word.
     346             :                  */
     347   189353739 :                 if (++word == XFS_BLOCKWSIZE(mp) && i < len) {
     348             :                         /*
     349             :                          * If done with this block, get the previous one.
     350             :                          */
     351      818482 :                         xfs_trans_brelse(tp, bp);
     352      818482 :                         error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp);
     353      818482 :                         if (error) {
     354             :                                 return error;
     355             :                         }
     356      818482 :                         b = bufp = bp->b_addr;
     357      818482 :                         word = 0;
     358             :                 } else {
     359             :                         /*
     360             :                          * Go on to the previous word in the buffer.
     361             :                          */
     362   188535257 :                         b++;
     363             :                 }
     364             :         } else {
     365             :                 /*
     366             :                  * Starting on a word boundary, no partial word.
     367             :                  */
     368             :                 i = 0;
     369             :         }
     370             :         /*
     371             :          * Loop over whole words in buffers.  When we use up one buffer
     372             :          * we move on to the next one.
     373             :          */
     374 >14012*10^8 :         while (len - i >= XFS_NBWORD) {
     375             :                 /*
     376             :                  * Compute difference between actual and desired value.
     377             :                  */
     378 >14012*10^8 :                 if ((wdiff = *b ^ want)) {
     379             :                         /*
     380             :                          * Different, mark where we are and return.
     381             :                          */
     382   206078309 :                         xfs_trans_brelse(tp, bp);
     383   206078309 :                         i += XFS_RTLOBIT(wdiff);
     384   206078309 :                         *rtblock = start + i - 1;
     385   206078309 :                         return 0;
     386             :                 }
     387 >14009*10^8 :                 i += XFS_NBWORD;
     388             :                 /*
     389             :                  * Go on to next block if that's where the next word is
     390             :                  * and we need the next word.
     391             :                  */
     392 >14009*10^8 :                 if (++word == XFS_BLOCKWSIZE(mp) && i < len) {
     393             :                         /*
     394             :                          * If done with this block, get the next one.
     395             :                          */
     396  1326219826 :                         xfs_trans_brelse(tp, bp);
     397  1326219826 :                         error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp);
     398  1326219826 :                         if (error) {
     399           7 :                                 return error;
     400             :                         }
     401  1326219819 :                         b = bufp = bp->b_addr;
     402  1326219819 :                         word = 0;
     403             :                 } else {
     404             :                         /*
     405             :                          * Go on to the next word in the buffer.
     406             :                          */
     407 >13996*10^8 :                         b++;
     408             :                 }
     409             :         }
     410             :         /*
     411             :          * If not ending on a word boundary, deal with the last
     412             :          * (partial) word.
     413             :          */
     414    40441228 :         if ((lastbit = len - i)) {
     415             :                 /*
     416             :                  * Calculate mask for all the relevant bits in this word.
     417             :                  */
     418     1006357 :                 mask = ((xfs_rtword_t)1 << lastbit) - 1;
     419             :                 /*
     420             :                  * Compute difference between actual and desired value.
     421             :                  */
     422     1006357 :                 if ((wdiff = (*b ^ want) & mask)) {
     423             :                         /*
     424             :                          * Different, mark where we are and return.
     425             :                          */
     426         111 :                         xfs_trans_brelse(tp, bp);
     427         111 :                         i += XFS_RTLOBIT(wdiff);
     428         111 :                         *rtblock = start + i - 1;
     429         111 :                         return 0;
     430             :                 } else
     431             :                         i = len;
     432             :         }
     433             :         /*
     434             :          * No match, return that we scanned the whole area.
     435             :          */
     436    40441117 :         xfs_trans_brelse(tp, bp);
     437    40441117 :         *rtblock = start + i - 1;
     438    40441117 :         return 0;
     439             : }
     440             : 
     441             : /*
     442             :  * Read and/or modify the summary information for a given extent size,
     443             :  * bitmap block combination.
     444             :  * Keeps track of a current summary block, so we don't keep reading
     445             :  * it from the buffer cache.
     446             :  *
     447             :  * Summary information is returned in *sum if specified.
     448             :  * If no delta is specified, returns summary only.
     449             :  */
     450             : int
     451   834175404 : xfs_rtmodify_summary_int(
     452             :         xfs_mount_t     *mp,            /* file system mount structure */
     453             :         xfs_trans_t     *tp,            /* transaction pointer */
     454             :         int             log,            /* log2 of extent size */
     455             :         xfs_rtblock_t   bbno,           /* bitmap block number */
     456             :         int             delta,          /* change to make to summary info */
     457             :         struct xfs_buf  **rbpp,         /* in/out: summary block buffer */
     458             :         xfs_fsblock_t   *rsb,           /* in/out: summary block number */
     459             :         xfs_suminfo_t   *sum)           /* out: summary info for this block */
     460             : {
     461   834175404 :         struct xfs_buf  *bp;            /* buffer for the summary block */
     462   834175404 :         int             error;          /* error value */
     463   834175404 :         xfs_fsblock_t   sb;             /* summary fsblock */
     464   834175404 :         int             so;             /* index into the summary file */
     465   834175404 :         xfs_suminfo_t   *sp;            /* pointer to returned data */
     466             : 
     467             :         /*
     468             :          * Compute entry number in the summary file.
     469             :          */
     470   834175404 :         so = XFS_SUMOFFS(mp, log, bbno);
     471             :         /*
     472             :          * Compute the block number in the summary file.
     473             :          */
     474   834175404 :         sb = XFS_SUMOFFSTOBLOCK(mp, so);
     475             :         /*
     476             :          * If we have an old buffer, and the block number matches, use that.
     477             :          */
     478   834175404 :         if (*rbpp && *rsb == sb)
     479   715058187 :                 bp = *rbpp;
     480             :         /*
     481             :          * Otherwise we have to get the buffer.
     482             :          */
     483             :         else {
     484             :                 /*
     485             :                  * If there was an old one, get rid of it first.
     486             :                  */
     487   119117217 :                 if (*rbpp)
     488    26918114 :                         xfs_trans_brelse(tp, *rbpp);
     489   119117217 :                 error = xfs_rtbuf_get(mp, tp, sb, 1, &bp);
     490   119117217 :                 if (error) {
     491             :                         return error;
     492             :                 }
     493             :                 /*
     494             :                  * Remember this buffer and block for the next call.
     495             :                  */
     496   119117216 :                 *rbpp = bp;
     497   119117216 :                 *rsb = sb;
     498             :         }
     499             :         /*
     500             :          * Point to the summary information, modify/log it, and/or copy it out.
     501             :          */
     502   834175403 :         sp = XFS_SUMPTR(mp, bp, so);
     503   834175403 :         if (delta) {
     504   170047368 :                 uint first = (uint)((char *)sp - (char *)bp->b_addr);
     505             : 
     506   170047368 :                 *sp += delta;
     507   170047368 :                 if (mp->m_rsum_cache) {
     508   170047368 :                         if (*sp == 0 && log == mp->m_rsum_cache[bbno])
     509    15909646 :                                 mp->m_rsum_cache[bbno]++;
     510   170047368 :                         if (*sp != 0 && log < mp->m_rsum_cache[bbno])
     511    16020337 :                                 mp->m_rsum_cache[bbno] = log;
     512             :                 }
     513   170047368 :                 xfs_trans_log_buf(tp, bp, first, first + sizeof(*sp) - 1);
     514             :         }
     515   834175403 :         if (sum)
     516   664128035 :                 *sum = *sp;
     517             :         return 0;
     518             : }
     519             : 
     520             : int
     521   114769585 : xfs_rtmodify_summary(
     522             :         xfs_mount_t     *mp,            /* file system mount structure */
     523             :         xfs_trans_t     *tp,            /* transaction pointer */
     524             :         int             log,            /* log2 of extent size */
     525             :         xfs_rtblock_t   bbno,           /* bitmap block number */
     526             :         int             delta,          /* change to make to summary info */
     527             :         struct xfs_buf  **rbpp,         /* in/out: summary block buffer */
     528             :         xfs_fsblock_t   *rsb)           /* in/out: summary block number */
     529             : {
     530   135203893 :         return xfs_rtmodify_summary_int(mp, tp, log, bbno,
     531             :                                         delta, rbpp, rsb, NULL);
     532             : }
     533             : 
     534             : /*
     535             :  * Set the given range of bitmap bits to the given value.
     536             :  * Do whatever I/O and logging is required.
     537             :  */
     538             : int
     539    92199046 : xfs_rtmodify_range(
     540             :         xfs_mount_t     *mp,            /* file system mount point */
     541             :         xfs_trans_t     *tp,            /* transaction pointer */
     542             :         xfs_rtblock_t   start,          /* starting block to modify */
     543             :         xfs_extlen_t    len,            /* length of extent to modify */
     544             :         int             val)            /* 1 for free, 0 for allocated */
     545             : {
     546    92199046 :         xfs_rtword_t    *b;             /* current word in buffer */
     547    92199046 :         int             bit;            /* bit number in the word */
     548    92199046 :         xfs_rtblock_t   block;          /* bitmap block number */
     549    92199046 :         struct xfs_buf  *bp;            /* buf for the block */
     550    92199046 :         xfs_rtword_t    *bufp;          /* starting word in buffer */
     551    92199046 :         int             error;          /* error value */
     552    92199046 :         xfs_rtword_t    *first;         /* first used word in the buffer */
     553    92199046 :         int             i;              /* current bit number rel. to start */
     554    92199046 :         int             lastbit;        /* last useful bit in word */
     555    92199046 :         xfs_rtword_t    mask;           /* mask o frelevant bits for value */
     556    92199046 :         int             word;           /* word number in the buffer */
     557             : 
     558             :         /*
     559             :          * Compute starting bitmap block number.
     560             :          */
     561    92199046 :         block = XFS_BITTOBLOCK(mp, start);
     562             :         /*
     563             :          * Read the bitmap block, and point to its data.
     564             :          */
     565    92199046 :         error = xfs_rtbuf_get(mp, tp, block, 0, &bp);
     566    92199046 :         if (error) {
     567             :                 return error;
     568             :         }
     569    92199045 :         bufp = bp->b_addr;
     570             :         /*
     571             :          * Compute the starting word's address, and starting bit.
     572             :          */
     573    92199045 :         word = XFS_BITTOWORD(mp, start);
     574    92199045 :         first = b = &bufp[word];
     575    92199045 :         bit = (int)(start & (XFS_NBWORD - 1));
     576             :         /*
     577             :          * 0 (allocated) => all zeroes; 1 (free) => all ones.
     578             :          */
     579    92199045 :         val = -val;
     580             :         /*
     581             :          * If not starting on a word boundary, deal with the first
     582             :          * (partial) word.
     583             :          */
     584    92199045 :         if (bit) {
     585             :                 /*
     586             :                  * Compute first bit not changed and mask of relevant bits.
     587             :                  */
     588    88784513 :                 lastbit = XFS_RTMIN(bit + len, XFS_NBWORD);
     589    88784513 :                 mask = (((xfs_rtword_t)1 << (lastbit - bit)) - 1) << bit;
     590             :                 /*
     591             :                  * Set/clear the active bits.
     592             :                  */
     593    88784513 :                 if (val)
     594    33705045 :                         *b |= mask;
     595             :                 else
     596    55079468 :                         *b &= ~mask;
     597    88784513 :                 i = lastbit - bit;
     598             :                 /*
     599             :                  * Go on to the next block if that's where the next word is
     600             :                  * and we need the next word.
     601             :                  */
     602    88784513 :                 if (++word == XFS_BLOCKWSIZE(mp) && i < len) {
     603             :                         /*
     604             :                          * Log the changed part of this block.
     605             :                          * Get the next one.
     606             :                          */
     607       32865 :                         xfs_trans_log_buf(tp, bp,
     608             :                                 (uint)((char *)first - (char *)bufp),
     609             :                                 (uint)((char *)b - (char *)bufp));
     610       32865 :                         error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp);
     611       32865 :                         if (error) {
     612             :                                 return error;
     613             :                         }
     614       32865 :                         first = b = bufp = bp->b_addr;
     615       32865 :                         word = 0;
     616             :                 } else {
     617             :                         /*
     618             :                          * Go on to the next word in the buffer
     619             :                          */
     620    88751648 :                         b++;
     621             :                 }
     622             :         } else {
     623             :                 /*
     624             :                  * Starting on a word boundary, no partial word.
     625             :                  */
     626             :                 i = 0;
     627             :         }
     628             :         /*
     629             :          * Loop over whole words in buffers.  When we use up one buffer
     630             :          * we move on to the next one.
     631             :          */
     632   137559706 :         while (len - i >= XFS_NBWORD) {
     633             :                 /*
     634             :                  * Set the word value correctly.
     635             :                  */
     636    45360661 :                 *b = val;
     637    45360661 :                 i += XFS_NBWORD;
     638             :                 /*
     639             :                  * Go on to the next block if that's where the next word is
     640             :                  * and we need the next word.
     641             :                  */
     642    45360661 :                 if (++word == XFS_BLOCKWSIZE(mp) && i < len) {
     643             :                         /*
     644             :                          * Log the changed part of this block.
     645             :                          * Get the next one.
     646             :                          */
     647       34279 :                         xfs_trans_log_buf(tp, bp,
     648       34279 :                                 (uint)((char *)first - (char *)bufp),
     649       34279 :                                 (uint)((char *)b - (char *)bufp));
     650       34279 :                         error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp);
     651       34279 :                         if (error) {
     652           0 :                                 return error;
     653             :                         }
     654       34279 :                         first = b = bufp = bp->b_addr;
     655       34279 :                         word = 0;
     656             :                 } else {
     657             :                         /*
     658             :                          * Go on to the next word in the buffer
     659             :                          */
     660    45326382 :                         b++;
     661             :                 }
     662             :         }
     663             :         /*
     664             :          * If not ending on a word boundary, deal with the last
     665             :          * (partial) word.
     666             :          */
     667    92199045 :         if ((lastbit = len - i)) {
     668             :                 /*
     669             :                  * Compute a mask of relevant bits.
     670             :                  */
     671    12596605 :                 mask = ((xfs_rtword_t)1 << lastbit) - 1;
     672             :                 /*
     673             :                  * Set/clear the active bits.
     674             :                  */
     675    12596605 :                 if (val)
     676     3826586 :                         *b |= mask;
     677             :                 else
     678     8770019 :                         *b &= ~mask;
     679    12596605 :                 b++;
     680             :         }
     681             :         /*
     682             :          * Log any remaining changed bytes.
     683             :          */
     684    92199045 :         if (b > first)
     685    92199045 :                 xfs_trans_log_buf(tp, bp, (uint)((char *)first - (char *)bufp),
     686    92199045 :                         (uint)((char *)b - (char *)bufp - 1));
     687             :         return 0;
     688             : }
     689             : 
     690             : /*
     691             :  * Mark an extent specified by start and len freed.
     692             :  * Updates all the summary information as well as the bitmap.
     693             :  */
     694             : int
     695    34843476 : xfs_rtfree_range(
     696             :         xfs_mount_t     *mp,            /* file system mount point */
     697             :         xfs_trans_t     *tp,            /* transaction pointer */
     698             :         xfs_rtblock_t   start,          /* starting block to free */
     699             :         xfs_extlen_t    len,            /* length to free */
     700             :         struct xfs_buf  **rbpp,         /* in/out: summary block buffer */
     701             :         xfs_fsblock_t   *rsb)           /* in/out: summary block number */
     702             : {
     703    34843476 :         xfs_rtblock_t   end;            /* end of the freed extent */
     704    34843476 :         int             error;          /* error value */
     705    34843476 :         xfs_rtblock_t   postblock;      /* first block freed > end */
     706    34843476 :         xfs_rtblock_t   preblock;       /* first block freed < start */
     707             : 
     708    34843476 :         end = start + len - 1;
     709             :         /*
     710             :          * Modify the bitmap to mark this extent freed.
     711             :          */
     712    34843476 :         error = xfs_rtmodify_range(mp, tp, start, len, 1);
     713    34843476 :         if (error) {
     714             :                 return error;
     715             :         }
     716             :         /*
     717             :          * Assume we're freeing out of the middle of an allocated extent.
     718             :          * We need to find the beginning and end of the extent so we can
     719             :          * properly update the summary.
     720             :          */
     721    34843475 :         error = xfs_rtfind_back(mp, tp, start, 0, &preblock);
     722    34843475 :         if (error) {
     723             :                 return error;
     724             :         }
     725             :         /*
     726             :          * Find the next allocated block (end of allocated extent).
     727             :          */
     728    34843475 :         error = xfs_rtfind_forw(mp, tp, end, mp->m_sb.sb_rextents - 1,
     729             :                 &postblock);
     730    34843475 :         if (error)
     731             :                 return error;
     732             :         /*
     733             :          * If there are blocks not being freed at the front of the
     734             :          * old extent, add summary data for them to be allocated.
     735             :          */
     736    34843475 :         if (preblock < start) {
     737    17672412 :                 error = xfs_rtmodify_summary(mp, tp,
     738             :                         XFS_RTBLOCKLOG(start - preblock),
     739     8836206 :                         XFS_BITTOBLOCK(mp, preblock), -1, rbpp, rsb);
     740     8836206 :                 if (error) {
     741             :                         return error;
     742             :                 }
     743             :         }
     744             :         /*
     745             :          * If there are blocks not being freed at the end of the
     746             :          * old extent, add summary data for them to be allocated.
     747             :          */
     748    34843475 :         if (postblock > end) {
     749    23196204 :                 error = xfs_rtmodify_summary(mp, tp,
     750             :                         XFS_RTBLOCKLOG(postblock - end),
     751    11598102 :                         XFS_BITTOBLOCK(mp, end + 1), -1, rbpp, rsb);
     752    11598102 :                 if (error) {
     753             :                         return error;
     754             :                 }
     755             :         }
     756             :         /*
     757             :          * Increment the summary information corresponding to the entire
     758             :          * (new) free extent.
     759             :          */
     760    69686950 :         error = xfs_rtmodify_summary(mp, tp,
     761    34843475 :                 XFS_RTBLOCKLOG(postblock + 1 - preblock),
     762    34843475 :                 XFS_BITTOBLOCK(mp, preblock), 1, rbpp, rsb);
     763    34843475 :         return error;
     764             : }
     765             : 
     766             : /*
     767             :  * Check that the given range is either all allocated (val = 0) or
     768             :  * all free (val = 1).
     769             :  */
     770             : int
     771   596806280 : xfs_rtcheck_range(
     772             :         xfs_mount_t     *mp,            /* file system mount point */
     773             :         xfs_trans_t     *tp,            /* transaction pointer */
     774             :         xfs_rtblock_t   start,          /* starting block number of extent */
     775             :         xfs_extlen_t    len,            /* length of extent */
     776             :         int             val,            /* 1 for free, 0 for allocated */
     777             :         xfs_rtblock_t   *new,           /* out: first block not matching */
     778             :         int             *stat)          /* out: 1 for matches, 0 for not */
     779             : {
     780   596806280 :         xfs_rtword_t    *b;             /* current word in buffer */
     781   596806280 :         int             bit;            /* bit number in the word */
     782   596806280 :         xfs_rtblock_t   block;          /* bitmap block number */
     783   596806280 :         struct xfs_buf  *bp;            /* buf for the block */
     784   596806280 :         xfs_rtword_t    *bufp;          /* starting word in buffer */
     785   596806280 :         int             error;          /* error value */
     786   596806280 :         xfs_rtblock_t   i;              /* current bit number rel. to start */
     787   596806280 :         xfs_rtblock_t   lastbit;        /* last useful bit in word */
     788   596806280 :         xfs_rtword_t    mask;           /* mask of relevant bits for value */
     789   596806280 :         xfs_rtword_t    wdiff;          /* difference from wanted value */
     790   596806280 :         int             word;           /* word number in the buffer */
     791             : 
     792             :         /*
     793             :          * Compute starting bitmap block number
     794             :          */
     795   596806280 :         block = XFS_BITTOBLOCK(mp, start);
     796             :         /*
     797             :          * Read the bitmap block.
     798             :          */
     799   596806280 :         error = xfs_rtbuf_get(mp, tp, block, 0, &bp);
     800   596871237 :         if (error) {
     801             :                 return error;
     802             :         }
     803   596871233 :         bufp = bp->b_addr;
     804             :         /*
     805             :          * Compute the starting word's address, and starting bit.
     806             :          */
     807   596871233 :         word = XFS_BITTOWORD(mp, start);
     808   596871233 :         b = &bufp[word];
     809   596871233 :         bit = (int)(start & (XFS_NBWORD - 1));
     810             :         /*
     811             :          * 0 (allocated) => all zero's; 1 (free) => all one's.
     812             :          */
     813   596871233 :         val = -val;
     814             :         /*
     815             :          * If not starting on a word boundary, deal with the first
     816             :          * (partial) word.
     817             :          */
     818   596871233 :         if (bit) {
     819             :                 /*
     820             :                  * Compute first bit not examined.
     821             :                  */
     822   519922315 :                 lastbit = XFS_RTMIN(bit + len, XFS_NBWORD);
     823             :                 /*
     824             :                  * Mask of relevant bits.
     825             :                  */
     826   519922315 :                 mask = (((xfs_rtword_t)1 << (lastbit - bit)) - 1) << bit;
     827             :                 /*
     828             :                  * Compute difference between actual and desired value.
     829             :                  */
     830   519922315 :                 if ((wdiff = (*b ^ val) & mask)) {
     831             :                         /*
     832             :                          * Different, compute first wrong bit and return.
     833             :                          */
     834   352578057 :                         xfs_trans_brelse(tp, bp);
     835   352606485 :                         i = XFS_RTLOBIT(wdiff) - bit;
     836   352606485 :                         *new = start + i;
     837   352606485 :                         *stat = 0;
     838   352606485 :                         return 0;
     839             :                 }
     840   167344258 :                 i = lastbit - bit;
     841             :                 /*
     842             :                  * Go on to next block if that's where the next word is
     843             :                  * and we need the next word.
     844             :                  */
     845   167344258 :                 if (++word == XFS_BLOCKWSIZE(mp) && i < len) {
     846             :                         /*
     847             :                          * If done with this block, get the next one.
     848             :                          */
     849       48919 :                         xfs_trans_brelse(tp, bp);
     850       48919 :                         error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp);
     851       48919 :                         if (error) {
     852             :                                 return error;
     853             :                         }
     854       48919 :                         b = bufp = bp->b_addr;
     855       48919 :                         word = 0;
     856             :                 } else {
     857             :                         /*
     858             :                          * Go on to the next word in the buffer.
     859             :                          */
     860   167295339 :                         b++;
     861             :                 }
     862             :         } else {
     863             :                 /*
     864             :                  * Starting on a word boundary, no partial word.
     865             :                  */
     866             :                 i = 0;
     867             :         }
     868             :         /*
     869             :          * Loop over whole words in buffers.  When we use up one buffer
     870             :          * we move on to the next one.
     871             :          */
     872   299389710 :         while (len - i >= XFS_NBWORD) {
     873             :                 /*
     874             :                  * Compute difference between actual and desired value.
     875             :                  */
     876    65318667 :                 if ((wdiff = *b ^ val)) {
     877             :                         /*
     878             :                          * Different, compute first wrong bit and return.
     879             :                          */
     880    10222184 :                         xfs_trans_brelse(tp, bp);
     881    10222184 :                         i += XFS_RTLOBIT(wdiff);
     882    10222184 :                         *new = start + i;
     883    10222184 :                         *stat = 0;
     884    10222184 :                         return 0;
     885             :                 }
     886    55096483 :                 i += XFS_NBWORD;
     887             :                 /*
     888             :                  * Go on to next block if that's where the next word is
     889             :                  * and we need the next word.
     890             :                  */
     891    55096483 :                 if (++word == XFS_BLOCKWSIZE(mp) && i < len) {
     892             :                         /*
     893             :                          * If done with this block, get the next one.
     894             :                          */
     895       50501 :                         xfs_trans_brelse(tp, bp);
     896       50552 :                         error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp);
     897       50552 :                         if (error) {
     898           0 :                                 return error;
     899             :                         }
     900       50552 :                         b = bufp = bp->b_addr;
     901       50552 :                         word = 0;
     902             :                 } else {
     903             :                         /*
     904             :                          * Go on to the next word in the buffer.
     905             :                          */
     906    55045982 :                         b++;
     907             :                 }
     908             :         }
     909             :         /*
     910             :          * If not ending on a word boundary, deal with the last
     911             :          * (partial) word.
     912             :          */
     913   234071043 :         if ((lastbit = len - i)) {
     914             :                 /*
     915             :                  * Mask of relevant bits.
     916             :                  */
     917    86920931 :                 mask = ((xfs_rtword_t)1 << lastbit) - 1;
     918             :                 /*
     919             :                  * Compute difference between actual and desired value.
     920             :                  */
     921    86920931 :                 if ((wdiff = (*b ^ val) & mask)) {
     922             :                         /*
     923             :                          * Different, compute first wrong bit and return.
     924             :                          */
     925    72727800 :                         xfs_trans_brelse(tp, bp);
     926    72727892 :                         i += XFS_RTLOBIT(wdiff);
     927    72727892 :                         *new = start + i;
     928    72727892 :                         *stat = 0;
     929    72727892 :                         return 0;
     930             :                 } else
     931             :                         i = len;
     932             :         }
     933             :         /*
     934             :          * Successful, return.
     935             :          */
     936   161343243 :         xfs_trans_brelse(tp, bp);
     937   161343259 :         *new = start + i;
     938   161343259 :         *stat = 1;
     939   161343259 :         return 0;
     940             : }
     941             : 
     942             : #ifdef DEBUG
     943             : /*
     944             :  * Check that the given extent (block range) is allocated already.
     945             :  */
     946             : STATIC int                              /* error */
     947    34843418 : xfs_rtcheck_alloc_range(
     948             :         xfs_mount_t     *mp,            /* file system mount point */
     949             :         xfs_trans_t     *tp,            /* transaction pointer */
     950             :         xfs_rtblock_t   bno,            /* starting block number of extent */
     951             :         xfs_extlen_t    len)            /* length of extent */
     952             : {
     953    34843418 :         xfs_rtblock_t   new;            /* dummy for xfs_rtcheck_range */
     954    34843418 :         int             stat;
     955    34843418 :         int             error;
     956             : 
     957    34843418 :         error = xfs_rtcheck_range(mp, tp, bno, len, 0, &new, &stat);
     958    34843418 :         if (error)
     959             :                 return error;
     960    34843418 :         ASSERT(stat);
     961             :         return 0;
     962             : }
     963             : #else
     964             : #define xfs_rtcheck_alloc_range(m,t,b,l)        (0)
     965             : #endif
     966             : /*
     967             :  * Free an extent in the realtime subvolume.  Length is expressed in
     968             :  * realtime extents, as is the block number.
     969             :  */
     970             : int                                     /* error */
     971    34843418 : xfs_rtfree_extent(
     972             :         xfs_trans_t     *tp,            /* transaction pointer */
     973             :         xfs_rtblock_t   bno,            /* starting block number to free */
     974             :         xfs_extlen_t    len)            /* length of extent freed */
     975             : {
     976    34843418 :         int             error;          /* error value */
     977    34843418 :         xfs_mount_t     *mp;            /* file system mount structure */
     978    34843418 :         xfs_fsblock_t   sb;             /* summary file block number */
     979    34843418 :         struct xfs_buf  *sumbp = NULL;  /* summary file block buffer */
     980             : 
     981    34843418 :         mp = tp->t_mountp;
     982             : 
     983    34843418 :         ASSERT(mp->m_rbmip->i_itemp != NULL);
     984    34843418 :         ASSERT(xfs_isilocked(mp->m_rbmip, XFS_ILOCK_EXCL));
     985             : 
     986    34843418 :         error = xfs_rtcheck_alloc_range(mp, tp, bno, len);
     987    34843418 :         if (error)
     988             :                 return error;
     989             : 
     990             :         /*
     991             :          * Free the range of realtime blocks.
     992             :          */
     993    34843418 :         error = xfs_rtfree_range(mp, tp, bno, len, &sumbp, &sb);
     994    34843418 :         if (error) {
     995             :                 return error;
     996             :         }
     997             :         /*
     998             :          * Mark more blocks free in the superblock.
     999             :          */
    1000    34843417 :         xfs_trans_mod_sb(tp, XFS_TRANS_SB_FREXTENTS, (long)len);
    1001             :         /*
    1002             :          * If we've now freed all the blocks, reset the file sequence
    1003             :          * number to 0.
    1004             :          */
    1005    34843417 :         if (tp->t_frextents_delta + mp->m_sb.sb_frextents ==
    1006    34843417 :             mp->m_sb.sb_rextents) {
    1007       10735 :                 if (!(mp->m_rbmip->i_diflags & XFS_DIFLAG_NEWRTBM))
    1008           0 :                         mp->m_rbmip->i_diflags |= XFS_DIFLAG_NEWRTBM;
    1009       10735 :                 *(uint64_t *)&VFS_I(mp->m_rbmip)->i_atime = 0;
    1010       10735 :                 xfs_trans_log_inode(tp, mp->m_rbmip, XFS_ILOG_CORE);
    1011             :         }
    1012             :         return 0;
    1013             : }
    1014             : 
    1015             : /*
    1016             :  * Free some blocks in the realtime subvolume.  rtbno and rtlen are in units of
    1017             :  * rt blocks, not rt extents; must be aligned to the rt extent size; and rtlen
    1018             :  * cannot exceed XFS_MAX_BMBT_EXTLEN.
    1019             :  */
    1020             : int
    1021    34843418 : xfs_rtfree_blocks(
    1022             :         struct xfs_trans        *tp,
    1023             :         xfs_fsblock_t           rtbno,
    1024             :         xfs_filblks_t           rtlen)
    1025             : {
    1026    34843418 :         struct xfs_mount        *mp = tp->t_mountp;
    1027    34843418 :         xfs_rtblock_t           bno;
    1028    34843418 :         xfs_filblks_t           len;
    1029    34843418 :         xfs_extlen_t            mod;
    1030             : 
    1031    34843418 :         ASSERT(rtlen <= XFS_MAX_BMBT_EXTLEN);
    1032             : 
    1033    34843418 :         len = div_u64_rem(rtlen, mp->m_sb.sb_rextsize, &mod);
    1034    34843418 :         if (mod) {
    1035           0 :                 ASSERT(mod == 0);
    1036           0 :                 return -EIO;
    1037             :         }
    1038             : 
    1039    34843418 :         bno = div_u64_rem(rtbno, mp->m_sb.sb_rextsize, &mod);
    1040    34843418 :         if (mod) {
    1041           0 :                 ASSERT(mod == 0);
    1042           0 :                 return -EIO;
    1043             :         }
    1044             : 
    1045    34843418 :         return xfs_rtfree_extent(tp, bno, len);
    1046             : }
    1047             : 
    1048             : /* Find all the free records within a given range. */
    1049             : int
    1050      166256 : xfs_rtalloc_query_range(
    1051             :         struct xfs_mount                *mp,
    1052             :         struct xfs_trans                *tp,
    1053             :         const struct xfs_rtalloc_rec    *low_rec,
    1054             :         const struct xfs_rtalloc_rec    *high_rec,
    1055             :         xfs_rtalloc_query_range_fn      fn,
    1056             :         void                            *priv)
    1057             : {
    1058      166256 :         struct xfs_rtalloc_rec          rec;
    1059      166256 :         xfs_rtblock_t                   rtstart;
    1060      166256 :         xfs_rtblock_t                   rtend;
    1061      166256 :         xfs_rtblock_t                   high_key;
    1062      166256 :         int                             is_free;
    1063      166256 :         int                             error = 0;
    1064             : 
    1065      166256 :         if (low_rec->ar_startext > high_rec->ar_startext)
    1066             :                 return -EINVAL;
    1067      166256 :         if (low_rec->ar_startext >= mp->m_sb.sb_rextents ||
    1068             :             low_rec->ar_startext == high_rec->ar_startext)
    1069             :                 return 0;
    1070             : 
    1071      166256 :         high_key = min(high_rec->ar_startext, mp->m_sb.sb_rextents - 1);
    1072             : 
    1073             :         /* Iterate the bitmap, looking for discrepancies. */
    1074      166256 :         rtstart = low_rec->ar_startext;
    1075   144503391 :         while (rtstart <= high_key) {
    1076             :                 /* Is the first block free? */
    1077   144342749 :                 error = xfs_rtcheck_range(mp, tp, rtstart, 1, 1, &rtend,
    1078             :                                 &is_free);
    1079   144342749 :                 if (error)
    1080             :                         break;
    1081             : 
    1082             :                 /* How long does the extent go for? */
    1083   144342749 :                 error = xfs_rtfind_forw(mp, tp, rtstart, high_key, &rtend);
    1084   144342749 :                 if (error)
    1085             :                         break;
    1086             : 
    1087   144342749 :                 if (is_free) {
    1088    72188639 :                         rec.ar_startext = rtstart;
    1089    72188639 :                         rec.ar_extcount = rtend - rtstart + 1;
    1090             : 
    1091    72188639 :                         error = fn(mp, tp, &rec, priv);
    1092    72188639 :                         if (error)
    1093             :                                 break;
    1094             :                 }
    1095             : 
    1096   144337135 :                 rtstart = rtend + 1;
    1097             :         }
    1098             : 
    1099             :         return error;
    1100             : }
    1101             : 
    1102             : /* Find all the free records. */
    1103             : int
    1104      148994 : xfs_rtalloc_query_all(
    1105             :         struct xfs_mount                *mp,
    1106             :         struct xfs_trans                *tp,
    1107             :         xfs_rtalloc_query_range_fn      fn,
    1108             :         void                            *priv)
    1109             : {
    1110      148994 :         struct xfs_rtalloc_rec          keys[2];
    1111             : 
    1112      148994 :         keys[0].ar_startext = 0;
    1113      148994 :         keys[1].ar_startext = mp->m_sb.sb_rextents - 1;
    1114      148994 :         keys[0].ar_extcount = keys[1].ar_extcount = 0;
    1115             : 
    1116      148994 :         return xfs_rtalloc_query_range(mp, tp, &keys[0], &keys[1], fn, priv);
    1117             : }
    1118             : 
    1119             : /* Is the given extent all free? */
    1120             : int
    1121    75458043 : xfs_rtalloc_extent_is_free(
    1122             :         struct xfs_mount                *mp,
    1123             :         struct xfs_trans                *tp,
    1124             :         xfs_rtblock_t                   start,
    1125             :         xfs_extlen_t                    len,
    1126             :         bool                            *is_free)
    1127             : {
    1128    75458043 :         xfs_rtblock_t                   end;
    1129    75458043 :         int                             matches;
    1130    75458043 :         int                             error;
    1131             : 
    1132    75458043 :         error = xfs_rtcheck_range(mp, tp, start, len, 1, &end, &matches);
    1133    75554485 :         if (error)
    1134             :                 return error;
    1135             : 
    1136    75554485 :         *is_free = matches;
    1137    75554485 :         return 0;
    1138             : }

Generated by: LCOV version 1.14