LCOV - code coverage report
Current view: top level - fs/xfs/scrub - xfbtree.c (source / functions) Hit Total Coverage
Test: fstests of 6.5.0-rc4-xfsx @ Mon Jul 31 20:08:34 PDT 2023 Lines: 274 344 79.7 %
Date: 2023-07-31 20:08:34 Functions: 30 32 93.8 %

          Line data    Source code
       1             : /* SPDX-License-Identifier: GPL-2.0 */
       2             : /*
       3             :  * Copyright (C) 2021-2023 Oracle.  All Rights Reserved.
       4             :  * Author: Darrick J. Wong <djwong@kernel.org>
       5             :  */
       6             : #include "xfs.h"
       7             : #include "xfs_fs.h"
       8             : #include "xfs_shared.h"
       9             : #include "xfs_format.h"
      10             : #include "xfs_log_format.h"
      11             : #include "xfs_trans_resv.h"
      12             : #include "xfs_bit.h"
      13             : #include "xfs_mount.h"
      14             : #include "xfs_trans.h"
      15             : #include "xfs_buf_item.h"
      16             : #include "xfs_btree.h"
      17             : #include "xfs_error.h"
      18             : #include "xfs_btree_mem.h"
      19             : #include "xfs_ag.h"
      20             : #include "xfs_rtgroup.h"
      21             : #include "scrub/scrub.h"
      22             : #include "scrub/xfile.h"
      23             : #include "scrub/xfbtree.h"
      24             : #include "scrub/bitmap.h"
      25             : #include "scrub/trace.h"
      26             : 
      27             : /* btree ops functions for in-memory btrees. */
      28             : 
      29             : static xfs_failaddr_t
      30      176553 : xfs_btree_mem_head_verify(
      31             :         struct xfs_buf                  *bp)
      32             : {
      33      176553 :         struct xfs_btree_mem_head       *mhead = bp->b_addr;
      34      176553 :         struct xfs_mount                *mp = bp->b_mount;
      35             : 
      36      176553 :         if (!xfs_verify_magic(bp, mhead->mh_magic))
      37           0 :                 return __this_address;
      38      176053 :         if (be32_to_cpu(mhead->mh_nlevels) == 0)
      39           0 :                 return __this_address;
      40      176053 :         if (!uuid_equal(&mhead->mh_uuid, &mp->m_sb.sb_meta_uuid))
      41           0 :                 return __this_address;
      42             : 
      43             :         return NULL;
      44             : }
      45             : 
      46             : static void
      47           0 : xfs_btree_mem_head_read_verify(
      48             :         struct xfs_buf          *bp)
      49             : {
      50           0 :         xfs_failaddr_t          fa = xfs_btree_mem_head_verify(bp);
      51             : 
      52           0 :         if (fa)
      53           0 :                 xfs_verifier_error(bp, -EFSCORRUPTED, fa);
      54           0 : }
      55             : 
      56             : static void
      57      163543 : xfs_btree_mem_head_write_verify(
      58             :         struct xfs_buf          *bp)
      59             : {
      60      163543 :         xfs_failaddr_t          fa = xfs_btree_mem_head_verify(bp);
      61             : 
      62      163507 :         if (fa)
      63           0 :                 xfs_verifier_error(bp, -EFSCORRUPTED, fa);
      64      163507 : }
      65             : 
      66             : static const struct xfs_buf_ops xfs_btree_mem_head_buf_ops = {
      67             :         .name                   = "xfs_btree_mem_head",
      68             :         .magic                  = { cpu_to_be32(XFS_BTREE_MEM_HEAD_MAGIC),
      69             :                                     cpu_to_be32(XFS_BTREE_MEM_HEAD_MAGIC) },
      70             :         .verify_read            = xfs_btree_mem_head_read_verify,
      71             :         .verify_write           = xfs_btree_mem_head_write_verify,
      72             :         .verify_struct          = xfs_btree_mem_head_verify,
      73             : };
      74             : 
      75             : /* Initialize the header block for an in-memory btree. */
      76             : static inline void
      77      163865 : xfs_btree_mem_head_init(
      78             :         struct xfs_buf                  *head_bp,
      79             :         unsigned long long              owner,
      80             :         xfileoff_t                      leaf_xfoff)
      81             : {
      82      163865 :         struct xfs_btree_mem_head       *mhead = head_bp->b_addr;
      83      163865 :         struct xfs_mount                *mp = head_bp->b_mount;
      84             : 
      85      163865 :         mhead->mh_magic = cpu_to_be32(XFS_BTREE_MEM_HEAD_MAGIC);
      86      163865 :         mhead->mh_nlevels = cpu_to_be32(1);
      87      163865 :         mhead->mh_owner = cpu_to_be64(owner);
      88      163865 :         mhead->mh_root = cpu_to_be64(leaf_xfoff);
      89      163865 :         uuid_copy(&mhead->mh_uuid, &mp->m_sb.sb_meta_uuid);
      90             : 
      91      163712 :         head_bp->b_ops = &xfs_btree_mem_head_buf_ops;
      92      163712 : }
      93             : 
      94             : /* Return tree height from the in-memory btree head. */
      95             : unsigned int
      96  1051183807 : xfs_btree_mem_head_nlevels(
      97             :         struct xfs_buf                  *head_bp)
      98             : {
      99  1051183807 :         struct xfs_btree_mem_head       *mhead = head_bp->b_addr;
     100             : 
     101  1051183807 :         return be32_to_cpu(mhead->mh_nlevels);
     102             : }
     103             : 
     104             : /* Extract the buftarg target for this xfile btree. */
     105             : struct xfs_buftarg *
     106  1591739501 : xfbtree_target(struct xfbtree *xfbtree)
     107             : {
     108  8822933620 :         return xfbtree->target;
     109             : }
     110             : 
     111             : /* Is this daddr (sector offset) contained within the buffer target? */
     112             : static inline bool
     113             : xfbtree_verify_buftarg_xfileoff(
     114             :         struct xfs_buftarg      *btp,
     115             :         xfileoff_t              xfoff)
     116             : {
     117  7662763422 :         xfs_daddr_t             xfoff_daddr = xfo_to_daddr(xfoff);
     118             : 
     119  7662763422 :         return xfs_buftarg_verify_daddr(btp, xfoff_daddr);
     120             : }
     121             : 
     122             : /* Is this btree xfile offset contained within the xfile? */
     123             : bool
     124  3210981706 : xfbtree_verify_xfileoff(
     125             :         struct xfs_btree_cur    *cur,
     126             :         unsigned long long      xfoff)
     127             : {
     128  7231194119 :         struct xfs_buftarg      *btp = xfbtree_target(cur->bc_mem.xfbtree);
     129             : 
     130  3210981706 :         return xfbtree_verify_buftarg_xfileoff(btp, xfoff);
     131             : }
     132             : 
     133             : /* Check if a btree pointer is reasonable. */
     134             : int
     135  4020212413 : xfbtree_check_ptr(
     136             :         struct xfs_btree_cur            *cur,
     137             :         const union xfs_btree_ptr       *ptr,
     138             :         int                             index,
     139             :         int                             level)
     140             : {
     141  4020212413 :         xfileoff_t                      bt_xfoff;
     142  4020212413 :         xfs_failaddr_t                  fa = NULL;
     143             : 
     144  4020212413 :         ASSERT(cur->bc_flags & XFS_BTREE_IN_XFILE);
     145             : 
     146  4020212413 :         if (cur->bc_flags & XFS_BTREE_LONG_PTRS)
     147  2826502497 :                 bt_xfoff = be64_to_cpu(ptr->l);
     148             :         else
     149  1193709916 :                 bt_xfoff = be32_to_cpu(ptr->s);
     150             : 
     151  4020212413 :         if (!xfbtree_verify_xfileoff(cur, bt_xfoff)) {
     152           0 :                 fa = __this_address;
     153           0 :                 goto done;
     154             :         }
     155             : 
     156             :         /* Can't point to the head or anything before it */
     157  4020587703 :         if (bt_xfoff < XFBTREE_INIT_LEAF_BLOCK) {
     158           0 :                 fa = __this_address;
     159           0 :                 goto done;
     160             :         }
     161             : 
     162  4020587703 : done:
     163           0 :         if (fa) {
     164           0 :                 xfs_err(cur->bc_mp,
     165             : "In-memory: Corrupt btree %d flags 0x%x pointer at level %d index %d fa %pS.",
     166             :                                 cur->bc_btnum, cur->bc_flags, level, index,
     167             :                                 fa);
     168           0 :                 return -EFSCORRUPTED;
     169             :         }
     170             :         return 0;
     171             : }
     172             : 
     173             : /* Convert a btree pointer to a daddr */
     174             : xfs_daddr_t
     175  3442071068 : xfbtree_ptr_to_daddr(
     176             :         struct xfs_btree_cur            *cur,
     177             :         const union xfs_btree_ptr       *ptr)
     178             : {
     179  3442071068 :         xfileoff_t                      bt_xfoff;
     180             : 
     181  3442071068 :         if (cur->bc_flags & XFS_BTREE_LONG_PTRS)
     182  2556968715 :                 bt_xfoff = be64_to_cpu(ptr->l);
     183             :         else
     184   885102353 :                 bt_xfoff = be32_to_cpu(ptr->s);
     185  3442071068 :         return xfo_to_daddr(bt_xfoff);
     186             : }
     187             : 
     188             : /* Set the pointer to point to this buffer. */
     189             : void
     190      941270 : xfbtree_buf_to_ptr(
     191             :         struct xfs_btree_cur    *cur,
     192             :         struct xfs_buf          *bp,
     193             :         union xfs_btree_ptr     *ptr)
     194             : {
     195      941270 :         xfileoff_t              xfoff = xfs_daddr_to_xfo(xfs_buf_daddr(bp));
     196             : 
     197      941270 :         if (cur->bc_flags & XFS_BTREE_LONG_PTRS)
     198      373724 :                 ptr->l = cpu_to_be64(xfoff);
     199             :         else
     200      567546 :                 ptr->s = cpu_to_be32(xfoff);
     201      941270 : }
     202             : 
     203             : /* Return the in-memory btree block size, in units of 512 bytes. */
     204  1591824111 : unsigned int xfbtree_bbsize(void)
     205             : {
     206  1591824111 :         return xfo_to_daddr(1);
     207             : }
     208             : 
     209             : /* Set the root of an in-memory btree. */
     210             : void
     211       12738 : xfbtree_set_root(
     212             :         struct xfs_btree_cur            *cur,
     213             :         const union xfs_btree_ptr       *ptr,
     214             :         int                             inc)
     215             : {
     216       12738 :         struct xfs_buf                  *head_bp = cur->bc_mem.head_bp;
     217       12738 :         struct xfs_btree_mem_head       *mhead = head_bp->b_addr;
     218             : 
     219       12738 :         ASSERT(cur->bc_flags & XFS_BTREE_IN_XFILE);
     220             : 
     221       12738 :         if (cur->bc_flags & XFS_BTREE_LONG_PTRS) {
     222        2375 :                 mhead->mh_root = ptr->l;
     223             :         } else {
     224       10363 :                 uint32_t                root = be32_to_cpu(ptr->s);
     225             : 
     226       10363 :                 mhead->mh_root = cpu_to_be64(root);
     227             :         }
     228       12738 :         be32_add_cpu(&mhead->mh_nlevels, inc);
     229       12738 :         xfs_trans_log_buf(cur->bc_tp, head_bp, 0, sizeof(*mhead) - 1);
     230       12738 : }
     231             : 
     232             : /* Initialize a pointer from the in-memory btree header. */
     233             : void
     234  1333176220 : xfbtree_init_ptr_from_cur(
     235             :         struct xfs_btree_cur            *cur,
     236             :         union xfs_btree_ptr             *ptr)
     237             : {
     238  1333176220 :         struct xfs_buf                  *head_bp = cur->bc_mem.head_bp;
     239  1333176220 :         struct xfs_btree_mem_head       *mhead = head_bp->b_addr;
     240             : 
     241  1333176220 :         ASSERT(cur->bc_flags & XFS_BTREE_IN_XFILE);
     242             : 
     243  1333176220 :         if (cur->bc_flags & XFS_BTREE_LONG_PTRS) {
     244  1094886687 :                 ptr->l = mhead->mh_root;
     245             :         } else {
     246   238289533 :                 uint64_t                root = be64_to_cpu(mhead->mh_root);
     247             : 
     248   238289533 :                 ptr->s = cpu_to_be32(root);
     249             :         }
     250  1333176220 : }
     251             : 
     252             : /* Duplicate an in-memory btree cursor. */
     253             : struct xfs_btree_cur *
     254    60200080 : xfbtree_dup_cursor(
     255             :         struct xfs_btree_cur            *cur)
     256             : {
     257    60200080 :         struct xfs_btree_cur            *ncur;
     258             : 
     259    60200080 :         ASSERT(cur->bc_flags & XFS_BTREE_IN_XFILE);
     260             : 
     261    60200080 :         ncur = xfs_btree_alloc_cursor(cur->bc_mp, cur->bc_tp, cur->bc_btnum,
     262    60200080 :                         cur->bc_ops, cur->bc_maxlevels, cur->bc_cache);
     263    60200768 :         ncur->bc_flags = cur->bc_flags;
     264    60200768 :         ncur->bc_nlevels = cur->bc_nlevels;
     265    60200768 :         ncur->bc_statoff = cur->bc_statoff;
     266             : 
     267   120401536 :         memcpy(&ncur->bc_mem, &cur->bc_mem, sizeof(cur->bc_mem));
     268             : 
     269    60200768 :         if (cur->bc_mem.pag)
     270    35579451 :                 ncur->bc_mem.pag = xfs_perag_hold(cur->bc_mem.pag);
     271    60201027 :         if (cur->bc_mem.rtg)
     272    24618644 :                 ncur->bc_mem.rtg = xfs_rtgroup_hold(cur->bc_mem.rtg);
     273             : 
     274    60202238 :         return ncur;
     275             : }
     276             : 
     277             : /* Check the owner of an in-memory btree block. */
     278             : xfs_failaddr_t
     279  1294395262 : xfbtree_check_block_owner(
     280             :         struct xfs_btree_cur    *cur,
     281             :         struct xfs_btree_block  *block)
     282             : {
     283  1294395262 :         struct xfbtree          *xfbt = cur->bc_mem.xfbtree;
     284             : 
     285  1294395262 :         if (cur->bc_flags & XFS_BTREE_LONG_PTRS) {
     286  1091425633 :                 if (be64_to_cpu(block->bb_u.l.bb_owner) != xfbt->owner)
     287           0 :                         return __this_address;
     288             : 
     289             :                 return NULL;
     290             :         }
     291             : 
     292   202969629 :         if (be32_to_cpu(block->bb_u.s.bb_owner) != xfbt->owner)
     293           0 :                 return __this_address;
     294             : 
     295             :         return NULL;
     296             : }
     297             : 
     298             : /* Return the owner of this in-memory btree. */
     299             : unsigned long long
     300      941257 : xfbtree_owner(
     301             :         struct xfs_btree_cur    *cur)
     302             : {
     303      941257 :         return cur->bc_mem.xfbtree->owner;
     304             : }
     305             : 
     306             : /* Return the xfile offset (in blocks) of a btree buffer. */
     307             : unsigned long long
     308  4498362509 : xfbtree_buf_to_xfoff(
     309             :         struct xfs_btree_cur    *cur,
     310             :         struct xfs_buf          *bp)
     311             : {
     312  4498362509 :         ASSERT(cur->bc_flags & XFS_BTREE_IN_XFILE);
     313             : 
     314  4498362509 :         return xfs_daddr_to_xfo(xfs_buf_daddr(bp));
     315             : }
     316             : 
     317             : /* Verify a long-format btree block. */
     318             : xfs_failaddr_t
     319   747913340 : xfbtree_lblock_verify(
     320             :         struct xfs_buf          *bp,
     321             :         unsigned int            max_recs)
     322             : {
     323   747913340 :         struct xfs_btree_block  *block = XFS_BUF_TO_BLOCK(bp);
     324   747913340 :         struct xfs_buftarg      *btp = bp->b_target;
     325             : 
     326             :         /* numrecs verification */
     327   747913340 :         if (be16_to_cpu(block->bb_numrecs) > max_recs)
     328           0 :                 return __this_address;
     329             : 
     330             :         /* sibling pointer verification */
     331   847322460 :         if (block->bb_u.l.bb_leftsib != cpu_to_be64(NULLFSBLOCK) &&
     332             :             !xfbtree_verify_buftarg_xfileoff(btp,
     333    99407095 :                                 be64_to_cpu(block->bb_u.l.bb_leftsib)))
     334           0 :                 return __this_address;
     335             : 
     336   834772485 :         if (block->bb_u.l.bb_rightsib != cpu_to_be64(NULLFSBLOCK) &&
     337             :             !xfbtree_verify_buftarg_xfileoff(btp,
     338    86856380 :                                 be64_to_cpu(block->bb_u.l.bb_rightsib)))
     339           0 :                 return __this_address;
     340             : 
     341             :         return NULL;
     342             : }
     343             : 
     344             : /* Verify a short-format btree block. */
     345             : xfs_failaddr_t
     346   152433498 : xfbtree_sblock_verify(
     347             :         struct xfs_buf          *bp,
     348             :         unsigned int            max_recs)
     349             : {
     350   152433498 :         struct xfs_btree_block  *block = XFS_BUF_TO_BLOCK(bp);
     351   152433498 :         struct xfs_buftarg      *btp = bp->b_target;
     352             : 
     353             :         /* numrecs verification */
     354   152433498 :         if (be16_to_cpu(block->bb_numrecs) > max_recs)
     355           0 :                 return __this_address;
     356             : 
     357             :         /* sibling pointer verification */
     358   279327667 :         if (block->bb_u.s.bb_leftsib != cpu_to_be32(NULLAGBLOCK) &&
     359   126894206 :             !xfbtree_verify_buftarg_xfileoff(btp,
     360   126894206 :                                 be32_to_cpu(block->bb_u.s.bb_leftsib)))
     361           0 :                 return __this_address;
     362             : 
     363   270845216 :         if (block->bb_u.s.bb_rightsib != cpu_to_be32(NULLAGBLOCK) &&
     364   118411622 :             !xfbtree_verify_buftarg_xfileoff(btp,
     365   118411622 :                                 be32_to_cpu(block->bb_u.s.bb_rightsib)))
     366           0 :                 return __this_address;
     367             : 
     368             :         return NULL;
     369             : }
     370             : 
     371             : /* Close the btree xfile and release all resources. */
     372             : void
     373      163236 : xfbtree_destroy(
     374             :         struct xfbtree          *xfbt)
     375             : {
     376      163236 :         xbitmap_destroy(xfbt->freespace);
     377      163441 :         kfree(xfbt->freespace);
     378      163637 :         xfs_buftarg_drain(xfbt->target);
     379      163733 :         kfree(xfbt);
     380      163633 : }
     381             : 
     382             : /* Compute the number of bytes available for records. */
     383             : static inline unsigned int
     384      163893 : xfbtree_rec_bytes(
     385             :         struct xfs_mount                *mp,
     386             :         const struct xfbtree_config     *cfg)
     387             : {
     388      163893 :         unsigned int                    blocklen = xfo_to_b(1);
     389             : 
     390      163893 :         if (cfg->btree_ops->geom_flags & XFS_BTREE_LONG_PTRS) {
     391      131578 :                 if (xfs_has_crc(mp))
     392             :                         return blocklen - XFS_BTREE_LBLOCK_CRC_LEN;
     393             : 
     394           0 :                 return blocklen - XFS_BTREE_LBLOCK_LEN;
     395             :         }
     396             : 
     397       32315 :         if (xfs_has_crc(mp))
     398       32312 :                 return blocklen - XFS_BTREE_SBLOCK_CRC_LEN;
     399             : 
     400             :         return blocklen - XFS_BTREE_SBLOCK_LEN;
     401             : }
     402             : 
     403             : /* Initialize an empty leaf block as the btree root. */
     404             : STATIC int
     405      163889 : xfbtree_init_leaf_block(
     406             :         struct xfs_mount                *mp,
     407             :         struct xfbtree                  *xfbt,
     408             :         const struct xfbtree_config     *cfg)
     409             : {
     410      163889 :         struct xfs_buf                  *bp;
     411      163889 :         xfs_daddr_t                     daddr;
     412      163889 :         int                             error;
     413             : 
     414      163889 :         daddr = xfo_to_daddr(XFBTREE_INIT_LEAF_BLOCK);
     415      163889 :         error = xfs_buf_get(xfbt->target, daddr, xfbtree_bbsize(), &bp);
     416      163655 :         if (error)
     417             :                 return error;
     418             : 
     419      163650 :         trace_xfbtree_create_root_buf(xfbt, bp);
     420             : 
     421      163635 :         xfs_btree_init_buf(mp, bp, cfg->btree_ops, 0, 0, cfg->owner);
     422      163467 :         error = xfs_bwrite(bp);
     423      163750 :         xfs_buf_relse(bp);
     424      163686 :         if (error)
     425             :                 return error;
     426             : 
     427      163686 :         xfbt->xf_used++;
     428      163686 :         return 0;
     429             : }
     430             : 
     431             : /* Initialize the in-memory btree header block. */
     432             : STATIC int
     433      163622 : xfbtree_init_head(
     434             :         struct xfbtree          *xfbt)
     435             : {
     436      163622 :         struct xfs_buf          *bp;
     437      163622 :         xfs_daddr_t             daddr;
     438      163622 :         int                     error;
     439             : 
     440      163622 :         daddr = xfo_to_daddr(XFBTREE_HEAD_BLOCK);
     441      163622 :         error = xfs_buf_get(xfbt->target, daddr, xfbtree_bbsize(), &bp);
     442      163912 :         if (error)
     443             :                 return error;
     444             : 
     445      163917 :         xfs_btree_mem_head_init(bp, xfbt->owner, XFBTREE_INIT_LEAF_BLOCK);
     446      163724 :         error = xfs_bwrite(bp);
     447      163824 :         xfs_buf_relse(bp);
     448      163868 :         if (error)
     449             :                 return error;
     450             : 
     451      163868 :         xfbt->xf_used++;
     452      163868 :         return 0;
     453             : }
     454             : 
     455             : /* Create an xfile btree backing thing that can be used for in-memory btrees. */
     456             : int
     457      163857 : xfbtree_create(
     458             :         struct xfs_mount                *mp,
     459             :         const struct xfbtree_config     *cfg,
     460             :         struct xfbtree                  **xfbtreep)
     461             : {
     462      163857 :         struct xfbtree                  *xfbt;
     463      163857 :         unsigned int                    blocklen = xfbtree_rec_bytes(mp, cfg);
     464      163857 :         unsigned int                    keyptr_len = cfg->btree_ops->key_len;
     465      163857 :         int                             error;
     466             : 
     467             :         /* Requires an xfile-backed buftarg. */
     468      163857 :         if (!(cfg->target->bt_flags & XFS_BUFTARG_XFILE)) {
     469           0 :                 ASSERT(cfg->target->bt_flags & XFS_BUFTARG_XFILE);
     470           0 :                 return -EINVAL;
     471             :         }
     472             : 
     473      163857 :         xfbt = kzalloc(sizeof(struct xfbtree), XCHK_GFP_FLAGS);
     474      163829 :         if (!xfbt)
     475             :                 return -ENOMEM;
     476             : 
     477             :         /* Assign our memory file and the free space bitmap. */
     478      163829 :         xfbt->target = cfg->target;
     479      163829 :         if (cfg->flags & XFBTREE_DIRECT_MAP)
     480      163882 :                 xfbt->target->bt_flags |= XFS_BUFTARG_DIRECT_MAP;
     481             : 
     482      163829 :         xfbt->freespace = kmalloc(sizeof(struct xbitmap), XCHK_GFP_FLAGS);
     483      163950 :         if (!xfbt->freespace) {
     484           0 :                 error = -ENOMEM;
     485           0 :                 goto err_buftarg;
     486             :         }
     487      163950 :         xbitmap_init(xfbt->freespace);
     488             : 
     489             :         /* Set up min/maxrecs for this btree. */
     490      163934 :         if (cfg->btree_ops->geom_flags & XFS_BTREE_LONG_PTRS)
     491      131598 :                 keyptr_len += sizeof(__be64);
     492             :         else
     493       32336 :                 keyptr_len += sizeof(__be32);
     494      163934 :         xfbt->maxrecs[0] = blocklen / cfg->btree_ops->rec_len;
     495      163934 :         xfbt->maxrecs[1] = blocklen / keyptr_len;
     496      163934 :         xfbt->minrecs[0] = xfbt->maxrecs[0] / 2;
     497      163934 :         xfbt->minrecs[1] = xfbt->maxrecs[1] / 2;
     498      163934 :         xfbt->owner = cfg->owner;
     499             : 
     500             :         /* Initialize the empty btree. */
     501      163934 :         error = xfbtree_init_leaf_block(mp, xfbt, cfg);
     502      163545 :         if (error)
     503           0 :                 goto err_freesp;
     504             : 
     505      163545 :         error = xfbtree_init_head(xfbt);
     506      163871 :         if (error)
     507           0 :                 goto err_freesp;
     508             : 
     509      163871 :         trace_xfbtree_create(mp, cfg, xfbt);
     510             : 
     511      163792 :         *xfbtreep = xfbt;
     512      163792 :         return 0;
     513             : 
     514           0 : err_freesp:
     515           0 :         xbitmap_destroy(xfbt->freespace);
     516           0 :         kfree(xfbt->freespace);
     517           0 : err_buftarg:
     518           0 :         xfs_buftarg_drain(xfbt->target);
     519           0 :         kfree(xfbt);
     520           0 :         return error;
     521             : }
     522             : 
     523             : /* Read the in-memory btree head. */
     524             : int
     525  1051169219 : xfbtree_head_read_buf(
     526             :         struct xfbtree          *xfbt,
     527             :         struct xfs_trans        *tp,
     528             :         struct xfs_buf          **bpp)
     529             : {
     530  1051169219 :         struct xfs_buftarg      *btp = xfbt->target;
     531  1051169219 :         struct xfs_mount        *mp = btp->bt_mount;
     532  1051169219 :         struct xfs_btree_mem_head *mhead;
     533  1051169219 :         struct xfs_buf          *bp;
     534  1051169219 :         xfs_daddr_t             daddr;
     535  1051169219 :         int                     error;
     536             : 
     537  1051169219 :         daddr = xfo_to_daddr(XFBTREE_HEAD_BLOCK);
     538  1051169219 :         error = xfs_trans_read_buf(mp, tp, btp, daddr, xfbtree_bbsize(), 0,
     539             :                         &bp, &xfs_btree_mem_head_buf_ops);
     540  1051151603 :         if (error)
     541             :                 return error;
     542             : 
     543  1051151603 :         mhead = bp->b_addr;
     544  1051151603 :         if (be64_to_cpu(mhead->mh_owner) != xfbt->owner) {
     545           0 :                 xfs_verifier_error(bp, -EFSCORRUPTED, __this_address);
     546           0 :                 xfs_trans_brelse(tp, bp);
     547           0 :                 return -EFSCORRUPTED;
     548             :         }
     549             : 
     550  1051151603 :         *bpp = bp;
     551  1051151603 :         return 0;
     552             : }
     553             : 
     554             : static inline struct xfile *xfbtree_xfile(struct xfbtree *xfbt)
     555             : {
     556      941270 :         return xfbt->target->bt_xfile;
     557             : }
     558             : 
     559             : /* Allocate a block to our in-memory btree. */
     560             : int
     561      941268 : xfbtree_alloc_block(
     562             :         struct xfs_btree_cur            *cur,
     563             :         const union xfs_btree_ptr       *start,
     564             :         union xfs_btree_ptr             *new,
     565             :         int                             *stat)
     566             : {
     567      941268 :         struct xfbtree                  *xfbt = cur->bc_mem.xfbtree;
     568      941268 :         xfileoff_t                      bt_xfoff;
     569      941268 :         loff_t                          pos;
     570      941268 :         int                             error;
     571             : 
     572      941268 :         ASSERT(cur->bc_flags & XFS_BTREE_IN_XFILE);
     573             : 
     574             :         /*
     575             :          * Find the first free block in the free space bitmap and take it.  If
     576             :          * none are found, seek to end of the file.
     577             :          */
     578      941268 :         error = xbitmap_take_first_set(xfbt->freespace, 0, -1ULL, &bt_xfoff);
     579      941268 :         if (error == -ENODATA) {
     580      941258 :                 bt_xfoff = xfbt->xf_used;
     581      941258 :                 xfbt->xf_used++;
     582          10 :         } else if (error) {
     583             :                 return error;
     584             :         }
     585             : 
     586      941268 :         trace_xfbtree_alloc_block(xfbt, cur, bt_xfoff);
     587             : 
     588             :         /* Fail if the block address exceeds the maximum for short pointers. */
     589      941270 :         if (!(cur->bc_flags & XFS_BTREE_LONG_PTRS) && bt_xfoff >= INT_MAX) {
     590           0 :                 *stat = 0;
     591           0 :                 return 0;
     592             :         }
     593             : 
     594             :         /* Make sure we actually can write to the block before we return it. */
     595      941270 :         pos = xfo_to_b(bt_xfoff);
     596      941270 :         error = xfile_prealloc(xfbtree_xfile(xfbt), pos, xfo_to_b(1));
     597      941263 :         if (error)
     598             :                 return error;
     599             : 
     600      941263 :         if (cur->bc_flags & XFS_BTREE_LONG_PTRS)
     601      373717 :                 new->l = cpu_to_be64(bt_xfoff);
     602             :         else
     603      567546 :                 new->s = cpu_to_be32(bt_xfoff);
     604             : 
     605      941263 :         *stat = 1;
     606      941263 :         return 0;
     607             : }
     608             : 
     609             : /* Free a block from our in-memory btree. */
     610             : int
     611          41 : xfbtree_free_block(
     612             :         struct xfs_btree_cur    *cur,
     613             :         struct xfs_buf          *bp)
     614             : {
     615          41 :         struct xfbtree          *xfbt = cur->bc_mem.xfbtree;
     616          41 :         xfileoff_t              bt_xfoff, bt_xflen;
     617             : 
     618          41 :         ASSERT(cur->bc_flags & XFS_BTREE_IN_XFILE);
     619             : 
     620          41 :         bt_xfoff = xfs_daddr_to_xfot(xfs_buf_daddr(bp));
     621          41 :         bt_xflen = xfs_daddr_to_xfot(bp->b_length);
     622             : 
     623          41 :         trace_xfbtree_free_block(xfbt, cur, bt_xfoff);
     624             : 
     625          41 :         return xbitmap_set(xfbt->freespace, bt_xfoff, bt_xflen);
     626             : }
     627             : 
     628             : /* Return the minimum number of records for a btree block. */
     629             : int
     630      189004 : xfbtree_get_minrecs(
     631             :         struct xfs_btree_cur    *cur,
     632             :         int                     level)
     633             : {
     634      189004 :         struct xfbtree          *xfbt = cur->bc_mem.xfbtree;
     635             : 
     636      189004 :         return xfbt->minrecs[level != 0];
     637             : }
     638             : 
     639             : /* Return the maximum number of records for a btree block. */
     640             : int
     641  8769933297 : xfbtree_get_maxrecs(
     642             :         struct xfs_btree_cur    *cur,
     643             :         int                     level)
     644             : {
     645  8769933297 :         struct xfbtree          *xfbt = cur->bc_mem.xfbtree;
     646             : 
     647  8769933297 :         return xfbt->maxrecs[level != 0];
     648             : }
     649             : 
     650             : /* If this log item is a buffer item that came from the xfbtree, return it. */
     651             : static inline struct xfs_buf *
     652             : xfbtree_buf_match(
     653             :         struct xfbtree                  *xfbt,
     654             :         const struct xfs_log_item       *lip)
     655             : {
     656  4412290655 :         const struct xfs_buf_log_item   *bli;
     657  4412290655 :         struct xfs_buf                  *bp;
     658             : 
     659  4412290655 :         if (lip->li_type != XFS_LI_BUF)
     660             :                 return NULL;
     661             : 
     662  4412291052 :         bli = container_of(lip, struct xfs_buf_log_item, bli_item);
     663  4412291052 :         bp = bli->bli_buf;
     664  4412291052 :         if (bp->b_target != xfbt->target)
     665             :                 return NULL;
     666             : 
     667             :         return bp;
     668             : }
     669             : 
     670             : /*
     671             :  * Detach this (probably dirty) xfbtree buffer from the transaction by any
     672             :  * means necessary.  Returns true if the buffer needs to be written.
     673             :  */
     674             : STATIC bool
     675  1044256395 : xfbtree_trans_bdetach(
     676             :         struct xfs_trans        *tp,
     677             :         struct xfs_buf          *bp)
     678             : {
     679  1044256395 :         struct xfs_buf_log_item *bli = bp->b_log_item;
     680  1044256395 :         bool                    dirty;
     681             : 
     682  1044256395 :         ASSERT(bli != NULL);
     683             : 
     684  1044256395 :         dirty = bli->bli_flags & (XFS_BLI_DIRTY | XFS_BLI_ORDERED);
     685             : 
     686  1044256395 :         bli->bli_flags &= ~(XFS_BLI_DIRTY | XFS_BLI_ORDERED |
     687             :                             XFS_BLI_LOGGED | XFS_BLI_STALE);
     688  1044256395 :         clear_bit(XFS_LI_DIRTY, &bli->bli_item.li_flags);
     689             : 
     690  2088605191 :         while (bp->b_log_item != NULL)
     691  1044320197 :                 xfs_trans_bdetach(tp, bp);
     692             : 
     693  1044284994 :         return dirty;
     694             : }
     695             : 
     696             : /*
     697             :  * Commit changes to the incore btree immediately by writing all dirty xfbtree
     698             :  * buffers to the backing xfile.  This detaches all xfbtree buffers from the
     699             :  * transaction, even on failure.  The buffer locks are dropped between the
     700             :  * delwri queue and submit, so the caller must synchronize btree access.
     701             :  *
     702             :  * Normally we'd let the buffers commit with the transaction and get written to
     703             :  * the xfile via the log, but online repair stages ephemeral btrees in memory
     704             :  * and uses the btree_staging functions to write new btrees to disk atomically.
     705             :  * The in-memory btree (and its backing store) are discarded at the end of the
     706             :  * repair phase, which means that xfbtree buffers cannot commit with the rest
     707             :  * of a transaction.
     708             :  *
     709             :  * In other words, online repair only needs the transaction to collect buffer
     710             :  * pointers and to avoid buffer deadlocks, not to guarantee consistency of
     711             :  * updates.
     712             :  */
     713             : int
     714   767619798 : xfbtree_trans_commit(
     715             :         struct xfbtree          *xfbt,
     716             :         struct xfs_trans        *tp)
     717             : {
     718   767619798 :         LIST_HEAD(buffer_list);
     719   767619798 :         struct xfs_log_item     *lip, *n;
     720   767619798 :         bool                    corrupt = false;
     721   767619798 :         bool                    tp_dirty = false;
     722             : 
     723             :         /*
     724             :          * For each xfbtree buffer attached to the transaction, write the dirty
     725             :          * buffers to the xfile and release them.
     726             :          */
     727  5179914253 :         list_for_each_entry_safe(lip, n, &tp->t_items, li_trans) {
     728  4412290655 :                 struct xfs_buf  *bp = xfbtree_buf_match(xfbt, lip);
     729  1044269368 :                 bool            dirty;
     730             : 
     731  1044269368 :                 if (!bp) {
     732  6736042574 :                         if (test_bit(XFS_LI_DIRTY, &lip->li_flags))
     733           0 :                                 tp_dirty |= true;
     734  3368021287 :                         continue;
     735             :                 }
     736             : 
     737  1044269368 :                 trace_xfbtree_trans_commit_buf(xfbt, bp);
     738             : 
     739  1044270330 :                 dirty = xfbtree_trans_bdetach(tp, bp);
     740  1044297942 :                 if (dirty && !corrupt) {
     741   900223273 :                         xfs_failaddr_t  fa;
     742             : 
     743             :                         /*
     744             :                          * Because this btree is ephemeral, validate the buffer
     745             :                          * structure before delwri_submit so that we can return
     746             :                          * corruption errors to the caller without shutting
     747             :                          * down the filesystem.
     748             :                          *
     749             :                          * Buffers that are directly mapped to the xfile do not
     750             :                          * need to be queued for IO at all.  Check if the DRAM
     751             :                          * has been poisoned, however.
     752             :                          *
     753             :                          * If the buffer fails verification, log the failure
     754             :                          * but continue walking the transaction items so that
     755             :                          * we remove all ephemeral btree buffers.
     756             :                          */
     757   900223273 :                         if (xfs_buf_check_poisoned(bp)) {
     758           0 :                                 corrupt = true;
     759           0 :                                 xfs_verifier_error(bp, -EFSCORRUPTED,
     760           0 :                                                 __this_address);
     761           0 :                                 continue;
     762             :                         }
     763             : 
     764   900215884 :                         fa = bp->b_ops->verify_struct(bp);
     765   900181572 :                         if (fa) {
     766           0 :                                 corrupt = true;
     767           0 :                                 xfs_verifier_error(bp, -EFSCORRUPTED, fa);
     768           0 :                                 continue;
     769             :                         }
     770             : 
     771   900181572 :                         if (!(bp->b_flags & _XBF_DIRECT_MAP))
     772           0 :                                 xfs_buf_delwri_queue_here(bp, &buffer_list);
     773             :                 }
     774             : 
     775  1044256241 :                 xfs_buf_relse(bp);
     776             :         }
     777             : 
     778             :         /*
     779             :          * Reset the transaction's dirty flag to reflect the dirty state of the
     780             :          * log items that are still attached.
     781             :          */
     782  1535247196 :         tp->t_flags = (tp->t_flags & ~XFS_TRANS_DIRTY) |
     783   767623598 :                         (tp_dirty ? XFS_TRANS_DIRTY : 0);
     784             : 
     785   767623598 :         if (corrupt) {
     786           0 :                 xfs_buf_delwri_cancel(&buffer_list);
     787           0 :                 return -EFSCORRUPTED;
     788             :         }
     789             : 
     790   767623598 :         if (list_empty(&buffer_list))
     791             :                 return 0;
     792             : 
     793           0 :         return xfs_buf_delwri_submit(&buffer_list);
     794             : }
     795             : 
     796             : /*
     797             :  * Cancel changes to the incore btree by detaching all the xfbtree buffers.
     798             :  * Changes are not written to the backing store.  This is needed for online
     799             :  * repair btrees, which are by nature ephemeral.
     800             :  */
     801             : void
     802           0 : xfbtree_trans_cancel(
     803             :         struct xfbtree          *xfbt,
     804             :         struct xfs_trans        *tp)
     805             : {
     806           0 :         struct xfs_log_item     *lip, *n;
     807           0 :         bool                    tp_dirty = false;
     808             : 
     809           0 :         list_for_each_entry_safe(lip, n, &tp->t_items, li_trans) {
     810           0 :                 struct xfs_buf  *bp = xfbtree_buf_match(xfbt, lip);
     811             : 
     812           0 :                 if (!bp) {
     813           0 :                         if (test_bit(XFS_LI_DIRTY, &lip->li_flags))
     814           0 :                                 tp_dirty |= true;
     815           0 :                         continue;
     816             :                 }
     817             : 
     818           0 :                 trace_xfbtree_trans_cancel_buf(xfbt, bp);
     819             : 
     820           0 :                 xfbtree_trans_bdetach(tp, bp);
     821           0 :                 xfs_buf_relse(bp);
     822             :         }
     823             : 
     824             :         /*
     825             :          * Reset the transaction's dirty flag to reflect the dirty state of the
     826             :          * log items that are still attached.
     827             :          */
     828           0 :         tp->t_flags = (tp->t_flags & ~XFS_TRANS_DIRTY) |
     829           0 :                         (tp_dirty ? XFS_TRANS_DIRTY : 0);
     830           0 : }

Generated by: LCOV version 1.14