LCOV - code coverage report
Current view: top level - fs/xfs/libxfs - xfs_iext_tree.c (source / functions) Hit Total Coverage
Test: fstests of 6.5.0-rc3-achx @ Mon Jul 31 20:08:12 PDT 2023 Lines: 441 444 99.3 %
Date: 2023-07-31 20:08:12 Functions: 30 30 100.0 %

          Line data    Source code
       1             : // SPDX-License-Identifier: GPL-2.0
       2             : /*
       3             :  * Copyright (c) 2017 Christoph Hellwig.
       4             :  */
       5             : 
       6             : #include "xfs.h"
       7             : #include "xfs_shared.h"
       8             : #include "xfs_format.h"
       9             : #include "xfs_bit.h"
      10             : #include "xfs_log_format.h"
      11             : #include "xfs_trans_resv.h"
      12             : #include "xfs_mount.h"
      13             : #include "xfs_inode.h"
      14             : #include "xfs_trace.h"
      15             : 
      16             : /*
      17             :  * In-core extent record layout:
      18             :  *
      19             :  * +-------+----------------------------+
      20             :  * | 00:53 | all 54 bits of startoff    |
      21             :  * | 54:63 | low 10 bits of startblock  |
      22             :  * +-------+----------------------------+
      23             :  * | 00:20 | all 21 bits of length      |
      24             :  * |    21 | unwritten extent bit       |
      25             :  * | 22:63 | high 42 bits of startblock |
      26             :  * +-------+----------------------------+
      27             :  */
      28             : #define XFS_IEXT_STARTOFF_MASK          xfs_mask64lo(BMBT_STARTOFF_BITLEN)
      29             : #define XFS_IEXT_LENGTH_MASK            xfs_mask64lo(BMBT_BLOCKCOUNT_BITLEN)
      30             : #define XFS_IEXT_STARTBLOCK_MASK        xfs_mask64lo(BMBT_STARTBLOCK_BITLEN)
      31             : 
      32             : struct xfs_iext_rec {
      33             :         uint64_t                        lo;
      34             :         uint64_t                        hi;
      35             : };
      36             : 
      37             : /*
      38             :  * Given that the length can't be a zero, only an empty hi value indicates an
      39             :  * unused record.
      40             :  */
      41             : static bool xfs_iext_rec_is_empty(struct xfs_iext_rec *rec)
      42             : {
      43 54637030269 :         return rec->hi == 0;
      44             : }
      45             : 
      46             : static inline void xfs_iext_rec_clear(struct xfs_iext_rec *rec)
      47             : {
      48   206719006 :         rec->lo = 0;
      49   206719006 :         rec->hi = 0;
      50             : }
      51             : 
      52             : static void
      53  2104722619 : xfs_iext_set(
      54             :         struct xfs_iext_rec     *rec,
      55             :         struct xfs_bmbt_irec    *irec)
      56             : {
      57  2104722619 :         ASSERT((irec->br_startoff & ~XFS_IEXT_STARTOFF_MASK) == 0);
      58  2104722619 :         ASSERT((irec->br_blockcount & ~XFS_IEXT_LENGTH_MASK) == 0);
      59  2104722619 :         ASSERT((irec->br_startblock & ~XFS_IEXT_STARTBLOCK_MASK) == 0);
      60             : 
      61  2104722619 :         rec->lo = irec->br_startoff & XFS_IEXT_STARTOFF_MASK;
      62  2104722619 :         rec->hi = irec->br_blockcount & XFS_IEXT_LENGTH_MASK;
      63             : 
      64  2104722619 :         rec->lo |= (irec->br_startblock << 54);
      65  2104722619 :         rec->hi |= ((irec->br_startblock & ~xfs_mask64lo(10)) << (22 - 10));
      66             : 
      67  2104722619 :         if (irec->br_state == XFS_EXT_UNWRITTEN)
      68   307519246 :                 rec->hi |= (1 << 21);
      69  2104722619 : }
      70             : 
      71             : static void
      72 17238975289 : xfs_iext_get(
      73             :         struct xfs_bmbt_irec    *irec,
      74             :         struct xfs_iext_rec     *rec)
      75             : {
      76 17238975289 :         irec->br_startoff = rec->lo & XFS_IEXT_STARTOFF_MASK;
      77 17238975289 :         irec->br_blockcount = rec->hi & XFS_IEXT_LENGTH_MASK;
      78             : 
      79 17238975289 :         irec->br_startblock = rec->lo >> 54;
      80 17238975289 :         irec->br_startblock |= (rec->hi & xfs_mask64hi(42)) >> (22 - 10);
      81             : 
      82 17238975289 :         if (rec->hi & (1 << 21))
      83  2103082776 :                 irec->br_state = XFS_EXT_UNWRITTEN;
      84             :         else
      85 15135892513 :                 irec->br_state = XFS_EXT_NORM;
      86 17238975289 : }
      87             : 
      88             : enum {
      89             :         NODE_SIZE       = 256,
      90             :         KEYS_PER_NODE   = NODE_SIZE / (sizeof(uint64_t) + sizeof(void *)),
      91             :         RECS_PER_LEAF   = (NODE_SIZE - (2 * sizeof(struct xfs_iext_leaf *))) /
      92             :                                 sizeof(struct xfs_iext_rec),
      93             : };
      94             : 
      95             : /*
      96             :  * In-core extent btree block layout:
      97             :  *
      98             :  * There are two types of blocks in the btree: leaf and inner (non-leaf) blocks.
      99             :  *
     100             :  * The leaf blocks are made up by %KEYS_PER_NODE extent records, which each
     101             :  * contain the startoffset, blockcount, startblock and unwritten extent flag.
     102             :  * See above for the exact format, followed by pointers to the previous and next
     103             :  * leaf blocks (if there are any).
     104             :  *
     105             :  * The inner (non-leaf) blocks first contain KEYS_PER_NODE lookup keys, followed
     106             :  * by an equal number of pointers to the btree blocks at the next lower level.
     107             :  *
     108             :  *              +-------+-------+-------+-------+-------+----------+----------+
     109             :  * Leaf:        | rec 1 | rec 2 | rec 3 | rec 4 | rec N | prev-ptr | next-ptr |
     110             :  *              +-------+-------+-------+-------+-------+----------+----------+
     111             :  *
     112             :  *              +-------+-------+-------+-------+-------+-------+------+-------+
     113             :  * Inner:       | key 1 | key 2 | key 3 | key N | ptr 1 | ptr 2 | ptr3 | ptr N |
     114             :  *              +-------+-------+-------+-------+-------+-------+------+-------+
     115             :  */
     116             : struct xfs_iext_node {
     117             :         uint64_t                keys[KEYS_PER_NODE];
     118             : #define XFS_IEXT_KEY_INVALID    (1ULL << 63)
     119             :         void                    *ptrs[KEYS_PER_NODE];
     120             : };
     121             : 
     122             : struct xfs_iext_leaf {
     123             :         struct xfs_iext_rec     recs[RECS_PER_LEAF];
     124             :         struct xfs_iext_leaf    *prev;
     125             :         struct xfs_iext_leaf    *next;
     126             : };
     127             : 
     128   726971283 : inline xfs_extnum_t xfs_iext_count(struct xfs_ifork *ifp)
     129             : {
     130 29670657808 :         return ifp->if_bytes / sizeof(struct xfs_iext_rec);
     131             : }
     132             : 
     133             : static inline int xfs_iext_max_recs(struct xfs_ifork *ifp)
     134             : {
     135 13097585573 :         if (ifp->if_height == 1)
     136 28943686525 :                 return xfs_iext_count(ifp);
     137             :         return RECS_PER_LEAF;
     138             : }
     139             : 
     140             : static inline struct xfs_iext_rec *cur_rec(struct xfs_iext_cursor *cur)
     141             : {
     142 85047150029 :         return &cur->leaf->recs[cur->pos];
     143             : }
     144             : 
     145 13570991931 : static inline bool xfs_iext_valid(struct xfs_ifork *ifp,
     146             :                 struct xfs_iext_cursor *cur)
     147             : {
     148 13570991931 :         if (!cur->leaf)
     149             :                 return false;
     150 26335310064 :         if (cur->pos < 0 || cur->pos >= xfs_iext_max_recs(ifp))
     151             :                 return false;
     152 12102117245 :         if (xfs_iext_rec_is_empty(cur_rec(cur)))
     153  1393280871 :                 return false;
     154             :         return true;
     155             : }
     156             : 
     157             : static void *
     158  1503466432 : xfs_iext_find_first_leaf(
     159             :         struct xfs_ifork        *ifp)
     160             : {
     161  1503466432 :         struct xfs_iext_node    *node = ifp->if_u1.if_root;
     162  1503466432 :         int                     height;
     163             : 
     164  1503466432 :         if (!ifp->if_height)
     165             :                 return NULL;
     166             : 
     167  1261982622 :         for (height = ifp->if_height; height > 1; height--) {
     168     9094542 :                 node = node->ptrs[0];
     169     9094542 :                 ASSERT(node);
     170             :         }
     171             : 
     172             :         return node;
     173             : }
     174             : 
     175             : static void *
     176  1164091429 : xfs_iext_find_last_leaf(
     177             :         struct xfs_ifork        *ifp)
     178             : {
     179  1164091429 :         struct xfs_iext_node    *node = ifp->if_u1.if_root;
     180  1164091429 :         int                     height, i;
     181             : 
     182  1164091429 :         if (!ifp->if_height)
     183             :                 return NULL;
     184             : 
     185  1616181206 :         for (height = ifp->if_height; height > 1; height--) {
     186  4077777947 :                 for (i = 1; i < KEYS_PER_NODE; i++)
     187  4060335590 :                         if (!node->ptrs[i])
     188             :                                 break;
     189   649066561 :                 node = node->ptrs[i - 1];
     190   649066183 :                 ASSERT(node);
     191             :         }
     192             : 
     193             :         return node;
     194             : }
     195             : 
     196             : void
     197  1403229685 : xfs_iext_first(
     198             :         struct xfs_ifork        *ifp,
     199             :         struct xfs_iext_cursor  *cur)
     200             : {
     201  1503711860 :         cur->pos = 0;
     202  1403229685 :         cur->leaf = xfs_iext_find_first_leaf(ifp);
     203  1403093746 : }
     204             : 
     205             : void
     206  1164487546 : xfs_iext_last(
     207             :         struct xfs_ifork        *ifp,
     208             :         struct xfs_iext_cursor  *cur)
     209             : {
     210  1164487546 :         int                     i;
     211             : 
     212  1164487546 :         cur->leaf = xfs_iext_find_last_leaf(ifp);
     213  1164975318 :         if (!cur->leaf) {
     214   196973921 :                 cur->pos = 0;
     215   196973921 :                 return;
     216             :         }
     217             : 
     218  9183128612 :         for (i = 1; i < xfs_iext_max_recs(ifp); i++) {
     219  6118128480 :                 if (xfs_iext_rec_is_empty(&cur->leaf->recs[i]))
     220             :                         break;
     221             :         }
     222   969369097 :         cur->pos = i - 1;
     223             : }
     224             : 
     225             : void
     226  6782103897 : xfs_iext_next(
     227             :         struct xfs_ifork        *ifp,
     228             :         struct xfs_iext_cursor  *cur)
     229             : {
     230  6782103897 :         if (!cur->leaf) {
     231   100482175 :                 ASSERT(cur->pos <= 0 || cur->pos >= RECS_PER_LEAF);
     232   100482175 :                 xfs_iext_first(ifp, cur);
     233   100425605 :                 return;
     234             :         }
     235             : 
     236  6681621722 :         ASSERT(cur->pos >= 0);
     237  9938003859 :         ASSERT(cur->pos < xfs_iext_max_recs(ifp));
     238             : 
     239  6681621722 :         cur->pos++;
     240  6681621722 :         if (ifp->if_height > 1 && !xfs_iext_valid(ifp, cur) &&
     241  1317365222 :             cur->leaf->next) {
     242   203059417 :                 cur->leaf = cur->leaf->next;
     243   203059417 :                 cur->pos = 0;
     244             :         }
     245             : }
     246             : 
     247             : void
     248  1008547976 : xfs_iext_prev(
     249             :         struct xfs_ifork        *ifp,
     250             :         struct xfs_iext_cursor  *cur)
     251             : {
     252  1008547976 :         if (!cur->leaf) {
     253   213172796 :                 ASSERT(cur->pos <= 0 || cur->pos >= RECS_PER_LEAF);
     254   213172796 :                 xfs_iext_last(ifp, cur);
     255   213172796 :                 return;
     256             :         }
     257             : 
     258   795375180 :         ASSERT(cur->pos >= 0);
     259   795375180 :         ASSERT(cur->pos <= RECS_PER_LEAF);
     260             : 
     261   795375180 : recurse:
     262   907269743 :         do {
     263   907269743 :                 cur->pos--;
     264   907269743 :                 if (xfs_iext_valid(ifp, cur))
     265             :                         return;
     266   172125692 :         } while (cur->pos > 0);
     267             : 
     268    82132748 :         if (ifp->if_height > 1 && cur->leaf->prev) {
     269    21901619 :                 cur->leaf = cur->leaf->prev;
     270    21901619 :                 cur->pos = RECS_PER_LEAF;
     271    21901619 :                 goto recurse;
     272             :         }
     273             : }
     274             : 
     275             : static inline int
     276             : xfs_iext_key_cmp(
     277             :         struct xfs_iext_node    *node,
     278             :         int                     n,
     279             :         xfs_fileoff_t           offset)
     280             : {
     281 27581749000 :         if (node->keys[n] > offset)
     282             :                 return 1;
     283 22418062504 :         if (node->keys[n] < offset)
     284           0 :                 return -1;
     285             :         return 0;
     286             : }
     287             : 
     288             : static inline int
     289             : xfs_iext_rec_cmp(
     290             :         struct xfs_iext_rec     *rec,
     291             :         xfs_fileoff_t           offset)
     292             : {
     293 34107428951 :         uint64_t                rec_offset = rec->lo & XFS_IEXT_STARTOFF_MASK;
     294 34107428951 :         uint32_t                rec_len = rec->hi & XFS_IEXT_LENGTH_MASK;
     295             : 
     296   106499676 :         if (rec_offset > offset)
     297             :                 return 1;
     298 32195668676 :         if (rec_offset + rec_len <= offset)
     299           0 :                 return -1;
     300             :         return 0;
     301             : }
     302             : 
     303             : static void *
     304 10568310072 : xfs_iext_find_level(
     305             :         struct xfs_ifork        *ifp,
     306             :         xfs_fileoff_t           offset,
     307             :         int                     level)
     308             : {
     309 10568310072 :         struct xfs_iext_node    *node = ifp->if_u1.if_root;
     310 10568310072 :         int                     height, i;
     311             : 
     312 10568310072 :         if (!ifp->if_height)
     313             :                 return NULL;
     314             : 
     315 15440658147 :         for (height = ifp->if_height; height > level; height--) {
     316 26601881600 :                 for (i = 1; i < KEYS_PER_NODE; i++)
     317 26489718206 :                         if (xfs_iext_key_cmp(node, i, offset) > 0)
     318             :                                 break;
     319             : 
     320  5140542588 :                 node = node->ptrs[i - 1];
     321  5140512152 :                 if (!node)
     322             :                         break;
     323             :         }
     324             : 
     325             :         return node;
     326             : }
     327             : 
     328             : static int
     329             : xfs_iext_node_pos(
     330             :         struct xfs_iext_node    *node,
     331             :         xfs_fileoff_t           offset)
     332             : {
     333     7193015 :         int                     i;
     334             : 
     335    47224718 :         for (i = 1; i < KEYS_PER_NODE; i++) {
     336    46947683 :                 if (xfs_iext_key_cmp(node, i, offset) > 0)
     337             :                         break;
     338             :         }
     339             : 
     340     7193024 :         return i - 1;
     341             : }
     342             : 
     343             : static int
     344             : xfs_iext_node_insert_pos(
     345             :         struct xfs_iext_node    *node,
     346             :         xfs_fileoff_t           offset)
     347             : {
     348    92016514 :         int                     i;
     349             : 
     350   844780160 :         for (i = 0; i < KEYS_PER_NODE; i++) {
     351   839418417 :                 if (xfs_iext_key_cmp(node, i, offset) > 0)
     352             :                         return i;
     353             :         }
     354             : 
     355             :         return KEYS_PER_NODE;
     356             : }
     357             : 
     358             : static int
     359             : xfs_iext_node_nr_entries(
     360             :         struct xfs_iext_node    *node,
     361             :         int                     start)
     362             : {
     363     2879689 :         int                     i;
     364             : 
     365   148946583 :         for (i = start; i < KEYS_PER_NODE; i++) {
     366   141384440 :                 if (node->keys[i] == XFS_IEXT_KEY_INVALID)
     367             :                         break;
     368             :         }
     369             : 
     370   100655165 :         return i;
     371             : }
     372             : 
     373             : static int
     374             : xfs_iext_leaf_nr_entries(
     375             :         struct xfs_ifork        *ifp,
     376             :         struct xfs_iext_leaf    *leaf,
     377             :         int                     start)
     378             : {
     379  1765352352 :         int                     i;
     380             : 
     381  3791582319 :         for (i = start; i < xfs_iext_max_recs(ifp); i++) {
     382  2201350627 :                 if (xfs_iext_rec_is_empty(&leaf->recs[i]))
     383             :                         break;
     384             :         }
     385             : 
     386  1937971144 :         return i;
     387             : }
     388             : 
     389             : static inline uint64_t
     390             : xfs_iext_leaf_key(
     391             :         struct xfs_iext_leaf    *leaf,
     392             :         int                     n)
     393             : {
     394   255976541 :         return leaf->recs[n].lo & XFS_IEXT_STARTOFF_MASK;
     395             : }
     396             : 
     397             : static void
     398     1946595 : xfs_iext_grow(
     399             :         struct xfs_ifork        *ifp)
     400             : {
     401     1946595 :         struct xfs_iext_node    *node = kmem_zalloc(NODE_SIZE, KM_NOFS);
     402     1946623 :         int                     i;
     403             : 
     404     1946623 :         if (ifp->if_height == 1) {
     405     1841697 :                 struct xfs_iext_leaf *prev = ifp->if_u1.if_root;
     406             : 
     407     1841697 :                 node->keys[0] = xfs_iext_leaf_key(prev, 0);
     408     1841697 :                 node->ptrs[0] = prev;
     409             :         } else  {
     410      104926 :                 struct xfs_iext_node *prev = ifp->if_u1.if_root;
     411             : 
     412      104926 :                 ASSERT(ifp->if_height > 1);
     413             : 
     414      104926 :                 node->keys[0] = prev->keys[0];
     415      104926 :                 node->ptrs[0] = prev;
     416             :         }
     417             : 
     418    31145709 :         for (i = 1; i < KEYS_PER_NODE; i++)
     419    29199101 :                 node->keys[i] = XFS_IEXT_KEY_INVALID;
     420             : 
     421     1946608 :         ifp->if_u1.if_root = node;
     422     1946608 :         ifp->if_height++;
     423     1946608 : }
     424             : 
     425             : static void
     426    25466125 : xfs_iext_update_node(
     427             :         struct xfs_ifork        *ifp,
     428             :         xfs_fileoff_t           old_offset,
     429             :         xfs_fileoff_t           new_offset,
     430             :         int                     level,
     431             :         void                    *ptr)
     432             : {
     433    25466125 :         struct xfs_iext_node    *node = ifp->if_u1.if_root;
     434    25466125 :         int                     height, i;
     435             : 
     436    65083082 :         for (height = ifp->if_height; height > level; height--) {
     437   241626884 :                 for (i = 0; i < KEYS_PER_NODE; i++) {
     438   240747386 :                         if (i > 0 && xfs_iext_key_cmp(node, i, old_offset) > 0)
     439             :                                 break;
     440   202010025 :                         if (node->keys[i] == old_offset)
     441    17286063 :                                 node->keys[i] = new_offset;
     442             :                 }
     443    39616960 :                 node = node->ptrs[i - 1];
     444    39616957 :                 ASSERT(node);
     445             :         }
     446             : 
     447    25466129 :         ASSERT(node == ptr);
     448    25466129 : }
     449             : 
     450             : static struct xfs_iext_node *
     451     5923982 : xfs_iext_split_node(
     452             :         struct xfs_iext_node    **nodep,
     453             :         int                     *pos,
     454             :         int                     *nr_entries)
     455             : {
     456     5923982 :         struct xfs_iext_node    *node = *nodep;
     457     5923982 :         struct xfs_iext_node    *new = kmem_zalloc(NODE_SIZE, KM_NOFS);
     458     5923978 :         const int               nr_move = KEYS_PER_NODE / 2;
     459     5923978 :         int                     nr_keep = nr_move + (KEYS_PER_NODE & 1);
     460     5923978 :         int                     i = 0;
     461             : 
     462             :         /* for sequential append operations just spill over into the new node */
     463     5923978 :         if (*pos == KEYS_PER_NODE) {
     464     5361742 :                 *nodep = new;
     465     5361742 :                 *pos = 0;
     466     5361742 :                 *nr_entries = 0;
     467     5361742 :                 goto done;
     468             :         }
     469             : 
     470             : 
     471     5059953 :         for (i = 0; i < nr_move; i++) {
     472     4497715 :                 new->keys[i] = node->keys[nr_keep + i];
     473     4497710 :                 new->ptrs[i] = node->ptrs[nr_keep + i];
     474             : 
     475     4497703 :                 node->keys[nr_keep + i] = XFS_IEXT_KEY_INVALID;
     476     4497689 :                 node->ptrs[nr_keep + i] = NULL;
     477             :         }
     478             : 
     479      562238 :         if (*pos >= nr_keep) {
     480      308526 :                 *nodep = new;
     481      308526 :                 *pos -= nr_keep;
     482      308526 :                 *nr_entries = nr_move;
     483             :         } else {
     484      253712 :                 *nr_entries = nr_keep;
     485             :         }
     486             : done:
     487    96209625 :         for (; i < KEYS_PER_NODE; i++)
     488    90285650 :                 new->keys[i] = XFS_IEXT_KEY_INVALID;
     489     5923975 :         return new;
     490             : }
     491             : 
     492             : static void
     493    86092506 : xfs_iext_insert_node(
     494             :         struct xfs_ifork        *ifp,
     495             :         uint64_t                offset,
     496             :         void                    *ptr,
     497             :         int                     level)
     498             : {
     499    92016489 :         struct xfs_iext_node    *node, *new;
     500    92016489 :         int                     i, pos, nr_entries;
     501             : 
     502    92016489 : again:
     503    92016489 :         if (ifp->if_height < level)
     504     1946609 :                 xfs_iext_grow(ifp);
     505             : 
     506    92016489 :         new = NULL;
     507    92016489 :         node = xfs_iext_find_level(ifp, offset, level);
     508    92016514 :         pos = xfs_iext_node_insert_pos(node, offset);
     509    92016659 :         nr_entries = xfs_iext_node_nr_entries(node, pos);
     510             : 
     511    95015622 :         ASSERT(pos >= nr_entries || xfs_iext_key_cmp(node, pos, offset) != 0);
     512    92016585 :         ASSERT(nr_entries <= KEYS_PER_NODE);
     513             : 
     514    92016585 :         if (nr_entries == KEYS_PER_NODE)
     515     5923981 :                 new = xfs_iext_split_node(&node, &pos, &nr_entries);
     516             : 
     517             :         /*
     518             :          * Update the pointers in higher levels if the first entry changes
     519             :          * in an existing node.
     520             :          */
     521    92016590 :         if (node != new && pos == 0 && nr_entries > 0)
     522           0 :                 xfs_iext_update_node(ifp, node->keys[0], offset, level, node);
     523             : 
     524   104930600 :         for (i = nr_entries; i > pos; i--) {
     525    12914043 :                 node->keys[i] = node->keys[i - 1];
     526    12914032 :                 node->ptrs[i] = node->ptrs[i - 1];
     527             :         }
     528    92016557 :         node->keys[pos] = offset;
     529    92016565 :         node->ptrs[pos] = ptr;
     530             : 
     531    92016617 :         if (new) {
     532     5923983 :                 offset = new->keys[0];
     533     5923983 :                 ptr = new;
     534     5923983 :                 level++;
     535     5923983 :                 goto again;
     536             :         }
     537    86092634 : }
     538             : 
     539             : static struct xfs_iext_leaf *
     540    86092634 : xfs_iext_split_leaf(
     541             :         struct xfs_iext_cursor  *cur,
     542             :         int                     *nr_entries)
     543             : {
     544    86092634 :         struct xfs_iext_leaf    *leaf = cur->leaf;
     545    86092634 :         struct xfs_iext_leaf    *new = kmem_zalloc(NODE_SIZE, KM_NOFS);
     546    86092598 :         const int               nr_move = RECS_PER_LEAF / 2;
     547    86092598 :         int                     nr_keep = nr_move + (RECS_PER_LEAF & 1);
     548    86092598 :         int                     i;
     549             : 
     550             :         /* for sequential append operations just spill over into the new node */
     551    86092598 :         if (cur->pos == RECS_PER_LEAF) {
     552    77998629 :                 cur->leaf = new;
     553    77998629 :                 cur->pos = 0;
     554    77998629 :                 *nr_entries = 0;
     555    77998629 :                 goto done;
     556             :         }
     557             : 
     558    64751374 :         for (i = 0; i < nr_move; i++) {
     559    56657378 :                 new->recs[i] = leaf->recs[nr_keep + i];
     560    56657372 :                 xfs_iext_rec_clear(&leaf->recs[nr_keep + i]);
     561             :         }
     562             : 
     563     8093996 :         if (cur->pos >= nr_keep) {
     564     6149126 :                 cur->leaf = new;
     565     6149126 :                 cur->pos -= nr_keep;
     566     6149126 :                 *nr_entries = nr_move;
     567             :         } else {
     568     1944870 :                 *nr_entries = nr_keep;
     569             :         }
     570    86092625 : done:
     571    86092625 :         if (leaf->next)
     572     2676281 :                 leaf->next->prev = new;
     573    86092625 :         new->next = leaf->next;
     574    86092625 :         new->prev = leaf;
     575    86092625 :         leaf->next = new;
     576    86092625 :         return new;
     577             : }
     578             : 
     579             : static void
     580   177010481 : xfs_iext_alloc_root(
     581             :         struct xfs_ifork        *ifp,
     582             :         struct xfs_iext_cursor  *cur)
     583             : {
     584   177010481 :         ASSERT(ifp->if_bytes == 0);
     585             : 
     586   177010481 :         ifp->if_u1.if_root = kmem_zalloc(sizeof(struct xfs_iext_rec), KM_NOFS);
     587   177073735 :         ifp->if_height = 1;
     588             : 
     589             :         /* now that we have a node step into it */
     590   177073735 :         cur->leaf = ifp->if_u1.if_root;
     591   177073735 :         cur->pos = 0;
     592   177073735 : }
     593             : 
     594             : static void
     595   356883059 : xfs_iext_realloc_root(
     596             :         struct xfs_ifork        *ifp,
     597             :         struct xfs_iext_cursor  *cur)
     598             : {
     599   356883059 :         int64_t new_size = ifp->if_bytes + sizeof(struct xfs_iext_rec);
     600   356883059 :         void *new;
     601             : 
     602             :         /* account for the prev/next pointers */
     603   356883059 :         if (new_size / sizeof(struct xfs_iext_rec) == RECS_PER_LEAF)
     604     2398071 :                 new_size = NODE_SIZE;
     605             : 
     606   356883059 :         new = krealloc(ifp->if_u1.if_root, new_size, GFP_NOFS | __GFP_NOFAIL);
     607   356884713 :         memset(new + ifp->if_bytes, 0, new_size - ifp->if_bytes);
     608   356884713 :         ifp->if_u1.if_root = new;
     609   356884713 :         cur->leaf = new;
     610   356884713 : }
     611             : 
     612             : /*
     613             :  * Increment the sequence counter on extent tree changes. If we are on a COW
     614             :  * fork, this allows the writeback code to skip looking for a COW extent if the
     615             :  * COW fork hasn't changed. We use WRITE_ONCE here to ensure the update to the
     616             :  * sequence counter is seen before the modifications to the extent tree itself
     617             :  * take effect.
     618             :  */
     619             : static inline void xfs_iext_inc_seq(struct xfs_ifork *ifp)
     620             : {
     621  2254810570 :         WRITE_ONCE(ifp->if_seq, READ_ONCE(ifp->if_seq) + 1);
     622             : }
     623             : 
     624             : void
     625  1765273884 : xfs_iext_insert_raw(
     626             :         struct xfs_ifork        *ifp,
     627             :         struct xfs_iext_cursor  *cur,
     628             :         struct xfs_bmbt_irec    *irec)
     629             : {
     630  1765273884 :         xfs_fileoff_t           offset = irec->br_startoff;
     631  1765273884 :         struct xfs_iext_leaf    *new = NULL;
     632  1765273884 :         int                     nr_entries, i;
     633             : 
     634  1765273884 :         xfs_iext_inc_seq(ifp);
     635             : 
     636  1765273884 :         if (ifp->if_height == 0)
     637   176993275 :                 xfs_iext_alloc_root(ifp, cur);
     638  1588280609 :         else if (ifp->if_height == 1)
     639   356882876 :                 xfs_iext_realloc_root(ifp, cur);
     640             : 
     641  1765352352 :         nr_entries = xfs_iext_leaf_nr_entries(ifp, cur->leaf, cur->pos);
     642  1765310330 :         ASSERT(nr_entries <= RECS_PER_LEAF);
     643  1871810006 :         ASSERT(cur->pos >= nr_entries ||
     644             :                xfs_iext_rec_cmp(cur_rec(cur), irec->br_startoff) != 0);
     645             : 
     646  1765310181 :         if (nr_entries == RECS_PER_LEAF)
     647    86092625 :                 new = xfs_iext_split_leaf(cur, &nr_entries);
     648             : 
     649             :         /*
     650             :          * Update the pointers in higher levels if the first entry changes
     651             :          * in an existing node.
     652             :          */
     653  1765310032 :         if (cur->leaf != new && cur->pos == 0 && nr_entries > 0) {
     654     9556131 :                 xfs_iext_update_node(ifp, xfs_iext_leaf_key(cur->leaf, 0),
     655             :                                 offset, 1, cur->leaf);
     656             :         }
     657             : 
     658  2141903015 :         for (i = nr_entries; i > cur->pos; i--)
     659   376618427 :                 cur->leaf->recs[i] = cur->leaf->recs[i - 1];
     660  1765284588 :         xfs_iext_set(cur_rec(cur), irec);
     661  1765256403 :         ifp->if_bytes += sizeof(struct xfs_iext_rec);
     662             : 
     663  1765256403 :         if (new)
     664    86092534 :                 xfs_iext_insert_node(ifp, xfs_iext_leaf_key(new, 0), new, 2);
     665  1765256490 : }
     666             : 
     667             : void
     668  1754992667 : xfs_iext_insert(
     669             :         struct xfs_inode        *ip,
     670             :         struct xfs_iext_cursor  *cur,
     671             :         struct xfs_bmbt_irec    *irec,
     672             :         int                     state)
     673             : {
     674  1754992667 :         struct xfs_ifork        *ifp = xfs_iext_state_to_fork(ip, state);
     675             : 
     676  1755006012 :         xfs_iext_insert_raw(ifp, cur, irec);
     677  1754960646 :         trace_xfs_iext_insert(ip, cur, state, _RET_IP_);
     678  1754937367 : }
     679             : 
     680             : static struct xfs_iext_node *
     681     1678685 : xfs_iext_rebalance_node(
     682             :         struct xfs_iext_node    *parent,
     683             :         int                     *pos,
     684             :         struct xfs_iext_node    *node,
     685             :         int                     nr_entries)
     686             : {
     687             :         /*
     688             :          * If the neighbouring nodes are completely full, or have different
     689             :          * parents, we might never be able to merge our node, and will only
     690             :          * delete it once the number of entries hits zero.
     691             :          */
     692     1678685 :         if (nr_entries == 0)
     693             :                 return node;
     694             : 
     695     1479454 :         if (*pos > 0) {
     696     1358174 :                 struct xfs_iext_node *prev = parent->ptrs[*pos - 1];
     697     1358174 :                 int nr_prev = xfs_iext_node_nr_entries(prev, 0), i;
     698             : 
     699     1358174 :                 if (nr_prev + nr_entries <= KEYS_PER_NODE) {
     700      205509 :                         for (i = 0; i < nr_entries; i++) {
     701      176823 :                                 prev->keys[nr_prev + i] = node->keys[i];
     702      176823 :                                 prev->ptrs[nr_prev + i] = node->ptrs[i];
     703             :                         }
     704             :                         return node;
     705             :                 }
     706             :         }
     707             : 
     708     2901536 :         if (*pos + 1 < xfs_iext_node_nr_entries(parent, *pos)) {
     709       70747 :                 struct xfs_iext_node *next = parent->ptrs[*pos + 1];
     710       70747 :                 int nr_next = xfs_iext_node_nr_entries(next, 0), i;
     711             : 
     712       70747 :                 if (nr_entries + nr_next <= KEYS_PER_NODE) {
     713             :                         /*
     714             :                          * Merge the next node into this node so that we don't
     715             :                          * have to do an additional update of the keys in the
     716             :                          * higher levels.
     717             :                          */
     718      172085 :                         for (i = 0; i < nr_next; i++) {
     719      155436 :                                 node->keys[nr_entries + i] = next->keys[i];
     720      155436 :                                 node->ptrs[nr_entries + i] = next->ptrs[i];
     721             :                         }
     722             : 
     723       16649 :                         ++*pos;
     724       16649 :                         return next;
     725             :                 }
     726             :         }
     727             : 
     728             :         return NULL;
     729             : }
     730             : 
     731             : static void
     732     5514330 : xfs_iext_remove_node(
     733             :         struct xfs_ifork        *ifp,
     734             :         xfs_fileoff_t           offset,
     735             :         void                    *victim)
     736             : {
     737     5514330 :         struct xfs_iext_node    *node, *parent;
     738     5514330 :         int                     level = 2, pos, nr_entries, i;
     739             : 
     740     5514330 :         ASSERT(level <= ifp->if_height);
     741     5514330 :         node = xfs_iext_find_level(ifp, offset, level);
     742    11028669 :         pos = xfs_iext_node_pos(node, offset);
     743     5758905 : again:
     744     5758905 :         ASSERT(node->ptrs[pos]);
     745     5758904 :         ASSERT(node->ptrs[pos] == victim);
     746     5758904 :         kmem_free(victim);
     747             : 
     748     5758905 :         nr_entries = xfs_iext_node_nr_entries(node, pos) - 1;
     749     5758897 :         offset = node->keys[0];
     750     9046099 :         for (i = pos; i < nr_entries; i++) {
     751     3287195 :                 node->keys[i] = node->keys[i + 1];
     752     3287195 :                 node->ptrs[i] = node->ptrs[i + 1];
     753             :         }
     754     5758904 :         node->keys[nr_entries] = XFS_IEXT_KEY_INVALID;
     755     5758903 :         node->ptrs[nr_entries] = NULL;
     756             : 
     757     5758902 :         if (pos == 0 && nr_entries > 0) {
     758       88680 :                 xfs_iext_update_node(ifp, offset, node->keys[0], level, node);
     759       88680 :                 offset = node->keys[0];
     760             :         }
     761             : 
     762     5758902 :         if (nr_entries >= KEYS_PER_NODE / 2)
     763     2093314 :                 return;
     764             : 
     765     3665588 :         if (level < ifp->if_height) {
     766             :                 /*
     767             :                  * If we aren't at the root yet try to find a neighbour node to
     768             :                  * merge with (or delete the node if it is empty), and then
     769             :                  * recurse up to the next level.
     770             :                  */
     771     1678685 :                 level++;
     772     1678685 :                 parent = xfs_iext_find_level(ifp, offset, level);
     773     1678685 :                 pos = xfs_iext_node_pos(parent, offset);
     774             : 
     775     1678685 :                 ASSERT(pos != KEYS_PER_NODE);
     776     1678685 :                 ASSERT(parent->ptrs[pos] == node);
     777             : 
     778     1678685 :                 node = xfs_iext_rebalance_node(parent, &pos, node, nr_entries);
     779     1678685 :                 if (node) {
     780      244566 :                         victim = node;
     781      244566 :                         node = parent;
     782      244566 :                         goto again;
     783             :                 }
     784     1986903 :         } else if (nr_entries == 1) {
     785             :                 /*
     786             :                  * If we are at the root and only one entry is left we can just
     787             :                  * free this node and update the root pointer.
     788             :                  */
     789     1116286 :                 ASSERT(node == ifp->if_u1.if_root);
     790     1116286 :                 ifp->if_u1.if_root = node->ptrs[0];
     791     1116286 :                 ifp->if_height--;
     792     1116286 :                 kmem_free(node);
     793             :         }
     794             : }
     795             : 
     796             : static void
     797    25316922 : xfs_iext_rebalance_leaf(
     798             :         struct xfs_ifork        *ifp,
     799             :         struct xfs_iext_cursor  *cur,
     800             :         struct xfs_iext_leaf    *leaf,
     801             :         xfs_fileoff_t           offset,
     802             :         int                     nr_entries)
     803             : {
     804             :         /*
     805             :          * If the neighbouring nodes are completely full we might never be able
     806             :          * to merge our node, and will only delete it once the number of
     807             :          * entries hits zero.
     808             :          */
     809    25316922 :         if (nr_entries == 0)
     810     3119208 :                 goto remove_node;
     811             : 
     812    22197714 :         if (leaf->prev) {
     813             :                 int nr_prev = xfs_iext_leaf_nr_entries(ifp, leaf->prev, 0), i;
     814             : 
     815    21579139 :                 if (nr_prev + nr_entries <= RECS_PER_LEAF) {
     816    12128241 :                         for (i = 0; i < nr_entries; i++)
     817    10196320 :                                 leaf->prev->recs[nr_prev + i] = leaf->recs[i];
     818             : 
     819     1931921 :                         if (cur->leaf == leaf) {
     820      584110 :                                 cur->leaf = leaf->prev;
     821      584110 :                                 cur->pos += nr_prev;
     822             :                         }
     823     1931921 :                         goto remove_node;
     824             :                 }
     825             :         }
     826             : 
     827    20265842 :         if (leaf->next) {
     828             :                 int nr_next = xfs_iext_leaf_nr_entries(ifp, leaf->next, 0), i;
     829             : 
     830      989012 :                 if (nr_entries + nr_next <= RECS_PER_LEAF) {
     831             :                         /*
     832             :                          * Merge the next node into this node so that we don't
     833             :                          * have to do an additional update of the keys in the
     834             :                          * higher levels.
     835             :                          */
     836     4299136 :                         for (i = 0; i < nr_next; i++) {
     837     3835924 :                                 leaf->recs[nr_entries + i] =
     838     3835924 :                                         leaf->next->recs[i];
     839             :                         }
     840             : 
     841      463212 :                         if (cur->leaf == leaf->next) {
     842       83145 :                                 cur->leaf = leaf;
     843       83145 :                                 cur->pos += nr_entries;
     844             :                         }
     845             : 
     846      463212 :                         offset = xfs_iext_leaf_key(leaf->next, 0);
     847      463212 :                         leaf = leaf->next;
     848      463212 :                         goto remove_node;
     849             :                 }
     850             :         }
     851             : 
     852             :         return;
     853     5514341 : remove_node:
     854     5514341 :         if (leaf->prev)
     855     5513014 :                 leaf->prev->next = leaf->next;
     856     5514341 :         if (leaf->next)
     857      607690 :                 leaf->next->prev = leaf->prev;
     858     5514341 :         xfs_iext_remove_node(ifp, offset, leaf);
     859             : }
     860             : 
     861             : static void
     862             : xfs_iext_free_last_leaf(
     863             :         struct xfs_ifork        *ifp)
     864             : {
     865    41314622 :         ifp->if_height--;
     866    41314622 :         kmem_free(ifp->if_u1.if_root);
     867    41422068 :         ifp->if_u1.if_root = NULL;
     868    41422068 : }
     869             : 
     870             : void
     871   150089097 : xfs_iext_remove(
     872             :         struct xfs_inode        *ip,
     873             :         struct xfs_iext_cursor  *cur,
     874             :         int                     state)
     875             : {
     876   150089097 :         struct xfs_ifork        *ifp = xfs_iext_state_to_fork(ip, state);
     877   150065548 :         struct xfs_iext_leaf    *leaf = cur->leaf;
     878   150065548 :         xfs_fileoff_t           offset = xfs_iext_leaf_key(leaf, 0);
     879   150065548 :         int                     i, nr_entries;
     880             : 
     881   150065548 :         trace_xfs_iext_remove(ip, cur, state, _RET_IP_);
     882             : 
     883   150067941 :         ASSERT(ifp->if_height > 0);
     884   150067941 :         ASSERT(ifp->if_u1.if_root != NULL);
     885   150067941 :         ASSERT(xfs_iext_valid(ifp, cur));
     886             : 
     887   150041903 :         xfs_iext_inc_seq(ifp);
     888             : 
     889   150041903 :         nr_entries = xfs_iext_leaf_nr_entries(ifp, leaf, cur->pos) - 1;
     890   275401047 :         for (i = cur->pos; i < nr_entries; i++)
     891   125307955 :                 leaf->recs[i] = leaf->recs[i + 1];
     892   150093092 :         xfs_iext_rec_clear(&leaf->recs[nr_entries]);
     893   150061601 :         ifp->if_bytes -= sizeof(struct xfs_iext_rec);
     894             : 
     895   150061601 :         if (cur->pos == 0 && nr_entries > 0) {
     896     3978711 :                 xfs_iext_update_node(ifp, offset, xfs_iext_leaf_key(leaf, 0), 1,
     897             :                                 leaf);
     898     3978708 :                 offset = xfs_iext_leaf_key(leaf, 0);
     899   146082890 :         } else if (cur->pos == nr_entries) {
     900   120946983 :                 if (ifp->if_height > 1 && leaf->next)
     901     1184710 :                         cur->leaf = leaf->next;
     902             :                 else
     903   119762273 :                         cur->leaf = NULL;
     904   120946983 :                 cur->pos = 0;
     905             :         }
     906             : 
     907   150061598 :         if (nr_entries >= RECS_PER_LEAF / 2)
     908             :                 return;
     909             : 
     910    87469009 :         if (ifp->if_height > 1)
     911    25316917 :                 xfs_iext_rebalance_leaf(ifp, cur, leaf, offset, nr_entries);
     912    62152092 :         else if (nr_entries == 0)
     913    41314622 :                 xfs_iext_free_last_leaf(ifp);
     914             : }
     915             : 
     916             : /*
     917             :  * Lookup the extent covering bno.
     918             :  *
     919             :  * If there is an extent covering bno return the extent index, and store the
     920             :  * expanded extent structure in *gotp, and the extent cursor in *cur.
     921             :  * If there is no extent covering bno, but there is an extent after it (e.g.
     922             :  * it lies in a hole) return that extent in *gotp and its cursor in *cur
     923             :  * instead.
     924             :  * If bno is beyond the last extent return false, and return an invalid
     925             :  * cursor value.
     926             :  */
     927             : bool
     928 10469826870 : xfs_iext_lookup_extent(
     929             :         struct xfs_inode        *ip,
     930             :         struct xfs_ifork        *ifp,
     931             :         xfs_fileoff_t           offset,
     932             :         struct xfs_iext_cursor  *cur,
     933             :         struct xfs_bmbt_irec    *gotp)
     934             : {
     935 10469826870 :         XFS_STATS_INC(ip->i_mount, xs_look_exlist);
     936             : 
     937 10467532995 :         cur->leaf = xfs_iext_find_level(ifp, offset, 1);
     938 10469833994 :         if (!cur->leaf) {
     939   268093033 :                 cur->pos = 0;
     940   268093033 :                 return false;
     941             :         }
     942             : 
     943 51326603012 :         for (cur->pos = 0; cur->pos < xfs_iext_max_recs(ifp); cur->pos++) {
     944 34217763539 :                 struct xfs_iext_rec *rec = cur_rec(cur);
     945             : 
     946 34213717716 :                 if (xfs_iext_rec_is_empty(rec))
     947             :                         break;
     948 34000929275 :                 if (xfs_iext_rec_cmp(rec, offset) >= 0)
     949  9445428634 :                         goto found;
     950             :         }
     951             : 
     952             :         /* Try looking in the next node for an entry > offset */
     953   752266504 :         if (ifp->if_height == 1 || !cur->leaf->next)
     954             :                 return false;
     955    27976593 :         cur->leaf = cur->leaf->next;
     956    27976593 :         cur->pos = 0;
     957    27976593 :         if (!xfs_iext_valid(ifp, cur))
     958             :                 return false;
     959    27976531 : found:
     960  9473405165 :         xfs_iext_get(gotp, cur_rec(cur));
     961  9481728886 :         return true;
     962             : }
     963             : 
     964             : /*
     965             :  * Returns the last extent before end, and if this extent doesn't cover
     966             :  * end, update end to the end of the extent.
     967             :  */
     968             : bool
     969   176543958 : xfs_iext_lookup_extent_before(
     970             :         struct xfs_inode        *ip,
     971             :         struct xfs_ifork        *ifp,
     972             :         xfs_fileoff_t           *end,
     973             :         struct xfs_iext_cursor  *cur,
     974             :         struct xfs_bmbt_irec    *gotp)
     975             : {
     976             :         /* could be optimized to not even look up the next on a match.. */
     977   176543958 :         if (xfs_iext_lookup_extent(ip, ifp, *end - 1, cur, gotp) &&
     978   101082270 :             gotp->br_startoff <= *end - 1)
     979             :                 return true;
     980    81734173 :         if (!xfs_iext_prev_extent(ifp, cur, gotp))
     981             :                 return false;
     982    80921426 :         *end = gotp->br_startoff + gotp->br_blockcount;
     983    80921426 :         return true;
     984             : }
     985             : 
     986             : void
     987   339513460 : xfs_iext_update_extent(
     988             :         struct xfs_inode        *ip,
     989             :         int                     state,
     990             :         struct xfs_iext_cursor  *cur,
     991             :         struct xfs_bmbt_irec    *new)
     992             : {
     993   339513460 :         struct xfs_ifork        *ifp = xfs_iext_state_to_fork(ip, state);
     994             : 
     995   339494783 :         xfs_iext_inc_seq(ifp);
     996             : 
     997   339494783 :         if (cur->pos == 0) {
     998    66931265 :                 struct xfs_bmbt_irec    old;
     999             : 
    1000    66931265 :                 xfs_iext_get(&old, cur_rec(cur));
    1001    66934782 :                 if (new->br_startoff != old.br_startoff) {
    1002    11842651 :                         xfs_iext_update_node(ifp, old.br_startoff,
    1003             :                                         new->br_startoff, 1, cur->leaf);
    1004             :                 }
    1005             :         }
    1006             : 
    1007   339498299 :         trace_xfs_bmap_pre_update(ip, cur, state, _RET_IP_);
    1008   339487080 :         xfs_iext_set(cur_rec(cur), new);
    1009   339486221 :         trace_xfs_bmap_post_update(ip, cur, state, _RET_IP_);
    1010   339481411 : }
    1011             : 
    1012             : /*
    1013             :  * Return true if the cursor points at an extent and return the extent structure
    1014             :  * in gotp.  Else return false.
    1015             :  */
    1016             : bool
    1017  9066544754 : xfs_iext_get_extent(
    1018             :         struct xfs_ifork        *ifp,
    1019             :         struct xfs_iext_cursor  *cur,
    1020             :         struct xfs_bmbt_irec    *gotp)
    1021             : {
    1022  9066544754 :         if (!xfs_iext_valid(ifp, cur))
    1023             :                 return false;
    1024  7694497575 :         xfs_iext_get(gotp, cur_rec(cur));
    1025  7694668256 :         return true;
    1026             : }
    1027             : 
    1028             : /*
    1029             :  * This is a recursive function, because of that we need to be extremely
    1030             :  * careful with stack usage.
    1031             :  */
    1032             : static void
    1033   222647863 : xfs_iext_destroy_node(
    1034             :         struct xfs_iext_node    *node,
    1035             :         int                     level)
    1036             : {
    1037   222647863 :         int                     i;
    1038             : 
    1039   222647863 :         if (level > 1) {
    1040    93596492 :                 for (i = 0; i < KEYS_PER_NODE; i++) {
    1041    88858362 :                         if (node->keys[i] == XFS_IEXT_KEY_INVALID)
    1042             :                                 break;
    1043    87086844 :                         xfs_iext_destroy_node(node->ptrs[i], level - 1);
    1044             :                 }
    1045             :         }
    1046             : 
    1047   222647873 :         kmem_free(node);
    1048   222676173 : }
    1049             : 
    1050             : void
    1051   135591300 : xfs_iext_destroy(
    1052             :         struct xfs_ifork        *ifp)
    1053             : {
    1054   135591300 :         xfs_iext_destroy_node(ifp->if_u1.if_root, ifp->if_height);
    1055             : 
    1056   135581069 :         ifp->if_bytes = 0;
    1057   135581069 :         ifp->if_height = 0;
    1058   135581069 :         ifp->if_u1.if_root = NULL;
    1059   135581069 : }

Generated by: LCOV version 1.14