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-acha @ Mon Jul 31 20:08:06 PDT 2023 Lines: 439 443 99.1 %
Date: 2023-07-31 20:08:07 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 25899603959 :         return rec->hi == 0;
      44             : }
      45             : 
      46             : static inline void xfs_iext_rec_clear(struct xfs_iext_rec *rec)
      47             : {
      48   101183385 :         rec->lo = 0;
      49   101183385 :         rec->hi = 0;
      50             : }
      51             : 
      52             : static void
      53  1570536814 : xfs_iext_set(
      54             :         struct xfs_iext_rec     *rec,
      55             :         struct xfs_bmbt_irec    *irec)
      56             : {
      57  1570536814 :         ASSERT((irec->br_startoff & ~XFS_IEXT_STARTOFF_MASK) == 0);
      58  1570536814 :         ASSERT((irec->br_blockcount & ~XFS_IEXT_LENGTH_MASK) == 0);
      59  1570536814 :         ASSERT((irec->br_startblock & ~XFS_IEXT_STARTBLOCK_MASK) == 0);
      60             : 
      61  1570536814 :         rec->lo = irec->br_startoff & XFS_IEXT_STARTOFF_MASK;
      62  1570536814 :         rec->hi = irec->br_blockcount & XFS_IEXT_LENGTH_MASK;
      63             : 
      64  1570536814 :         rec->lo |= (irec->br_startblock << 54);
      65  1570536814 :         rec->hi |= ((irec->br_startblock & ~xfs_mask64lo(10)) << (22 - 10));
      66             : 
      67  1570536814 :         if (irec->br_state == XFS_EXT_UNWRITTEN)
      68   148712260 :                 rec->hi |= (1 << 21);
      69  1570536814 : }
      70             : 
      71             : static void
      72  7773878350 : xfs_iext_get(
      73             :         struct xfs_bmbt_irec    *irec,
      74             :         struct xfs_iext_rec     *rec)
      75             : {
      76  7773878350 :         irec->br_startoff = rec->lo & XFS_IEXT_STARTOFF_MASK;
      77  7773878350 :         irec->br_blockcount = rec->hi & XFS_IEXT_LENGTH_MASK;
      78             : 
      79  7773878350 :         irec->br_startblock = rec->lo >> 54;
      80  7773878350 :         irec->br_startblock |= (rec->hi & xfs_mask64hi(42)) >> (22 - 10);
      81             : 
      82  7773878350 :         if (rec->hi & (1 << 21))
      83   538026411 :                 irec->br_state = XFS_EXT_UNWRITTEN;
      84             :         else
      85  7235851939 :                 irec->br_state = XFS_EXT_NORM;
      86  7773878350 : }
      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   370920869 : inline xfs_extnum_t xfs_iext_count(struct xfs_ifork *ifp)
     129             : {
     130 12097685130 :         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  7454338334 :         if (ifp->if_height == 1)
     136 11726764261 :                 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 29931063017 :         return &cur->leaf->recs[cur->pos];
     143             : }
     144             : 
     145  7691258633 : static inline bool xfs_iext_valid(struct xfs_ifork *ifp,
     146             :                 struct xfs_iext_cursor *cur)
     147             : {
     148  7691258633 :         if (!cur->leaf)
     149             :                 return false;
     150 14982735621 :         if (cur->pos < 0 || cur->pos >= xfs_iext_max_recs(ifp))
     151             :                 return false;
     152  6919236166 :         if (xfs_iext_rec_is_empty(cur_rec(cur)))
     153  1099034199 :                 return false;
     154             :         return true;
     155             : }
     156             : 
     157             : static void *
     158   925733226 : xfs_iext_find_first_leaf(
     159             :         struct xfs_ifork        *ifp)
     160             : {
     161   925733226 :         struct xfs_iext_node    *node = ifp->if_u1.if_root;
     162   925733226 :         int                     height;
     163             : 
     164   925733226 :         if (!ifp->if_height)
     165             :                 return NULL;
     166             : 
     167   770818898 :         for (height = ifp->if_height; height > 1; height--) {
     168     3070640 :                 node = node->ptrs[0];
     169     3070640 :                 ASSERT(node);
     170             :         }
     171             : 
     172             :         return node;
     173             : }
     174             : 
     175             : static void *
     176   630184461 : xfs_iext_find_last_leaf(
     177             :         struct xfs_ifork        *ifp)
     178             : {
     179   630184461 :         struct xfs_iext_node    *node = ifp->if_u1.if_root;
     180   630184461 :         int                     height, i;
     181             : 
     182   630184461 :         if (!ifp->if_height)
     183             :                 return NULL;
     184             : 
     185   917617455 :         for (height = ifp->if_height; height > 1; height--) {
     186  2211205800 :                 for (i = 1; i < KEYS_PER_NODE; i++)
     187  2202584873 :                         if (!node->ptrs[i])
     188             :                                 break;
     189   405219374 :                 node = node->ptrs[i - 1];
     190   405219374 :                 ASSERT(node);
     191             :         }
     192             : 
     193             :         return node;
     194             : }
     195             : 
     196             : void
     197   881693862 : xfs_iext_first(
     198             :         struct xfs_ifork        *ifp,
     199             :         struct xfs_iext_cursor  *cur)
     200             : {
     201   925708221 :         cur->pos = 0;
     202   881693862 :         cur->leaf = xfs_iext_find_first_leaf(ifp);
     203   881838967 : }
     204             : 
     205             : void
     206   630130793 : xfs_iext_last(
     207             :         struct xfs_ifork        *ifp,
     208             :         struct xfs_iext_cursor  *cur)
     209             : {
     210   630130793 :         int                     i;
     211             : 
     212   630130793 :         cur->leaf = xfs_iext_find_last_leaf(ifp);
     213   630436315 :         if (!cur->leaf) {
     214   117784440 :                 cur->pos = 0;
     215   117784440 :                 return;
     216             :         }
     217             : 
     218  5298751280 :         for (i = 1; i < xfs_iext_max_recs(ifp); i++) {
     219  3906734150 :                 if (xfs_iext_rec_is_empty(&cur->leaf->recs[i]))
     220             :                         break;
     221             :         }
     222   512651875 :         cur->pos = i - 1;
     223             : }
     224             : 
     225             : void
     226  4191675938 : xfs_iext_next(
     227             :         struct xfs_ifork        *ifp,
     228             :         struct xfs_iext_cursor  *cur)
     229             : {
     230  4191675938 :         if (!cur->leaf) {
     231    44014359 :                 ASSERT(cur->pos <= 0 || cur->pos >= RECS_PER_LEAF);
     232    44014359 :                 xfs_iext_first(ifp, cur);
     233    44015204 :                 return;
     234             :         }
     235             : 
     236  4147661579 :         ASSERT(cur->pos >= 0);
     237  5800741658 :         ASSERT(cur->pos < xfs_iext_max_recs(ifp));
     238             : 
     239  4147661579 :         cur->pos++;
     240  4147661579 :         if (ifp->if_height > 1 && !xfs_iext_valid(ifp, cur) &&
     241  1099220730 :             cur->leaf->next) {
     242   139452727 :                 cur->leaf = cur->leaf->next;
     243   139452727 :                 cur->pos = 0;
     244             :         }
     245             : }
     246             : 
     247             : void
     248   433727353 : xfs_iext_prev(
     249             :         struct xfs_ifork        *ifp,
     250             :         struct xfs_iext_cursor  *cur)
     251             : {
     252   433727353 :         if (!cur->leaf) {
     253   148905876 :                 ASSERT(cur->pos <= 0 || cur->pos >= RECS_PER_LEAF);
     254   148905876 :                 xfs_iext_last(ifp, cur);
     255   148905876 :                 return;
     256             :         }
     257             : 
     258   284821477 :         ASSERT(cur->pos >= 0);
     259   284821477 :         ASSERT(cur->pos <= RECS_PER_LEAF);
     260             : 
     261   284821477 : recurse:
     262   307489024 :         do {
     263   307489024 :                 cur->pos--;
     264   307489024 :                 if (xfs_iext_valid(ifp, cur))
     265             :                         return;
     266    57673185 :         } while (cur->pos > 0);
     267             : 
     268    39539440 :         if (ifp->if_height > 1 && cur->leaf->prev) {
     269     4533802 :                 cur->leaf = cur->leaf->prev;
     270     4533802 :                 cur->pos = RECS_PER_LEAF;
     271     4533802 :                 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    40899656 :         if (node->keys[n] > offset)
     282             :                 return 1;
     283           0 :         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 13548763297 :         uint64_t                rec_offset = rec->lo & XFS_IEXT_STARTOFF_MASK;
     294 13548763297 :         uint32_t                rec_len = rec->hi & XFS_IEXT_LENGTH_MASK;
     295             : 
     296 13548763297 :         if (rec_offset > offset)
     297             :                 return 1;
     298 13179635736 :         if (rec_offset + rec_len <= offset)
     299           0 :                 return -1;
     300             :         return 0;
     301             : }
     302             : 
     303             : static void *
     304  4209069198 : xfs_iext_find_level(
     305             :         struct xfs_ifork        *ifp,
     306             :         xfs_fileoff_t           offset,
     307             :         int                     level)
     308             : {
     309  4209069198 :         struct xfs_iext_node    *node = ifp->if_u1.if_root;
     310  4209069198 :         int                     height, i;
     311             : 
     312  4209069198 :         if (!ifp->if_height)
     313             :                 return NULL;
     314             : 
     315  6431106271 :         for (height = ifp->if_height; height > level; height--) {
     316 11655024488 :                 for (i = 1; i < KEYS_PER_NODE; i++)
     317 11612852917 :                         if (xfs_iext_key_cmp(node, i, offset) > 0)
     318             :                                 break;
     319             : 
     320  2320565618 :                 node = node->ptrs[i - 1];
     321  2320565618 :                 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     4445947 :         int                     i;
     334             : 
     335    34452592 :         for (i = 1; i < KEYS_PER_NODE; i++) {
     336    34219989 :                 if (xfs_iext_key_cmp(node, i, offset) > 0)
     337             :                         break;
     338             :         }
     339             : 
     340     4445947 :         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    74219438 :         int                     i;
     349             : 
     350   687646468 :         for (i = 0; i < KEYS_PER_NODE; i++) {
     351   683214027 :                 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     2330760 :         int                     i;
     364             : 
     365   110065027 :         for (i = start; i < KEYS_PER_NODE; i++) {
     366   103886723 :                 if (node->keys[i] == XFS_IEXT_KEY_INVALID)
     367             :                         break;
     368             :         }
     369             : 
     370    79809610 :         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  1488249292 :         int                     i;
     380             : 
     381  2661459500 :         for (i = start; i < xfs_iext_max_recs(ifp); i++) {
     382  1440638967 :                 if (xfs_iext_rec_is_empty(&leaf->recs[i]))
     383             :                         break;
     384             :         }
     385             : 
     386  1590776983 :         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   162113213 :         return leaf->recs[n].lo & XFS_IEXT_STARTOFF_MASK;
     395             : }
     396             : 
     397             : static void
     398     1376118 : xfs_iext_grow(
     399             :         struct xfs_ifork        *ifp)
     400             : {
     401     1376118 :         struct xfs_iext_node    *node = kmem_zalloc(NODE_SIZE, KM_NOFS);
     402     1376111 :         int                     i;
     403             : 
     404     1376111 :         if (ifp->if_height == 1) {
     405     1295898 :                 struct xfs_iext_leaf *prev = ifp->if_u1.if_root;
     406             : 
     407     1295898 :                 node->keys[0] = xfs_iext_leaf_key(prev, 0);
     408     1295898 :                 node->ptrs[0] = prev;
     409             :         } else  {
     410       80213 :                 struct xfs_iext_node *prev = ifp->if_u1.if_root;
     411             : 
     412       80213 :                 ASSERT(ifp->if_height > 1);
     413             : 
     414       80213 :                 node->keys[0] = prev->keys[0];
     415       80213 :                 node->ptrs[0] = prev;
     416             :         }
     417             : 
     418    22017791 :         for (i = 1; i < KEYS_PER_NODE; i++)
     419    20641680 :                 node->keys[i] = XFS_IEXT_KEY_INVALID;
     420             : 
     421     1376111 :         ifp->if_u1.if_root = node;
     422     1376111 :         ifp->if_height++;
     423     1376111 : }
     424             : 
     425             : static void
     426     6559750 : 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     6559750 :         struct xfs_iext_node    *node = ifp->if_u1.if_root;
     434     6559750 :         int                     height, i;
     435             : 
     436    14503016 :         for (height = ifp->if_height; height > level; height--) {
     437    47688696 :                 for (i = 0; i < KEYS_PER_NODE; i++) {
     438    47526178 :                         if (i > 0 && xfs_iext_key_cmp(node, i, old_offset) > 0)
     439             :                                 break;
     440    39745428 :                         if (node->keys[i] == old_offset)
     441     3529126 :                                 node->keys[i] = new_offset;
     442             :                 }
     443     7943268 :                 node = node->ptrs[i - 1];
     444     7943268 :                 ASSERT(node);
     445             :         }
     446             : 
     447     6559748 :         ASSERT(node == ptr);
     448     6559748 : }
     449             : 
     450             : static struct xfs_iext_node *
     451     4821228 : xfs_iext_split_node(
     452             :         struct xfs_iext_node    **nodep,
     453             :         int                     *pos,
     454             :         int                     *nr_entries)
     455             : {
     456     4821228 :         struct xfs_iext_node    *node = *nodep;
     457     4821228 :         struct xfs_iext_node    *new = kmem_zalloc(NODE_SIZE, KM_NOFS);
     458     4821229 :         const int               nr_move = KEYS_PER_NODE / 2;
     459     4821229 :         int                     nr_keep = nr_move + (KEYS_PER_NODE & 1);
     460     4821229 :         int                     i = 0;
     461             : 
     462             :         /* for sequential append operations just spill over into the new node */
     463     4821229 :         if (*pos == KEYS_PER_NODE) {
     464     4432440 :                 *nodep = new;
     465     4432440 :                 *pos = 0;
     466     4432440 :                 *nr_entries = 0;
     467     4432440 :                 goto done;
     468             :         }
     469             : 
     470             : 
     471     3499093 :         for (i = 0; i < nr_move; i++) {
     472     3110304 :                 new->keys[i] = node->keys[nr_keep + i];
     473     3110304 :                 new->ptrs[i] = node->ptrs[nr_keep + i];
     474             : 
     475     3110304 :                 node->keys[nr_keep + i] = XFS_IEXT_KEY_INVALID;
     476     3110304 :                 node->ptrs[nr_keep + i] = NULL;
     477             :         }
     478             : 
     479      388789 :         if (*pos >= nr_keep) {
     480      208222 :                 *nodep = new;
     481      208222 :                 *pos -= nr_keep;
     482      208222 :                 *nr_entries = nr_move;
     483             :         } else {
     484      180567 :                 *nr_entries = nr_keep;
     485             :         }
     486             : done:
     487    78850581 :         for (; i < KEYS_PER_NODE; i++)
     488    74029352 :                 new->keys[i] = XFS_IEXT_KEY_INVALID;
     489     4821229 :         return new;
     490             : }
     491             : 
     492             : static void
     493    69398176 : xfs_iext_insert_node(
     494             :         struct xfs_ifork        *ifp,
     495             :         uint64_t                offset,
     496             :         void                    *ptr,
     497             :         int                     level)
     498             : {
     499    74219440 :         struct xfs_iext_node    *node, *new;
     500    74219440 :         int                     i, pos, nr_entries;
     501             : 
     502    74219440 : again:
     503    74219440 :         if (ifp->if_height < level)
     504     1376116 :                 xfs_iext_grow(ifp);
     505             : 
     506    74219438 :         new = NULL;
     507    74219438 :         node = xfs_iext_find_level(ifp, offset, level);
     508    74219438 :         pos = xfs_iext_node_insert_pos(node, offset);
     509    74219438 :         nr_entries = xfs_iext_node_nr_entries(node, pos);
     510             : 
     511    75536181 :         ASSERT(pos >= nr_entries || xfs_iext_key_cmp(node, pos, offset) != 0);
     512    74219438 :         ASSERT(nr_entries <= KEYS_PER_NODE);
     513             : 
     514    74219438 :         if (nr_entries == KEYS_PER_NODE)
     515     4821230 :                 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    74219448 :         if (node != new && pos == 0 && nr_entries > 0)
     522           0 :                 xfs_iext_update_node(ifp, node->keys[0], offset, level, node);
     523             : 
     524    79545212 :         for (i = nr_entries; i > pos; i--) {
     525     5325764 :                 node->keys[i] = node->keys[i - 1];
     526     5325764 :                 node->ptrs[i] = node->ptrs[i - 1];
     527             :         }
     528    74219448 :         node->keys[pos] = offset;
     529    74219448 :         node->ptrs[pos] = ptr;
     530             : 
     531    74219448 :         if (new) {
     532     4821264 :                 offset = new->keys[0];
     533     4821264 :                 ptr = new;
     534     4821264 :                 level++;
     535     4821264 :                 goto again;
     536             :         }
     537    69398184 : }
     538             : 
     539             : static struct xfs_iext_leaf *
     540    69398222 : xfs_iext_split_leaf(
     541             :         struct xfs_iext_cursor  *cur,
     542             :         int                     *nr_entries)
     543             : {
     544    69398222 :         struct xfs_iext_leaf    *leaf = cur->leaf;
     545    69398222 :         struct xfs_iext_leaf    *new = kmem_zalloc(NODE_SIZE, KM_NOFS);
     546    69398164 :         const int               nr_move = RECS_PER_LEAF / 2;
     547    69398164 :         int                     nr_keep = nr_move + (RECS_PER_LEAF & 1);
     548    69398164 :         int                     i;
     549             : 
     550             :         /* for sequential append operations just spill over into the new node */
     551    69398164 :         if (cur->pos == RECS_PER_LEAF) {
     552    67256443 :                 cur->leaf = new;
     553    67256443 :                 cur->pos = 0;
     554    67256443 :                 *nr_entries = 0;
     555    67256443 :                 goto done;
     556             :         }
     557             : 
     558    17133724 :         for (i = 0; i < nr_move; i++) {
     559    14992003 :                 new->recs[i] = leaf->recs[nr_keep + i];
     560    14992003 :                 xfs_iext_rec_clear(&leaf->recs[nr_keep + i]);
     561             :         }
     562             : 
     563     2141721 :         if (cur->pos >= nr_keep) {
     564     1492788 :                 cur->leaf = new;
     565     1492788 :                 cur->pos -= nr_keep;
     566     1492788 :                 *nr_entries = nr_move;
     567             :         } else {
     568      648933 :                 *nr_entries = nr_keep;
     569             :         }
     570    69398164 : done:
     571    69398164 :         if (leaf->next)
     572     1010871 :                 leaf->next->prev = new;
     573    69398164 :         new->next = leaf->next;
     574    69398164 :         new->prev = leaf;
     575    69398164 :         leaf->next = new;
     576    69398164 :         return new;
     577             : }
     578             : 
     579             : static void
     580   155114071 : xfs_iext_alloc_root(
     581             :         struct xfs_ifork        *ifp,
     582             :         struct xfs_iext_cursor  *cur)
     583             : {
     584   155114071 :         ASSERT(ifp->if_bytes == 0);
     585             : 
     586   155114071 :         ifp->if_u1.if_root = kmem_zalloc(sizeof(struct xfs_iext_rec), KM_NOFS);
     587   155116129 :         ifp->if_height = 1;
     588             : 
     589             :         /* now that we have a node step into it */
     590   155116129 :         cur->leaf = ifp->if_u1.if_root;
     591   155116129 :         cur->pos = 0;
     592   155116129 : }
     593             : 
     594             : static void
     595   320038947 : xfs_iext_realloc_root(
     596             :         struct xfs_ifork        *ifp,
     597             :         struct xfs_iext_cursor  *cur)
     598             : {
     599   320038947 :         int64_t new_size = ifp->if_bytes + sizeof(struct xfs_iext_rec);
     600   320038947 :         void *new;
     601             : 
     602             :         /* account for the prev/next pointers */
     603   320038947 :         if (new_size / sizeof(struct xfs_iext_rec) == RECS_PER_LEAF)
     604     1544337 :                 new_size = NODE_SIZE;
     605             : 
     606   320038947 :         new = krealloc(ifp->if_u1.if_root, new_size, GFP_NOFS | __GFP_NOFAIL);
     607   320037345 :         memset(new + ifp->if_bytes, 0, new_size - ifp->if_bytes);
     608   320037345 :         ifp->if_u1.if_root = new;
     609   320037345 :         cur->leaf = new;
     610   320037345 : }
     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  1656738108 :         WRITE_ONCE(ifp->if_seq, READ_ONCE(ifp->if_seq) + 1);
     622             : }
     623             : 
     624             : void
     625  1488252446 : xfs_iext_insert_raw(
     626             :         struct xfs_ifork        *ifp,
     627             :         struct xfs_iext_cursor  *cur,
     628             :         struct xfs_bmbt_irec    *irec)
     629             : {
     630  1488252446 :         xfs_fileoff_t           offset = irec->br_startoff;
     631  1488252446 :         struct xfs_iext_leaf    *new = NULL;
     632  1488252446 :         int                     nr_entries, i;
     633             : 
     634  1488252446 :         xfs_iext_inc_seq(ifp);
     635             : 
     636  1488252446 :         if (ifp->if_height == 0)
     637   155111464 :                 xfs_iext_alloc_root(ifp, cur);
     638  1333140982 :         else if (ifp->if_height == 1)
     639   320039423 :                 xfs_iext_realloc_root(ifp, cur);
     640             : 
     641  1488249292 :         nr_entries = xfs_iext_leaf_nr_entries(ifp, cur->leaf, cur->pos);
     642  1488249292 :         ASSERT(nr_entries <= RECS_PER_LEAF);
     643  1488249292 :         ASSERT(cur->pos >= nr_entries ||
     644             :                xfs_iext_rec_cmp(cur_rec(cur), irec->br_startoff) != 0);
     645             : 
     646  1488249292 :         if (nr_entries == RECS_PER_LEAF)
     647    69398214 :                 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  1488249179 :         if (cur->leaf != new && cur->pos == 0 && nr_entries > 0) {
     654     3399473 :                 xfs_iext_update_node(ifp, xfs_iext_leaf_key(cur->leaf, 0),
     655             :                                 offset, 1, cur->leaf);
     656             :         }
     657             : 
     658  1586441479 :         for (i = nr_entries; i > cur->pos; i--)
     659    98192301 :                 cur->leaf->recs[i] = cur->leaf->recs[i - 1];
     660  1488249178 :         xfs_iext_set(cur_rec(cur), irec);
     661  1488246594 :         ifp->if_bytes += sizeof(struct xfs_iext_rec);
     662             : 
     663  1488246594 :         if (new)
     664    69398162 :                 xfs_iext_insert_node(ifp, xfs_iext_leaf_key(new, 0), new, 2);
     665  1488246612 : }
     666             : 
     667             : void
     668  1487997055 : 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  1487997055 :         struct xfs_ifork        *ifp = xfs_iext_state_to_fork(ip, state);
     675             : 
     676  1488001739 :         xfs_iext_insert_raw(ifp, cur, irec);
     677  1487998714 :         trace_xfs_iext_insert(ip, cur, state, _RET_IP_);
     678  1488002331 : }
     679             : 
     680             : static struct xfs_iext_node *
     681     1365776 : 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     1365776 :         if (nr_entries == 0)
     693             :                 return node;
     694             : 
     695     1196363 :         if (*pos > 0) {
     696     1122533 :                 struct xfs_iext_node *prev = parent->ptrs[*pos - 1];
     697     1122533 :                 int nr_prev = xfs_iext_node_nr_entries(prev, 0), i;
     698             : 
     699     1122533 :                 if (nr_prev + nr_entries <= KEYS_PER_NODE) {
     700       36704 :                         for (i = 0; i < nr_entries; i++) {
     701       31610 :                                 prev->keys[nr_prev + i] = node->keys[i];
     702       31610 :                                 prev->ptrs[nr_prev + i] = node->ptrs[i];
     703             :                         }
     704             :                         return node;
     705             :                 }
     706             :         }
     707             : 
     708     2382538 :         if (*pos + 1 < xfs_iext_node_nr_entries(parent, *pos)) {
     709       16958 :                 struct xfs_iext_node *next = parent->ptrs[*pos + 1];
     710       16958 :                 int nr_next = xfs_iext_node_nr_entries(next, 0), i;
     711             : 
     712       16958 :                 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       49666 :                         for (i = 0; i < nr_next; i++) {
     719       44931 :                                 node->keys[nr_entries + i] = next->keys[i];
     720       44931 :                                 node->ptrs[nr_entries + i] = next->ptrs[i];
     721             :                         }
     722             : 
     723        4735 :                         ++*pos;
     724        4735 :                         return next;
     725             :                 }
     726             :         }
     727             : 
     728             :         return NULL;
     729             : }
     730             : 
     731             : static void
     732     3080171 : xfs_iext_remove_node(
     733             :         struct xfs_ifork        *ifp,
     734             :         xfs_fileoff_t           offset,
     735             :         void                    *victim)
     736             : {
     737     3080171 :         struct xfs_iext_node    *node, *parent;
     738     3080171 :         int                     level = 2, pos, nr_entries, i;
     739             : 
     740     3080171 :         ASSERT(level <= ifp->if_height);
     741     3080171 :         node = xfs_iext_find_level(ifp, offset, level);
     742     6160342 :         pos = xfs_iext_node_pos(node, offset);
     743     3259413 : again:
     744     3259413 :         ASSERT(node->ptrs[pos]);
     745     3259413 :         ASSERT(node->ptrs[pos] == victim);
     746     3259413 :         kmem_free(victim);
     747             : 
     748     3259412 :         nr_entries = xfs_iext_node_nr_entries(node, pos) - 1;
     749     3259412 :         offset = node->keys[0];
     750     4048321 :         for (i = pos; i < nr_entries; i++) {
     751      788909 :                 node->keys[i] = node->keys[i + 1];
     752      788909 :                 node->ptrs[i] = node->ptrs[i + 1];
     753             :         }
     754     3259412 :         node->keys[nr_entries] = XFS_IEXT_KEY_INVALID;
     755     3259412 :         node->ptrs[nr_entries] = NULL;
     756             : 
     757     3259412 :         if (pos == 0 && nr_entries > 0) {
     758       20142 :                 xfs_iext_update_node(ifp, offset, node->keys[0], level, node);
     759       20142 :                 offset = node->keys[0];
     760             :         }
     761             : 
     762     3259412 :         if (nr_entries >= KEYS_PER_NODE / 2)
     763     1476648 :                 return;
     764             : 
     765     1782764 :         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     1365776 :                 level++;
     772     1365776 :                 parent = xfs_iext_find_level(ifp, offset, level);
     773     1365776 :                 pos = xfs_iext_node_pos(parent, offset);
     774             : 
     775     1365776 :                 ASSERT(pos != KEYS_PER_NODE);
     776     1365776 :                 ASSERT(parent->ptrs[pos] == node);
     777             : 
     778     1365776 :                 node = xfs_iext_rebalance_node(parent, &pos, node, nr_entries);
     779     1365776 :                 if (node) {
     780      179242 :                         victim = node;
     781      179242 :                         node = parent;
     782      179242 :                         goto again;
     783             :                 }
     784      416988 :         } 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      235419 :                 ASSERT(node == ifp->if_u1.if_root);
     790      235419 :                 ifp->if_u1.if_root = node->ptrs[0];
     791      235419 :                 ifp->if_height--;
     792      235419 :                 kmem_free(node);
     793             :         }
     794             : }
     795             : 
     796             : static void
     797    18876470 : 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    18876470 :         if (nr_entries == 0)
     810     2624751 :                 goto remove_node;
     811             : 
     812    16251719 :         if (leaf->prev) {
     813             :                 int nr_prev = xfs_iext_leaf_nr_entries(ifp, leaf->prev, 0), i;
     814             : 
     815    16158595 :                 if (nr_prev + nr_entries <= RECS_PER_LEAF) {
     816     2407794 :                         for (i = 0; i < nr_entries; i++)
     817     2027246 :                                 leaf->prev->recs[nr_prev + i] = leaf->recs[i];
     818             : 
     819      380548 :                         if (cur->leaf == leaf) {
     820       84421 :                                 cur->leaf = leaf->prev;
     821       84421 :                                 cur->pos += nr_prev;
     822             :                         }
     823      380548 :                         goto remove_node;
     824             :                 }
     825             :         }
     826             : 
     827    15871171 :         if (leaf->next) {
     828             :                 int nr_next = xfs_iext_leaf_nr_entries(ifp, leaf->next, 0), i;
     829             : 
     830      177714 :                 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      709639 :                         for (i = 0; i < nr_next; i++) {
     837      634767 :                                 leaf->recs[nr_entries + i] =
     838             :                                         leaf->next->recs[i];
     839             :                         }
     840             : 
     841       74872 :                         if (cur->leaf == leaf->next) {
     842        9666 :                                 cur->leaf = leaf;
     843        9666 :                                 cur->pos += nr_entries;
     844             :                         }
     845             : 
     846       74872 :                         offset = xfs_iext_leaf_key(leaf->next, 0);
     847       74872 :                         leaf = leaf->next;
     848       74872 :                         goto remove_node;
     849             :                 }
     850             :         }
     851             : 
     852             :         return;
     853     3080171 : remove_node:
     854     3080171 :         if (leaf->prev)
     855     3079916 :                 leaf->prev->next = leaf->next;
     856     3080171 :         if (leaf->next)
     857      125153 :                 leaf->next->prev = leaf->prev;
     858     3080171 :         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    30917229 :         ifp->if_height--;
     866    30917229 :         kmem_free(ifp->if_u1.if_root);
     867    30920754 :         ifp->if_u1.if_root = NULL;
     868    30920754 : }
     869             : 
     870             : void
     871    86192924 : xfs_iext_remove(
     872             :         struct xfs_inode        *ip,
     873             :         struct xfs_iext_cursor  *cur,
     874             :         int                     state)
     875             : {
     876    86192924 :         struct xfs_ifork        *ifp = xfs_iext_state_to_fork(ip, state);
     877    86192499 :         struct xfs_iext_leaf    *leaf = cur->leaf;
     878    86192499 :         xfs_fileoff_t           offset = xfs_iext_leaf_key(leaf, 0);
     879    86192499 :         int                     i, nr_entries;
     880             : 
     881    86192499 :         trace_xfs_iext_remove(ip, cur, state, _RET_IP_);
     882             : 
     883    86191382 :         ASSERT(ifp->if_height > 0);
     884    86191382 :         ASSERT(ifp->if_u1.if_root != NULL);
     885    86191382 :         ASSERT(xfs_iext_valid(ifp, cur));
     886             : 
     887    86191382 :         xfs_iext_inc_seq(ifp);
     888             : 
     889    86191382 :         nr_entries = xfs_iext_leaf_nr_entries(ifp, leaf, cur->pos) - 1;
     890   110417776 :         for (i = cur->pos; i < nr_entries; i++)
     891    24226394 :                 leaf->recs[i] = leaf->recs[i + 1];
     892    86191382 :         xfs_iext_rec_clear(&leaf->recs[nr_entries]);
     893    86191382 :         ifp->if_bytes -= sizeof(struct xfs_iext_rec);
     894             : 
     895    86191382 :         if (cur->pos == 0 && nr_entries > 0) {
     896      876154 :                 xfs_iext_update_node(ifp, offset, xfs_iext_leaf_key(leaf, 0), 1,
     897             :                                 leaf);
     898      876155 :                 offset = xfs_iext_leaf_key(leaf, 0);
     899    85315228 :         } else if (cur->pos == nr_entries) {
     900    80966881 :                 if (ifp->if_height > 1 && leaf->next)
     901      174695 :                         cur->leaf = leaf->next;
     902             :                 else
     903    80792186 :                         cur->leaf = NULL;
     904    80966881 :                 cur->pos = 0;
     905             :         }
     906             : 
     907    86191383 :         if (nr_entries >= RECS_PER_LEAF / 2)
     908             :                 return;
     909             : 
     910    57027854 :         if (ifp->if_height > 1)
     911    18876470 :                 xfs_iext_rebalance_leaf(ifp, cur, leaf, offset, nr_entries);
     912    38151384 :         else if (nr_entries == 0)
     913    30917229 :                 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  4127072905 : 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  4127072905 :         XFS_STATS_INC(ip->i_mount, xs_look_exlist);
     936             : 
     937  4127072905 :         cur->leaf = xfs_iext_find_level(ifp, offset, 1);
     938  4127072905 :         if (!cur->leaf) {
     939    98528839 :                 cur->pos = 0;
     940    98528839 :                 return false;
     941             :         }
     942             : 
     943 19459092479 :         for (cur->pos = 0; cur->pos < xfs_iext_max_recs(ifp); cur->pos++) {
     944 13632994676 :                 struct xfs_iext_rec *rec = cur_rec(cur);
     945             : 
     946 13632994676 :                 if (xfs_iext_rec_is_empty(rec))
     947             :                         break;
     948 13518602062 :                 if (xfs_iext_rec_cmp(rec, offset) >= 0)
     949  3668302468 :                         goto found;
     950             :         }
     951             : 
     952             :         /* Try looking in the next node for an entry > offset */
     953   360241598 :         if (ifp->if_height == 1 || !cur->leaf->next)
     954             :                 return false;
     955     5135572 :         cur->leaf = cur->leaf->next;
     956     5135572 :         cur->pos = 0;
     957     5135572 :         if (!xfs_iext_valid(ifp, cur))
     958             :                 return false;
     959     5135572 : found:
     960  3673438040 :         xfs_iext_get(gotp, cur_rec(cur));
     961  3673438040 :         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    78356775 : 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    78356775 :         if (xfs_iext_lookup_extent(ip, ifp, *end - 1, cur, gotp) &&
     978    34147235 :             gotp->br_startoff <= *end - 1)
     979             :                 return true;
     980    46310864 :         if (!xfs_iext_prev_extent(ifp, cur, gotp))
     981             :                 return false;
     982    45863233 :         *end = gotp->br_startoff + gotp->br_blockcount;
     983    45863233 :         return true;
     984             : }
     985             : 
     986             : void
     987    82292427 : 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    82292427 :         struct xfs_ifork        *ifp = xfs_iext_state_to_fork(ip, state);
     994             : 
     995    82294280 :         xfs_iext_inc_seq(ifp);
     996             : 
     997    82294280 :         if (cur->pos == 0) {
     998    18887484 :                 struct xfs_bmbt_irec    old;
     999             : 
    1000    18887484 :                 xfs_iext_get(&old, cur_rec(cur));
    1001    18887280 :                 if (new->br_startoff != old.br_startoff) {
    1002     2263985 :                         xfs_iext_update_node(ifp, old.br_startoff,
    1003             :                                         new->br_startoff, 1, cur->leaf);
    1004             :                 }
    1005             :         }
    1006             : 
    1007    82294076 :         trace_xfs_bmap_pre_update(ip, cur, state, _RET_IP_);
    1008    82293542 :         xfs_iext_set(cur_rec(cur), new);
    1009    82292438 :         trace_xfs_bmap_post_update(ip, cur, state, _RET_IP_);
    1010    82293110 : }
    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  4798376515 : xfs_iext_get_extent(
    1018             :         struct xfs_ifork        *ifp,
    1019             :         struct xfs_iext_cursor  *cur,
    1020             :         struct xfs_bmbt_irec    *gotp)
    1021             : {
    1022  4798376515 :         if (!xfs_iext_valid(ifp, cur))
    1023             :                 return false;
    1024  4085802696 :         xfs_iext_get(gotp, cur_rec(cur));
    1025  4085802696 :         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   196179097 : xfs_iext_destroy_node(
    1034             :         struct xfs_iext_node    *node,
    1035             :         int                     level)
    1036             : {
    1037   196179097 :         int                     i;
    1038             : 
    1039   196179097 :         if (level > 1) {
    1040    77882431 :                 for (i = 0; i < KEYS_PER_NODE; i++) {
    1041    73985911 :                         if (node->keys[i] == XFS_IEXT_KEY_INVALID)
    1042             :                                 break;
    1043    72099798 :                         xfs_iext_destroy_node(node->ptrs[i], level - 1);
    1044             :                 }
    1045             :         }
    1046             : 
    1047   196179141 :         kmem_free(node);
    1048   196234938 : }
    1049             : 
    1050             : void
    1051   124089356 : xfs_iext_destroy(
    1052             :         struct xfs_ifork        *ifp)
    1053             : {
    1054   124089356 :         xfs_iext_destroy_node(ifp->if_u1.if_root, ifp->if_height);
    1055             : 
    1056   124119971 :         ifp->if_bytes = 0;
    1057   124119971 :         ifp->if_height = 0;
    1058   124119971 :         ifp->if_u1.if_root = NULL;
    1059   124119971 : }

Generated by: LCOV version 1.14