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-djwx @ Mon Jul 31 20:08:22 PDT 2023 Lines: 438 441 99.3 %
Date: 2023-07-31 20:08:22 Functions: 29 29 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 47232109141 :         return rec->hi == 0;
      44             : }
      45             : 
      46             : static inline void xfs_iext_rec_clear(struct xfs_iext_rec *rec)
      47             : {
      48   177270933 :         rec->lo = 0;
      49   177270933 :         rec->hi = 0;
      50             : }
      51             : 
      52             : static void
      53  2037767648 : xfs_iext_set(
      54             :         struct xfs_iext_rec     *rec,
      55             :         struct xfs_bmbt_irec    *irec)
      56             : {
      57  2037767648 :         ASSERT((irec->br_startoff & ~XFS_IEXT_STARTOFF_MASK) == 0);
      58  2037767648 :         ASSERT((irec->br_blockcount & ~XFS_IEXT_LENGTH_MASK) == 0);
      59  2037767648 :         ASSERT((irec->br_startblock & ~XFS_IEXT_STARTBLOCK_MASK) == 0);
      60             : 
      61  2037767648 :         rec->lo = irec->br_startoff & XFS_IEXT_STARTOFF_MASK;
      62  2037767648 :         rec->hi = irec->br_blockcount & XFS_IEXT_LENGTH_MASK;
      63             : 
      64  2037767648 :         rec->lo |= (irec->br_startblock << 54);
      65  2037767648 :         rec->hi |= ((irec->br_startblock & ~xfs_mask64lo(10)) << (22 - 10));
      66             : 
      67  2037767648 :         if (irec->br_state == XFS_EXT_UNWRITTEN)
      68   323728634 :                 rec->hi |= (1 << 21);
      69  2037767648 : }
      70             : 
      71             : static void
      72 15341490959 : xfs_iext_get(
      73             :         struct xfs_bmbt_irec    *irec,
      74             :         struct xfs_iext_rec     *rec)
      75             : {
      76 15341490959 :         irec->br_startoff = rec->lo & XFS_IEXT_STARTOFF_MASK;
      77 15341490959 :         irec->br_blockcount = rec->hi & XFS_IEXT_LENGTH_MASK;
      78             : 
      79 15341490959 :         irec->br_startblock = rec->lo >> 54;
      80 15341490959 :         irec->br_startblock |= (rec->hi & xfs_mask64hi(42)) >> (22 - 10);
      81             : 
      82 15341490959 :         if (rec->hi & (1 << 21))
      83  2258446456 :                 irec->br_state = XFS_EXT_UNWRITTEN;
      84             :         else
      85 13083044503 :                 irec->br_state = XFS_EXT_NORM;
      86 15341490959 : }
      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   615551371 : inline xfs_extnum_t xfs_iext_count(struct xfs_ifork *ifp)
     129             : {
     130 26693491245 :         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 13196674033 :         if (ifp->if_height == 1)
     136 26077939874 :                 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 74322934518 :         return &cur->leaf->recs[cur->pos];
     143             : }
     144             : 
     145 13740333062 : static inline bool xfs_iext_valid(struct xfs_ifork *ifp,
     146             :                 struct xfs_iext_cursor *cur)
     147             : {
     148 13740333062 :         if (!cur->leaf)
     149             :                 return false;
     150 26520141491 :         if (cur->pos < 0 || cur->pos >= xfs_iext_max_recs(ifp))
     151             :                 return false;
     152 12290151976 :         if (xfs_iext_rec_is_empty(cur_rec(cur)))
     153  1388866207 :                 return false;
     154             :         return true;
     155             : }
     156             : 
     157             : static void *
     158  1235649046 : xfs_iext_find_first_leaf(
     159             :         struct xfs_ifork        *ifp)
     160             : {
     161  1235649046 :         struct xfs_iext_node    *node = ifp->if_u1.if_root;
     162  1235649046 :         int                     height;
     163             : 
     164  1235649046 :         if (!ifp->if_height)
     165             :                 return NULL;
     166             : 
     167   979001680 :         for (height = ifp->if_height; height > 1; height--) {
     168    56009750 :                 node = node->ptrs[0];
     169    56009750 :                 ASSERT(node);
     170             :         }
     171             : 
     172             :         return node;
     173             : }
     174             : 
     175             : static void *
     176  1049906729 : xfs_iext_find_last_leaf(
     177             :         struct xfs_ifork        *ifp)
     178             : {
     179  1049906729 :         struct xfs_iext_node    *node = ifp->if_u1.if_root;
     180  1049906729 :         int                     height, i;
     181             : 
     182  1049906729 :         if (!ifp->if_height)
     183             :                 return NULL;
     184             : 
     185  1408008223 :         for (height = ifp->if_height; height > 1; height--) {
     186  3488618923 :                 for (i = 1; i < KEYS_PER_NODE; i++)
     187  3475840536 :                         if (!node->ptrs[i])
     188             :                                 break;
     189   572539699 :                 node = node->ptrs[i - 1];
     190   572593229 :                 ASSERT(node);
     191             :         }
     192             : 
     193             :         return node;
     194             : }
     195             : 
     196             : void
     197  1052274890 : xfs_iext_first(
     198             :         struct xfs_ifork        *ifp,
     199             :         struct xfs_iext_cursor  *cur)
     200             : {
     201  1235757409 :         cur->pos = 0;
     202  1052274890 :         cur->leaf = xfs_iext_find_first_leaf(ifp);
     203  1052207211 : }
     204             : 
     205             : void
     206  1050839906 : xfs_iext_last(
     207             :         struct xfs_ifork        *ifp,
     208             :         struct xfs_iext_cursor  *cur)
     209             : {
     210  1050839906 :         int                     i;
     211             : 
     212  1050839906 :         cur->leaf = xfs_iext_find_last_leaf(ifp);
     213  1050660475 :         if (!cur->leaf) {
     214   214489837 :                 cur->pos = 0;
     215   214489837 :                 return;
     216             :         }
     217             : 
     218  8834664006 :         for (i = 1; i < xfs_iext_max_recs(ifp); i++) {
     219  5727944579 :                 if (xfs_iext_rec_is_empty(&cur->leaf->recs[i]))
     220             :                         break;
     221             :         }
     222   838996707 :         cur->pos = i - 1;
     223             : }
     224             : 
     225             : void
     226  7427407070 : xfs_iext_next(
     227             :         struct xfs_ifork        *ifp,
     228             :         struct xfs_iext_cursor  *cur)
     229             : {
     230  7427407070 :         if (!cur->leaf) {
     231   183482519 :                 ASSERT(cur->pos <= 0 || cur->pos >= RECS_PER_LEAF);
     232   183482519 :                 xfs_iext_first(ifp, cur);
     233   183499775 :                 return;
     234             :         }
     235             : 
     236  7243924551 :         ASSERT(cur->pos >= 0);
     237 10771609686 :         ASSERT(cur->pos < xfs_iext_max_recs(ifp));
     238             : 
     239  7243924551 :         cur->pos++;
     240  7243924551 :         if (ifp->if_height > 1 && !xfs_iext_valid(ifp, cur) &&
     241  1279221504 :             cur->leaf->next) {
     242   205813890 :                 cur->leaf = cur->leaf->next;
     243   205813890 :                 cur->pos = 0;
     244             :         }
     245             : }
     246             : 
     247             : void
     248   877230924 : xfs_iext_prev(
     249             :         struct xfs_ifork        *ifp,
     250             :         struct xfs_iext_cursor  *cur)
     251             : {
     252   877230924 :         if (!cur->leaf) {
     253   175778137 :                 ASSERT(cur->pos <= 0 || cur->pos >= RECS_PER_LEAF);
     254   175778137 :                 xfs_iext_last(ifp, cur);
     255   175778137 :                 return;
     256             :         }
     257             : 
     258   701452787 :         ASSERT(cur->pos >= 0);
     259   701452787 :         ASSERT(cur->pos <= RECS_PER_LEAF);
     260             : 
     261   701452787 : recurse:
     262   792172466 :         do {
     263   792172466 :                 cur->pos--;
     264   792172466 :                 if (xfs_iext_valid(ifp, cur))
     265             :                         return;
     266   145753824 :         } while (cur->pos > 0);
     267             : 
     268    73622768 :         if (ifp->if_height > 1 && cur->leaf->prev) {
     269    18588623 :                 cur->leaf = cur->leaf->prev;
     270    18588623 :                 cur->pos = RECS_PER_LEAF;
     271    18588623 :                 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 24055180695 :         if (node->keys[n] > offset)
     282             :                 return 1;
     283 19772729995 :         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 27131559277 :         uint64_t                rec_offset = rec->lo & XFS_IEXT_STARTOFF_MASK;
     294 27131559277 :         uint32_t                rec_len = rec->hi & XFS_IEXT_LENGTH_MASK;
     295             : 
     296    92105526 :         if (rec_offset > offset)
     297             :                 return 1;
     298 25712649209 :         if (rec_offset + rec_len <= offset)
     299           0 :                 return -1;
     300             :         return 0;
     301             : }
     302             : 
     303             : static void *
     304  8688881714 : xfs_iext_find_level(
     305             :         struct xfs_ifork        *ifp,
     306             :         xfs_fileoff_t           offset,
     307             :         int                     level)
     308             : {
     309  8688881714 :         struct xfs_iext_node    *node = ifp->if_u1.if_root;
     310  8688881714 :         int                     height, i;
     311             : 
     312  8688881714 :         if (!ifp->if_height)
     313             :                 return NULL;
     314             : 
     315 12686388109 :         for (height = ifp->if_height; height > level; height--) {
     316 23119808316 :                 for (i = 1; i < KEYS_PER_NODE; i++)
     317 23020050462 :                         if (xfs_iext_key_cmp(node, i, offset) > 0)
     318             :                                 break;
     319             : 
     320  4252452344 :                 node = node->ptrs[i - 1];
     321  4252634762 :                 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     6283182 :         int                     i;
     334             : 
     335    42644841 :         for (i = 1; i < KEYS_PER_NODE; i++) {
     336    42389075 :                 if (xfs_iext_key_cmp(node, i, offset) > 0)
     337             :                         break;
     338             :         }
     339             : 
     340     6283193 :         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    87330366 :         int                     i;
     349             : 
     350   783582030 :         for (i = 0; i < KEYS_PER_NODE; i++) {
     351   778650883 :                 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     2661724 :         int                     i;
     364             : 
     365   140348646 :         for (i = start; i < KEYS_PER_NODE; i++) {
     366   133355156 :                 if (node->keys[i] == XFS_IEXT_KEY_INVALID)
     367             :                         break;
     368             :         }
     369             : 
     370    94951687 :         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  1728974350 :         int                     i;
     380             : 
     381  3598362379 :         for (i = start; i < xfs_iext_max_recs(ifp); i++) {
     382  1970570683 :                 if (xfs_iext_rec_is_empty(&leaf->recs[i]))
     383             :                         break;
     384             :         }
     385             : 
     386  1875718976 :         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   227457276 :         return leaf->recs[n].lo & XFS_IEXT_STARTOFF_MASK;
     395             : }
     396             : 
     397             : static void
     398     4444501 : xfs_iext_grow(
     399             :         struct xfs_ifork        *ifp)
     400             : {
     401     4444501 :         struct xfs_iext_node    *node = kmem_zalloc(NODE_SIZE, KM_NOFS);
     402     4444504 :         int                     i;
     403             : 
     404     4444504 :         if (ifp->if_height == 1) {
     405     4343968 :                 struct xfs_iext_leaf *prev = ifp->if_u1.if_root;
     406             : 
     407     4343968 :                 node->keys[0] = xfs_iext_leaf_key(prev, 0);
     408     4343968 :                 node->ptrs[0] = prev;
     409             :         } else  {
     410      100536 :                 struct xfs_iext_node *prev = ifp->if_u1.if_root;
     411             : 
     412      100536 :                 ASSERT(ifp->if_height > 1);
     413             : 
     414      100536 :                 node->keys[0] = prev->keys[0];
     415      100536 :                 node->ptrs[0] = prev;
     416             :         }
     417             : 
     418    71111919 :         for (i = 1; i < KEYS_PER_NODE; i++)
     419    66667418 :                 node->keys[i] = XFS_IEXT_KEY_INVALID;
     420             : 
     421     4444501 :         ifp->if_u1.if_root = node;
     422     4444501 :         ifp->if_height++;
     423     4444501 : }
     424             : 
     425             : static void
     426    22882694 : 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    22882694 :         struct xfs_iext_node    *node = ifp->if_u1.if_root;
     434    22882694 :         int                     height, i;
     435             : 
     436    62174493 :         for (height = ifp->if_height; height > level; height--) {
     437   247998667 :                 for (i = 0; i < KEYS_PER_NODE; i++) {
     438   247115015 :                         if (i > 0 && xfs_iext_key_cmp(node, i, old_offset) > 0)
     439             :                                 break;
     440   208706894 :                         if (node->keys[i] == old_offset)
     441    16014873 :                                 node->keys[i] = new_offset;
     442             :                 }
     443    39291803 :                 node = node->ptrs[i - 1];
     444    39291799 :                 ASSERT(node);
     445             :         }
     446             : 
     447    22882708 :         ASSERT(node == ptr);
     448    22882708 : }
     449             : 
     450             : static struct xfs_iext_node *
     451     5483574 : xfs_iext_split_node(
     452             :         struct xfs_iext_node    **nodep,
     453             :         int                     *pos,
     454             :         int                     *nr_entries)
     455             : {
     456     5483574 :         struct xfs_iext_node    *node = *nodep;
     457     5483574 :         struct xfs_iext_node    *new = kmem_zalloc(NODE_SIZE, KM_NOFS);
     458     5483574 :         const int               nr_move = KEYS_PER_NODE / 2;
     459     5483574 :         int                     nr_keep = nr_move + (KEYS_PER_NODE & 1);
     460     5483574 :         int                     i = 0;
     461             : 
     462             :         /* for sequential append operations just spill over into the new node */
     463     5483574 :         if (*pos == KEYS_PER_NODE) {
     464     4931144 :                 *nodep = new;
     465     4931144 :                 *pos = 0;
     466     4931144 :                 *nr_entries = 0;
     467     4931144 :                 goto done;
     468             :         }
     469             : 
     470             : 
     471     4971633 :         for (i = 0; i < nr_move; i++) {
     472     4419207 :                 new->keys[i] = node->keys[nr_keep + i];
     473     4419211 :                 new->ptrs[i] = node->ptrs[nr_keep + i];
     474             : 
     475     4419197 :                 node->keys[nr_keep + i] = XFS_IEXT_KEY_INVALID;
     476     4419193 :                 node->ptrs[nr_keep + i] = NULL;
     477             :         }
     478             : 
     479      552426 :         if (*pos >= nr_keep) {
     480      305639 :                 *nodep = new;
     481      305639 :                 *pos -= nr_keep;
     482      305639 :                 *nr_entries = nr_move;
     483             :         } else {
     484      246787 :                 *nr_entries = nr_keep;
     485             :         }
     486             : done:
     487    88801107 :         for (; i < KEYS_PER_NODE; i++)
     488    83317541 :                 new->keys[i] = XFS_IEXT_KEY_INVALID;
     489     5483566 :         return new;
     490             : }
     491             : 
     492             : static void
     493    81846863 : xfs_iext_insert_node(
     494             :         struct xfs_ifork        *ifp,
     495             :         uint64_t                offset,
     496             :         void                    *ptr,
     497             :         int                     level)
     498             : {
     499    87330434 :         struct xfs_iext_node    *node, *new;
     500    87330434 :         int                     i, pos, nr_entries;
     501             : 
     502    87330434 : again:
     503    87330434 :         if (ifp->if_height < level)
     504     4444508 :                 xfs_iext_grow(ifp);
     505             : 
     506    87330429 :         new = NULL;
     507    87330429 :         node = xfs_iext_find_level(ifp, offset, level);
     508    87330366 :         pos = xfs_iext_node_insert_pos(node, offset);
     509    87330502 :         nr_entries = xfs_iext_node_nr_entries(node, pos);
     510             : 
     511    90251764 :         ASSERT(pos >= nr_entries || xfs_iext_key_cmp(node, pos, offset) != 0);
     512    87330431 :         ASSERT(nr_entries <= KEYS_PER_NODE);
     513             : 
     514    87330431 :         if (nr_entries == KEYS_PER_NODE)
     515     5483575 :                 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    87330445 :         if (node != new && pos == 0 && nr_entries > 0)
     522           0 :                 xfs_iext_update_node(ifp, node->keys[0], offset, level, node);
     523             : 
     524   100459121 :         for (i = nr_entries; i > pos; i--) {
     525    13128711 :                 node->keys[i] = node->keys[i - 1];
     526    13128700 :                 node->ptrs[i] = node->ptrs[i - 1];
     527             :         }
     528    87330410 :         node->keys[pos] = offset;
     529    87330411 :         node->ptrs[pos] = ptr;
     530             : 
     531    87330471 :         if (new) {
     532     5483571 :                 offset = new->keys[0];
     533     5483571 :                 ptr = new;
     534     5483571 :                 level++;
     535     5483571 :                 goto again;
     536             :         }
     537    81846900 : }
     538             : 
     539             : static struct xfs_iext_leaf *
     540    81846900 : xfs_iext_split_leaf(
     541             :         struct xfs_iext_cursor  *cur,
     542             :         int                     *nr_entries)
     543             : {
     544    81846900 :         struct xfs_iext_leaf    *leaf = cur->leaf;
     545    81846900 :         struct xfs_iext_leaf    *new = kmem_zalloc(NODE_SIZE, KM_NOFS);
     546    81846813 :         const int               nr_move = RECS_PER_LEAF / 2;
     547    81846813 :         int                     nr_keep = nr_move + (RECS_PER_LEAF & 1);
     548    81846813 :         int                     i;
     549             : 
     550             :         /* for sequential append operations just spill over into the new node */
     551    81846813 :         if (cur->pos == RECS_PER_LEAF) {
     552    74522512 :                 cur->leaf = new;
     553    74522512 :                 cur->pos = 0;
     554    74522512 :                 *nr_entries = 0;
     555    74522512 :                 goto done;
     556             :         }
     557             : 
     558    58594090 :         for (i = 0; i < nr_move; i++) {
     559    51269773 :                 new->recs[i] = leaf->recs[nr_keep + i];
     560    51269784 :                 xfs_iext_rec_clear(&leaf->recs[nr_keep + i]);
     561             :         }
     562             : 
     563     7324317 :         if (cur->pos >= nr_keep) {
     564     5594458 :                 cur->leaf = new;
     565     5594458 :                 cur->pos -= nr_keep;
     566     5594458 :                 *nr_entries = nr_move;
     567             :         } else {
     568     1729859 :                 *nr_entries = nr_keep;
     569             :         }
     570    81846829 : done:
     571    81846829 :         if (leaf->next)
     572     2618384 :                 leaf->next->prev = new;
     573    81846829 :         new->next = leaf->next;
     574    81846829 :         new->prev = leaf;
     575    81846829 :         leaf->next = new;
     576    81846829 :         return new;
     577             : }
     578             : 
     579             : static void
     580   161183165 : xfs_iext_alloc_root(
     581             :         struct xfs_ifork        *ifp,
     582             :         struct xfs_iext_cursor  *cur)
     583             : {
     584   161183165 :         ASSERT(ifp->if_bytes == 0);
     585             : 
     586   161183165 :         ifp->if_u1.if_root = kmem_zalloc(sizeof(struct xfs_iext_rec), KM_NOFS);
     587   161207661 :         ifp->if_height = 1;
     588             : 
     589             :         /* now that we have a node step into it */
     590   161207661 :         cur->leaf = ifp->if_u1.if_root;
     591   161207661 :         cur->pos = 0;
     592   161207661 : }
     593             : 
     594             : static void
     595   434492072 : xfs_iext_realloc_root(
     596             :         struct xfs_ifork        *ifp,
     597             :         struct xfs_iext_cursor  *cur)
     598             : {
     599   434492072 :         int64_t new_size = ifp->if_bytes + sizeof(struct xfs_iext_rec);
     600   434492072 :         void *new;
     601             : 
     602             :         /* account for the prev/next pointers */
     603   434492072 :         if (new_size / sizeof(struct xfs_iext_rec) == RECS_PER_LEAF)
     604     5948115 :                 new_size = NODE_SIZE;
     605             : 
     606   434492072 :         new = krealloc(ifp->if_u1.if_root, new_size, GFP_NOFS | __GFP_NOFAIL);
     607   434494481 :         memset(new + ifp->if_bytes, 0, new_size - ifp->if_bytes);
     608   434494481 :         ifp->if_u1.if_root = new;
     609   434494481 :         cur->leaf = new;
     610   434494481 : }
     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  2163809061 :         WRITE_ONCE(ifp->if_seq, READ_ONCE(ifp->if_seq) + 1);
     622             : }
     623             : 
     624             : void
     625  1728943563 : xfs_iext_insert(
     626             :         struct xfs_inode        *ip,
     627             :         struct xfs_iext_cursor  *cur,
     628             :         struct xfs_bmbt_irec    *irec,
     629             :         int                     state)
     630             : {
     631  1728943563 :         struct xfs_ifork        *ifp = xfs_iext_state_to_fork(ip, state);
     632  1728927931 :         xfs_fileoff_t           offset = irec->br_startoff;
     633  1728927931 :         struct xfs_iext_leaf    *new = NULL;
     634  1728927931 :         int                     nr_entries, i;
     635             : 
     636  1728927931 :         xfs_iext_inc_seq(ifp);
     637             : 
     638  1728927931 :         if (ifp->if_height == 0)
     639   161160265 :                 xfs_iext_alloc_root(ifp, cur);
     640  1567767666 :         else if (ifp->if_height == 1)
     641   434492923 :                 xfs_iext_realloc_root(ifp, cur);
     642             : 
     643  1728974350 :         nr_entries = xfs_iext_leaf_nr_entries(ifp, cur->leaf, cur->pos);
     644  1728955410 :         ASSERT(nr_entries <= RECS_PER_LEAF);
     645  1821060936 :         ASSERT(cur->pos >= nr_entries ||
     646             :                xfs_iext_rec_cmp(cur_rec(cur), irec->br_startoff) != 0);
     647             : 
     648  1728954945 :         if (nr_entries == RECS_PER_LEAF)
     649    81846876 :                 new = xfs_iext_split_leaf(cur, &nr_entries);
     650             : 
     651             :         /*
     652             :          * Update the pointers in higher levels if the first entry changes
     653             :          * in an existing node.
     654             :          */
     655  1728954847 :         if (cur->leaf != new && cur->pos == 0 && nr_entries > 0) {
     656     8231319 :                 xfs_iext_update_node(ifp, xfs_iext_leaf_key(cur->leaf, 0),
     657             :                                 offset, 1, cur->leaf);
     658             :         }
     659             : 
     660  2055549622 :         for (i = nr_entries; i > cur->pos; i--)
     661   326603988 :                 cur->leaf->recs[i] = cur->leaf->recs[i - 1];
     662  1728945634 :         xfs_iext_set(cur_rec(cur), irec);
     663  1728915508 :         ifp->if_bytes += sizeof(struct xfs_iext_rec);
     664             : 
     665  1728915508 :         trace_xfs_iext_insert(ip, cur, state, _RET_IP_);
     666             : 
     667  1728914901 :         if (new)
     668    81846877 :                 xfs_iext_insert_node(ifp, xfs_iext_leaf_key(new, 0), new, 2);
     669  1728914921 : }
     670             : 
     671             : static struct xfs_iext_node *
     672     1549021 : xfs_iext_rebalance_node(
     673             :         struct xfs_iext_node    *parent,
     674             :         int                     *pos,
     675             :         struct xfs_iext_node    *node,
     676             :         int                     nr_entries)
     677             : {
     678             :         /*
     679             :          * If the neighbouring nodes are completely full, or have different
     680             :          * parents, we might never be able to merge our node, and will only
     681             :          * delete it once the number of entries hits zero.
     682             :          */
     683     1549021 :         if (nr_entries == 0)
     684             :                 return node;
     685             : 
     686     1364487 :         if (*pos > 0) {
     687     1258085 :                 struct xfs_iext_node *prev = parent->ptrs[*pos - 1];
     688     1258085 :                 int nr_prev = xfs_iext_node_nr_entries(prev, 0), i;
     689             : 
     690     1258085 :                 if (nr_prev + nr_entries <= KEYS_PER_NODE) {
     691      166981 :                         for (i = 0; i < nr_entries; i++) {
     692      143125 :                                 prev->keys[nr_prev + i] = node->keys[i];
     693      143125 :                                 prev->ptrs[nr_prev + i] = node->ptrs[i];
     694             :                         }
     695             :                         return node;
     696             :                 }
     697             :         }
     698             : 
     699     2681262 :         if (*pos + 1 < xfs_iext_node_nr_entries(parent, *pos)) {
     700       63008 :                 struct xfs_iext_node *next = parent->ptrs[*pos + 1];
     701       63008 :                 int nr_next = xfs_iext_node_nr_entries(next, 0), i;
     702             : 
     703       63008 :                 if (nr_entries + nr_next <= KEYS_PER_NODE) {
     704             :                         /*
     705             :                          * Merge the next node into this node so that we don't
     706             :                          * have to do an additional update of the keys in the
     707             :                          * higher levels.
     708             :                          */
     709      174806 :                         for (i = 0; i < nr_next; i++) {
     710      157837 :                                 node->keys[nr_entries + i] = next->keys[i];
     711      157837 :                                 node->ptrs[nr_entries + i] = next->ptrs[i];
     712             :                         }
     713             : 
     714       16969 :                         ++*pos;
     715       16969 :                         return next;
     716             :                 }
     717             :         }
     718             : 
     719             :         return NULL;
     720             : }
     721             : 
     722             : static void
     723     4734161 : xfs_iext_remove_node(
     724             :         struct xfs_ifork        *ifp,
     725             :         xfs_fileoff_t           offset,
     726             :         void                    *victim)
     727             : {
     728     4734161 :         struct xfs_iext_node    *node, *parent;
     729     4734161 :         int                     level = 2, pos, nr_entries, i;
     730             : 
     731     4734161 :         ASSERT(level <= ifp->if_height);
     732     4734161 :         node = xfs_iext_find_level(ifp, offset, level);
     733     9468333 :         pos = xfs_iext_node_pos(node, offset);
     734     4959531 : again:
     735     4959531 :         ASSERT(node->ptrs[pos]);
     736     4959531 :         ASSERT(node->ptrs[pos] == victim);
     737     4959534 :         kmem_free(victim);
     738             : 
     739     4959528 :         nr_entries = xfs_iext_node_nr_entries(node, pos) - 1;
     740     4959530 :         offset = node->keys[0];
     741     7838464 :         for (i = pos; i < nr_entries; i++) {
     742     2878936 :                 node->keys[i] = node->keys[i + 1];
     743     2878936 :                 node->ptrs[i] = node->ptrs[i + 1];
     744             :         }
     745     4959528 :         node->keys[nr_entries] = XFS_IEXT_KEY_INVALID;
     746     4959528 :         node->ptrs[nr_entries] = NULL;
     747             : 
     748     4959536 :         if (pos == 0 && nr_entries > 0) {
     749       72736 :                 xfs_iext_update_node(ifp, offset, node->keys[0], level, node);
     750       72736 :                 offset = node->keys[0];
     751             :         }
     752             : 
     753     4959536 :         if (nr_entries >= KEYS_PER_NODE / 2)
     754     1927834 :                 return;
     755             : 
     756     3031702 :         if (level < ifp->if_height) {
     757             :                 /*
     758             :                  * If we aren't at the root yet try to find a neighbour node to
     759             :                  * merge with (or delete the node if it is empty), and then
     760             :                  * recurse up to the next level.
     761             :                  */
     762     1549021 :                 level++;
     763     1549021 :                 parent = xfs_iext_find_level(ifp, offset, level);
     764     1549021 :                 pos = xfs_iext_node_pos(parent, offset);
     765             : 
     766     1549021 :                 ASSERT(pos != KEYS_PER_NODE);
     767     1549021 :                 ASSERT(parent->ptrs[pos] == node);
     768             : 
     769     1549021 :                 node = xfs_iext_rebalance_node(parent, &pos, node, nr_entries);
     770     1549021 :                 if (node) {
     771      225359 :                         victim = node;
     772      225359 :                         node = parent;
     773      225359 :                         goto again;
     774             :                 }
     775     1482681 :         } else if (nr_entries == 1) {
     776             :                 /*
     777             :                  * If we are at the root and only one entry is left we can just
     778             :                  * free this node and update the root pointer.
     779             :                  */
     780      858924 :                 ASSERT(node == ifp->if_u1.if_root);
     781      858924 :                 ifp->if_u1.if_root = node->ptrs[0];
     782      858924 :                 ifp->if_height--;
     783      858924 :                 kmem_free(node);
     784             :         }
     785             : }
     786             : 
     787             : static void
     788    23403601 : xfs_iext_rebalance_leaf(
     789             :         struct xfs_ifork        *ifp,
     790             :         struct xfs_iext_cursor  *cur,
     791             :         struct xfs_iext_leaf    *leaf,
     792             :         xfs_fileoff_t           offset,
     793             :         int                     nr_entries)
     794             : {
     795             :         /*
     796             :          * If the neighbouring nodes are completely full we might never be able
     797             :          * to merge our node, and will only delete it once the number of
     798             :          * entries hits zero.
     799             :          */
     800    23403601 :         if (nr_entries == 0)
     801     2995306 :                 goto remove_node;
     802             : 
     803    20408295 :         if (leaf->prev) {
     804             :                 int nr_prev = xfs_iext_leaf_nr_entries(ifp, leaf->prev, 0), i;
     805             : 
     806    19978540 :                 if (nr_prev + nr_entries <= RECS_PER_LEAF) {
     807     8649137 :                         for (i = 0; i < nr_entries; i++)
     808     7263530 :                                 leaf->prev->recs[nr_prev + i] = leaf->recs[i];
     809             : 
     810     1385607 :                         if (cur->leaf == leaf) {
     811      436730 :                                 cur->leaf = leaf->prev;
     812      436730 :                                 cur->pos += nr_prev;
     813             :                         }
     814     1385607 :                         goto remove_node;
     815             :                 }
     816             :         }
     817             : 
     818    19022735 :         if (leaf->next) {
     819             :                 int nr_next = xfs_iext_leaf_nr_entries(ifp, leaf->next, 0), i;
     820             : 
     821      760351 :                 if (nr_entries + nr_next <= RECS_PER_LEAF) {
     822             :                         /*
     823             :                          * Merge the next node into this node so that we don't
     824             :                          * have to do an additional update of the keys in the
     825             :                          * higher levels.
     826             :                          */
     827     3293983 :                         for (i = 0; i < nr_next; i++) {
     828     2940727 :                                 leaf->recs[nr_entries + i] =
     829     2940727 :                                         leaf->next->recs[i];
     830             :                         }
     831             : 
     832      353256 :                         if (cur->leaf == leaf->next) {
     833       59105 :                                 cur->leaf = leaf;
     834       59105 :                                 cur->pos += nr_entries;
     835             :                         }
     836             : 
     837      353256 :                         offset = xfs_iext_leaf_key(leaf->next, 0);
     838      353256 :                         leaf = leaf->next;
     839      353256 :                         goto remove_node;
     840             :                 }
     841             :         }
     842             : 
     843             :         return;
     844     4734169 : remove_node:
     845     4734169 :         if (leaf->prev)
     846     4732894 :                 leaf->prev->next = leaf->next;
     847     4734169 :         if (leaf->next)
     848      492731 :                 leaf->next->prev = leaf->prev;
     849     4734169 :         xfs_iext_remove_node(ifp, offset, leaf);
     850             : }
     851             : 
     852             : static void
     853             : xfs_iext_free_last_leaf(
     854             :         struct xfs_ifork        *ifp)
     855             : {
     856    32607002 :         ifp->if_height--;
     857    32607002 :         kmem_free(ifp->if_u1.if_root);
     858    32674715 :         ifp->if_u1.if_root = NULL;
     859    32674715 : }
     860             : 
     861             : void
     862   126018762 : xfs_iext_remove(
     863             :         struct xfs_inode        *ip,
     864             :         struct xfs_iext_cursor  *cur,
     865             :         int                     state)
     866             : {
     867   126018762 :         struct xfs_ifork        *ifp = xfs_iext_state_to_fork(ip, state);
     868   126025935 :         struct xfs_iext_leaf    *leaf = cur->leaf;
     869   126025935 :         xfs_fileoff_t           offset = xfs_iext_leaf_key(leaf, 0);
     870   126025935 :         int                     i, nr_entries;
     871             : 
     872   126025935 :         trace_xfs_iext_remove(ip, cur, state, _RET_IP_);
     873             : 
     874   126023000 :         ASSERT(ifp->if_height > 0);
     875   126023000 :         ASSERT(ifp->if_u1.if_root != NULL);
     876   126023000 :         ASSERT(xfs_iext_valid(ifp, cur));
     877             : 
     878   126006290 :         xfs_iext_inc_seq(ifp);
     879             : 
     880   126006290 :         nr_entries = xfs_iext_leaf_nr_entries(ifp, leaf, cur->pos) - 1;
     881   220145669 :         for (i = cur->pos; i < nr_entries; i++)
     882    94119709 :                 leaf->recs[i] = leaf->recs[i + 1];
     883   126025960 :         xfs_iext_rec_clear(&leaf->recs[nr_entries]);
     884   126001144 :         ifp->if_bytes -= sizeof(struct xfs_iext_rec);
     885             : 
     886   126001144 :         if (cur->pos == 0 && nr_entries > 0) {
     887     3327961 :                 xfs_iext_update_node(ifp, offset, xfs_iext_leaf_key(leaf, 0), 1,
     888             :                                 leaf);
     889     3327960 :                 offset = xfs_iext_leaf_key(leaf, 0);
     890   122673183 :         } else if (cur->pos == nr_entries) {
     891   104514875 :                 if (ifp->if_height > 1 && leaf->next)
     892      773332 :                         cur->leaf = leaf->next;
     893             :                 else
     894   103741543 :                         cur->leaf = NULL;
     895   104514875 :                 cur->pos = 0;
     896             :         }
     897             : 
     898   126001143 :         if (nr_entries >= RECS_PER_LEAF / 2)
     899             :                 return;
     900             : 
     901    74490560 :         if (ifp->if_height > 1)
     902    23403605 :                 xfs_iext_rebalance_leaf(ifp, cur, leaf, offset, nr_entries);
     903    51086955 :         else if (nr_entries == 0)
     904    32607002 :                 xfs_iext_free_last_leaf(ifp);
     905             : }
     906             : 
     907             : /*
     908             :  * Lookup the extent covering bno.
     909             :  *
     910             :  * If there is an extent covering bno return the extent index, and store the
     911             :  * expanded extent structure in *gotp, and the extent cursor in *cur.
     912             :  * If there is no extent covering bno, but there is an extent after it (e.g.
     913             :  * it lies in a hole) return that extent in *gotp and its cursor in *cur
     914             :  * instead.
     915             :  * If bno is beyond the last extent return false, and return an invalid
     916             :  * cursor value.
     917             :  */
     918             : bool
     919  8599762059 : xfs_iext_lookup_extent(
     920             :         struct xfs_inode        *ip,
     921             :         struct xfs_ifork        *ifp,
     922             :         xfs_fileoff_t           offset,
     923             :         struct xfs_iext_cursor  *cur,
     924             :         struct xfs_bmbt_irec    *gotp)
     925             : {
     926  8599762059 :         XFS_STATS_INC(ip->i_mount, xs_look_exlist);
     927             : 
     928  8597731064 :         cur->leaf = xfs_iext_find_level(ifp, offset, 1);
     929  8598438114 :         if (!cur->leaf) {
     930   255107003 :                 cur->pos = 0;
     931   255107003 :                 return false;
     932             :         }
     933             : 
     934 41526080782 :         for (cur->pos = 0; cur->pos < xfs_iext_max_recs(ifp); cur->pos++) {
     935 27244012873 :                 struct xfs_iext_rec *rec = cur_rec(cur);
     936             : 
     937 27240416811 :                 if (xfs_iext_rec_is_empty(rec))
     938             :                         break;
     939 27039453751 :                 if (xfs_iext_rec_cmp(rec, offset) >= 0)
     940  7580706156 :                         goto found;
     941             :         }
     942             : 
     943             :         /* Try looking in the next node for an entry > offset */
     944   759028893 :         if (ifp->if_height == 1 || !cur->leaf->next)
     945             :                 return false;
     946    20216418 :         cur->leaf = cur->leaf->next;
     947    20216418 :         cur->pos = 0;
     948    20216418 :         if (!xfs_iext_valid(ifp, cur))
     949             :                 return false;
     950    20216380 : found:
     951  7600922536 :         xfs_iext_get(gotp, cur_rec(cur));
     952  7611920824 :         return true;
     953             : }
     954             : 
     955             : /*
     956             :  * Returns the last extent before end, and if this extent doesn't cover
     957             :  * end, update end to the end of the extent.
     958             :  */
     959             : bool
     960   149714245 : xfs_iext_lookup_extent_before(
     961             :         struct xfs_inode        *ip,
     962             :         struct xfs_ifork        *ifp,
     963             :         xfs_fileoff_t           *end,
     964             :         struct xfs_iext_cursor  *cur,
     965             :         struct xfs_bmbt_irec    *gotp)
     966             : {
     967             :         /* could be optimized to not even look up the next on a match.. */
     968   149714245 :         if (xfs_iext_lookup_extent(ip, ifp, *end - 1, cur, gotp) &&
     969    85349982 :             gotp->br_startoff <= *end - 1)
     970             :                 return true;
     971    69459537 :         if (!xfs_iext_prev_extent(ifp, cur, gotp))
     972             :                 return false;
     973    69016724 :         *end = gotp->br_startoff + gotp->br_blockcount;
     974    69016724 :         return true;
     975             : }
     976             : 
     977             : void
     978   308882584 : xfs_iext_update_extent(
     979             :         struct xfs_inode        *ip,
     980             :         int                     state,
     981             :         struct xfs_iext_cursor  *cur,
     982             :         struct xfs_bmbt_irec    *new)
     983             : {
     984   308882584 :         struct xfs_ifork        *ifp = xfs_iext_state_to_fork(ip, state);
     985             : 
     986   308874840 :         xfs_iext_inc_seq(ifp);
     987             : 
     988   308874840 :         if (cur->pos == 0) {
     989    61773878 :                 struct xfs_bmbt_irec    old;
     990             : 
     991    61773878 :                 xfs_iext_get(&old, cur_rec(cur));
     992    61773125 :                 if (new->br_startoff != old.br_startoff) {
     993    11250713 :                         xfs_iext_update_node(ifp, old.br_startoff,
     994             :                                         new->br_startoff, 1, cur->leaf);
     995             :                 }
     996             :         }
     997             : 
     998   308874086 :         trace_xfs_bmap_pre_update(ip, cur, state, _RET_IP_);
     999   308864864 :         xfs_iext_set(cur_rec(cur), new);
    1000   308868593 :         trace_xfs_bmap_post_update(ip, cur, state, _RET_IP_);
    1001   308863556 : }
    1002             : 
    1003             : /*
    1004             :  * Return true if the cursor points at an extent and return the extent structure
    1005             :  * in gotp.  Else return false.
    1006             :  */
    1007             : bool
    1008  9084680760 : xfs_iext_get_extent(
    1009             :         struct xfs_ifork        *ifp,
    1010             :         struct xfs_iext_cursor  *cur,
    1011             :         struct xfs_bmbt_irec    *gotp)
    1012             : {
    1013  9084680760 :         if (!xfs_iext_valid(ifp, cur))
    1014             :                 return false;
    1015  7673186715 :         xfs_iext_get(gotp, cur_rec(cur));
    1016  7673239652 :         return true;
    1017             : }
    1018             : 
    1019             : /*
    1020             :  * This is a recursive function, because of that we need to be extremely
    1021             :  * careful with stack usage.
    1022             :  */
    1023             : static void
    1024   214400814 : xfs_iext_destroy_node(
    1025             :         struct xfs_iext_node    *node,
    1026             :         int                     level)
    1027             : {
    1028   214400814 :         int                     i;
    1029             : 
    1030   214400814 :         if (level > 1) {
    1031    94798020 :                 for (i = 0; i < KEYS_PER_NODE; i++) {
    1032    90451510 :                         if (node->keys[i] == XFS_IEXT_KEY_INVALID)
    1033             :                                 break;
    1034    85954231 :                         xfs_iext_destroy_node(node->ptrs[i], level - 1);
    1035             :                 }
    1036             :         }
    1037             : 
    1038   214400915 :         kmem_free(node);
    1039   214412091 : }
    1040             : 
    1041             : void
    1042   128473409 : xfs_iext_destroy(
    1043             :         struct xfs_ifork        *ifp)
    1044             : {
    1045   128473409 :         xfs_iext_destroy_node(ifp->if_u1.if_root, ifp->if_height);
    1046             : 
    1047   128486416 :         ifp->if_bytes = 0;
    1048   128486416 :         ifp->if_height = 0;
    1049   128486416 :         ifp->if_u1.if_root = NULL;
    1050   128486416 : }

Generated by: LCOV version 1.14