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

Generated by: LCOV version 1.14