LCOV - code coverage report
Current view: top level - fs/btrfs - root-tree.c (source / functions) Hit Total Coverage
Test: fstests of 6.5.0-rc4-xfsx @ Mon Jul 31 20:08:34 PDT 2023 Lines: 234 292 80.1 %
Date: 2023-07-31 20:08:34 Functions: 13 13 100.0 %

          Line data    Source code
       1             : // SPDX-License-Identifier: GPL-2.0
       2             : /*
       3             :  * Copyright (C) 2007 Oracle.  All rights reserved.
       4             :  */
       5             : 
       6             : #include <linux/err.h>
       7             : #include <linux/uuid.h>
       8             : #include "ctree.h"
       9             : #include "fs.h"
      10             : #include "messages.h"
      11             : #include "transaction.h"
      12             : #include "disk-io.h"
      13             : #include "print-tree.h"
      14             : #include "qgroup.h"
      15             : #include "space-info.h"
      16             : #include "accessors.h"
      17             : #include "root-tree.h"
      18             : #include "orphan.h"
      19             : 
      20             : /*
      21             :  * Read a root item from the tree. In case we detect a root item smaller then
      22             :  * sizeof(root_item), we know it's an old version of the root structure and
      23             :  * initialize all new fields to zero. The same happens if we detect mismatching
      24             :  * generation numbers as then we know the root was once mounted with an older
      25             :  * kernel that was not aware of the root item structure change.
      26             :  */
      27       48140 : static void btrfs_read_root_item(struct extent_buffer *eb, int slot,
      28             :                                 struct btrfs_root_item *item)
      29             : {
      30       48140 :         u32 len;
      31       48140 :         int need_reset = 0;
      32             : 
      33       48140 :         len = btrfs_item_size(eb, slot);
      34       48140 :         read_extent_buffer(eb, item, btrfs_item_ptr_offset(eb, slot),
      35       48140 :                            min_t(u32, len, sizeof(*item)));
      36       48140 :         if (len < sizeof(*item))
      37             :                 need_reset = 1;
      38       48140 :         if (!need_reset && btrfs_root_generation(item)
      39             :                 != btrfs_root_generation_v2(item)) {
      40           0 :                 if (btrfs_root_generation_v2(item) != 0) {
      41           0 :                         btrfs_warn(eb->fs_info,
      42             :                                         "mismatching generation and generation_v2 found in root item. This root was probably mounted with an older kernel. Resetting all new fields.");
      43             :                 }
      44             :                 need_reset = 1;
      45             :         }
      46       48140 :         if (need_reset) {
      47             :                 /* Clear all members from generation_v2 onwards. */
      48           0 :                 memset_startat(item, 0, generation_v2);
      49           0 :                 generate_random_guid(item->uuid);
      50             :         }
      51       48140 : }
      52             : 
      53             : /*
      54             :  * btrfs_find_root - lookup the root by the key.
      55             :  * root: the root of the root tree
      56             :  * search_key: the key to search
      57             :  * path: the path we search
      58             :  * root_item: the root item of the tree we look for
      59             :  * root_key: the root key of the tree we look for
      60             :  *
      61             :  * If ->offset of 'search_key' is -1ULL, it means we are not sure the offset
      62             :  * of the search key, just lookup the root with the highest offset for a
      63             :  * given objectid.
      64             :  *
      65             :  * If we find something return 0, otherwise > 0, < 0 on error.
      66             :  */
      67       51457 : int btrfs_find_root(struct btrfs_root *root, const struct btrfs_key *search_key,
      68             :                     struct btrfs_path *path, struct btrfs_root_item *root_item,
      69             :                     struct btrfs_key *root_key)
      70             : {
      71       51457 :         struct btrfs_key found_key;
      72       51457 :         struct extent_buffer *l;
      73       51457 :         int ret;
      74       51457 :         int slot;
      75             : 
      76       51457 :         ret = btrfs_search_slot(NULL, root, search_key, path, 0, 0);
      77       51457 :         if (ret < 0)
      78             :                 return ret;
      79             : 
      80       51457 :         if (search_key->offset != -1ULL) {   /* the search key is exact */
      81       39119 :                 if (ret > 0)
      82        3317 :                         goto out;
      83             :         } else {
      84       12338 :                 BUG_ON(ret == 0);               /* Logical error */
      85       12338 :                 if (path->slots[0] == 0)
      86           0 :                         goto out;
      87       12338 :                 path->slots[0]--;
      88       12338 :                 ret = 0;
      89             :         }
      90             : 
      91       48140 :         l = path->nodes[0];
      92       48140 :         slot = path->slots[0];
      93             : 
      94       48140 :         btrfs_item_key_to_cpu(l, &found_key, slot);
      95       48140 :         if (found_key.objectid != search_key->objectid ||
      96       48140 :             found_key.type != BTRFS_ROOT_ITEM_KEY) {
      97           0 :                 ret = 1;
      98           0 :                 goto out;
      99             :         }
     100             : 
     101       48140 :         if (root_item)
     102       48140 :                 btrfs_read_root_item(l, slot, root_item);
     103       48140 :         if (root_key)
     104       96280 :                 memcpy(root_key, &found_key, sizeof(found_key));
     105           0 : out:
     106       51457 :         btrfs_release_path(path);
     107       51457 :         return ret;
     108             : }
     109             : 
     110     1273953 : void btrfs_set_root_node(struct btrfs_root_item *item,
     111             :                          struct extent_buffer *node)
     112             : {
     113     1273953 :         btrfs_set_root_bytenr(item, node->start);
     114     1273953 :         btrfs_set_root_level(item, btrfs_header_level(node));
     115     1273953 :         btrfs_set_root_generation(item, btrfs_header_generation(node));
     116     1273953 : }
     117             : 
     118             : /*
     119             :  * copy the data in 'item' into the btree
     120             :  */
     121     2832649 : int btrfs_update_root(struct btrfs_trans_handle *trans, struct btrfs_root
     122             :                       *root, struct btrfs_key *key, struct btrfs_root_item
     123             :                       *item)
     124             : {
     125     2832649 :         struct btrfs_fs_info *fs_info = root->fs_info;
     126     2832649 :         struct btrfs_path *path;
     127     2832649 :         struct extent_buffer *l;
     128     2832649 :         int ret;
     129     2832649 :         int slot;
     130     2832649 :         unsigned long ptr;
     131     2832649 :         u32 old_len;
     132             : 
     133     2832649 :         path = btrfs_alloc_path();
     134     2832649 :         if (!path)
     135             :                 return -ENOMEM;
     136             : 
     137     2832649 :         ret = btrfs_search_slot(trans, root, key, path, 0, 1);
     138     2832649 :         if (ret < 0)
     139           0 :                 goto out;
     140             : 
     141     2832649 :         if (ret > 0) {
     142           0 :                 btrfs_crit(fs_info,
     143             :                         "unable to find root key (%llu %u %llu) in tree %llu",
     144             :                         key->objectid, key->type, key->offset,
     145             :                         root->root_key.objectid);
     146           0 :                 ret = -EUCLEAN;
     147           0 :                 btrfs_abort_transaction(trans, ret);
     148           0 :                 goto out;
     149             :         }
     150             : 
     151     2832649 :         l = path->nodes[0];
     152     2832649 :         slot = path->slots[0];
     153     2832649 :         ptr = btrfs_item_ptr_offset(l, slot);
     154     2832649 :         old_len = btrfs_item_size(l, slot);
     155             : 
     156             :         /*
     157             :          * If this is the first time we update the root item which originated
     158             :          * from an older kernel, we need to enlarge the item size to make room
     159             :          * for the added fields.
     160             :          */
     161     2832649 :         if (old_len < sizeof(*item)) {
     162           0 :                 btrfs_release_path(path);
     163           0 :                 ret = btrfs_search_slot(trans, root, key, path,
     164             :                                 -1, 1);
     165           0 :                 if (ret < 0) {
     166           0 :                         btrfs_abort_transaction(trans, ret);
     167           0 :                         goto out;
     168             :                 }
     169             : 
     170           0 :                 ret = btrfs_del_item(trans, root, path);
     171           0 :                 if (ret < 0) {
     172           0 :                         btrfs_abort_transaction(trans, ret);
     173           0 :                         goto out;
     174             :                 }
     175           0 :                 btrfs_release_path(path);
     176           0 :                 ret = btrfs_insert_empty_item(trans, root, path,
     177             :                                 key, sizeof(*item));
     178           0 :                 if (ret < 0) {
     179           0 :                         btrfs_abort_transaction(trans, ret);
     180           0 :                         goto out;
     181             :                 }
     182           0 :                 l = path->nodes[0];
     183           0 :                 slot = path->slots[0];
     184           0 :                 ptr = btrfs_item_ptr_offset(l, slot);
     185             :         }
     186             : 
     187             :         /*
     188             :          * Update generation_v2 so at the next mount we know the new root
     189             :          * fields are valid.
     190             :          */
     191     2832649 :         btrfs_set_root_generation_v2(item, btrfs_root_generation(item));
     192             : 
     193     2832649 :         write_extent_buffer(l, item, ptr, sizeof(*item));
     194     2832649 :         btrfs_mark_buffer_dirty(path->nodes[0]);
     195     2832649 : out:
     196     2832649 :         btrfs_free_path(path);
     197     2832649 :         return ret;
     198             : }
     199             : 
     200        7003 : int btrfs_insert_root(struct btrfs_trans_handle *trans, struct btrfs_root *root,
     201             :                       const struct btrfs_key *key, struct btrfs_root_item *item)
     202             : {
     203             :         /*
     204             :          * Make sure generation v1 and v2 match. See update_root for details.
     205             :          */
     206        7003 :         btrfs_set_root_generation_v2(item, btrfs_root_generation(item));
     207        7003 :         return btrfs_insert_item(trans, root, key, item, sizeof(*item));
     208             : }
     209             : 
     210        3181 : int btrfs_find_orphan_roots(struct btrfs_fs_info *fs_info)
     211             : {
     212        3181 :         struct btrfs_root *tree_root = fs_info->tree_root;
     213        3181 :         struct extent_buffer *leaf;
     214        3181 :         struct btrfs_path *path;
     215        3181 :         struct btrfs_key key;
     216        3181 :         struct btrfs_root *root;
     217        3181 :         int err = 0;
     218        3181 :         int ret;
     219             : 
     220        3181 :         path = btrfs_alloc_path();
     221        3181 :         if (!path)
     222             :                 return -ENOMEM;
     223             : 
     224        3181 :         key.objectid = BTRFS_ORPHAN_OBJECTID;
     225        3181 :         key.type = BTRFS_ORPHAN_ITEM_KEY;
     226        3181 :         key.offset = 0;
     227             : 
     228        3381 :         while (1) {
     229        3381 :                 u64 root_objectid;
     230             : 
     231        3381 :                 ret = btrfs_search_slot(NULL, tree_root, &key, path, 0, 0);
     232        3381 :                 if (ret < 0) {
     233             :                         err = ret;
     234             :                         break;
     235             :                 }
     236             : 
     237        3381 :                 leaf = path->nodes[0];
     238        3381 :                 if (path->slots[0] >= btrfs_header_nritems(leaf)) {
     239        3181 :                         ret = btrfs_next_leaf(tree_root, path);
     240        3181 :                         if (ret < 0)
     241             :                                 err = ret;
     242        3181 :                         if (ret != 0)
     243             :                                 break;
     244           0 :                         leaf = path->nodes[0];
     245             :                 }
     246             : 
     247         200 :                 btrfs_item_key_to_cpu(leaf, &key, path->slots[0]);
     248         200 :                 btrfs_release_path(path);
     249             : 
     250         200 :                 if (key.objectid != BTRFS_ORPHAN_OBJECTID ||
     251         200 :                     key.type != BTRFS_ORPHAN_ITEM_KEY)
     252             :                         break;
     253             : 
     254         200 :                 root_objectid = key.offset;
     255         200 :                 key.offset++;
     256             : 
     257         200 :                 root = btrfs_get_fs_root(fs_info, root_objectid, false);
     258         200 :                 err = PTR_ERR_OR_ZERO(root);
     259         200 :                 if (err && err != -ENOENT) {
     260             :                         break;
     261         200 :                 } else if (err == -ENOENT) {
     262           0 :                         struct btrfs_trans_handle *trans;
     263             : 
     264           0 :                         btrfs_release_path(path);
     265             : 
     266           0 :                         trans = btrfs_join_transaction(tree_root);
     267           0 :                         if (IS_ERR(trans)) {
     268           0 :                                 err = PTR_ERR(trans);
     269           0 :                                 btrfs_handle_fs_error(fs_info, err,
     270             :                                             "Failed to start trans to delete orphan item");
     271           0 :                                 break;
     272             :                         }
     273           0 :                         err = btrfs_del_orphan_item(trans, tree_root,
     274             :                                                     root_objectid);
     275           0 :                         btrfs_end_transaction(trans);
     276           0 :                         if (err) {
     277           0 :                                 btrfs_handle_fs_error(fs_info, err,
     278             :                                             "Failed to delete root orphan item");
     279           0 :                                 break;
     280             :                         }
     281           0 :                         continue;
     282             :                 }
     283             : 
     284         200 :                 WARN_ON(!test_bit(BTRFS_ROOT_ORPHAN_ITEM_INSERTED, &root->state));
     285         200 :                 if (btrfs_root_refs(&root->root_item) == 0) {
     286         200 :                         struct btrfs_key drop_key;
     287             : 
     288         200 :                         btrfs_disk_key_to_cpu(&drop_key, &root->root_item.drop_progress);
     289             :                         /*
     290             :                          * If we have a non-zero drop_progress then we know we
     291             :                          * made it partly through deleting this snapshot, and
     292             :                          * thus we need to make sure we block any balance from
     293             :                          * happening until this snapshot is completely dropped.
     294             :                          */
     295         200 :                         if (drop_key.objectid != 0 || drop_key.type != 0 ||
     296         200 :                             drop_key.offset != 0) {
     297           0 :                                 set_bit(BTRFS_FS_UNFINISHED_DROPS, &fs_info->flags);
     298           0 :                                 set_bit(BTRFS_ROOT_UNFINISHED_DROP, &root->state);
     299             :                         }
     300             : 
     301         200 :                         set_bit(BTRFS_ROOT_DEAD_TREE, &root->state);
     302         200 :                         btrfs_add_dead_root(root);
     303             :                 }
     304         200 :                 btrfs_put_root(root);
     305             :         }
     306             : 
     307        3181 :         btrfs_free_path(path);
     308        3181 :         return err;
     309             : }
     310             : 
     311             : /* drop the root item for 'key' from the tree root */
     312        1776 : int btrfs_del_root(struct btrfs_trans_handle *trans,
     313             :                    const struct btrfs_key *key)
     314             : {
     315        1776 :         struct btrfs_root *root = trans->fs_info->tree_root;
     316        1776 :         struct btrfs_path *path;
     317        1776 :         int ret;
     318             : 
     319        1776 :         path = btrfs_alloc_path();
     320        1776 :         if (!path)
     321             :                 return -ENOMEM;
     322        1776 :         ret = btrfs_search_slot(trans, root, key, path, -1, 1);
     323        1776 :         if (ret < 0)
     324           0 :                 goto out;
     325             : 
     326        1776 :         BUG_ON(ret != 0);
     327             : 
     328        1776 :         ret = btrfs_del_item(trans, root, path);
     329        1776 : out:
     330        1776 :         btrfs_free_path(path);
     331        1776 :         return ret;
     332             : }
     333             : 
     334         174 : int btrfs_del_root_ref(struct btrfs_trans_handle *trans, u64 root_id,
     335             :                        u64 ref_id, u64 dirid, u64 *sequence,
     336             :                        const struct fscrypt_str *name)
     337             : {
     338         174 :         struct btrfs_root *tree_root = trans->fs_info->tree_root;
     339         174 :         struct btrfs_path *path;
     340         174 :         struct btrfs_root_ref *ref;
     341         174 :         struct extent_buffer *leaf;
     342         174 :         struct btrfs_key key;
     343         174 :         unsigned long ptr;
     344         174 :         int ret;
     345             : 
     346         174 :         path = btrfs_alloc_path();
     347         174 :         if (!path)
     348             :                 return -ENOMEM;
     349             : 
     350         174 :         key.objectid = root_id;
     351         174 :         key.type = BTRFS_ROOT_BACKREF_KEY;
     352         174 :         key.offset = ref_id;
     353         348 : again:
     354         348 :         ret = btrfs_search_slot(trans, tree_root, &key, path, -1, 1);
     355         348 :         if (ret < 0) {
     356           0 :                 goto out;
     357         348 :         } else if (ret == 0) {
     358         348 :                 leaf = path->nodes[0];
     359         348 :                 ref = btrfs_item_ptr(leaf, path->slots[0],
     360             :                                      struct btrfs_root_ref);
     361         348 :                 ptr = (unsigned long)(ref + 1);
     362         348 :                 if ((btrfs_root_ref_dirid(leaf, ref) != dirid) ||
     363         696 :                     (btrfs_root_ref_name_len(leaf, ref) != name->len) ||
     364         348 :                     memcmp_extent_buffer(leaf, name->name, ptr, name->len)) {
     365           0 :                         ret = -ENOENT;
     366           0 :                         goto out;
     367             :                 }
     368         348 :                 *sequence = btrfs_root_ref_sequence(leaf, ref);
     369             : 
     370         348 :                 ret = btrfs_del_item(trans, tree_root, path);
     371         348 :                 if (ret)
     372           0 :                         goto out;
     373             :         } else {
     374           0 :                 ret = -ENOENT;
     375           0 :                 goto out;
     376             :         }
     377             : 
     378         348 :         if (key.type == BTRFS_ROOT_BACKREF_KEY) {
     379         174 :                 btrfs_release_path(path);
     380         174 :                 key.objectid = ref_id;
     381         174 :                 key.type = BTRFS_ROOT_REF_KEY;
     382         174 :                 key.offset = root_id;
     383         174 :                 goto again;
     384             :         }
     385             : 
     386         174 : out:
     387         174 :         btrfs_free_path(path);
     388         174 :         return ret;
     389             : }
     390             : 
     391             : /*
     392             :  * add a btrfs_root_ref item.  type is either BTRFS_ROOT_REF_KEY
     393             :  * or BTRFS_ROOT_BACKREF_KEY.
     394             :  *
     395             :  * The dirid, sequence, name and name_len refer to the directory entry
     396             :  * that is referencing the root.
     397             :  *
     398             :  * For a forward ref, the root_id is the id of the tree referencing
     399             :  * the root and ref_id is the id of the subvol  or snapshot.
     400             :  *
     401             :  * For a back ref the root_id is the id of the subvol or snapshot and
     402             :  * ref_id is the id of the tree referencing it.
     403             :  *
     404             :  * Will return 0, -ENOMEM, or anything from the CoW path
     405             :  */
     406        1284 : int btrfs_add_root_ref(struct btrfs_trans_handle *trans, u64 root_id,
     407             :                        u64 ref_id, u64 dirid, u64 sequence,
     408             :                        const struct fscrypt_str *name)
     409             : {
     410        1284 :         struct btrfs_root *tree_root = trans->fs_info->tree_root;
     411        1284 :         struct btrfs_key key;
     412        1284 :         int ret;
     413        1284 :         struct btrfs_path *path;
     414        1284 :         struct btrfs_root_ref *ref;
     415        1284 :         struct extent_buffer *leaf;
     416        1284 :         unsigned long ptr;
     417             : 
     418        1284 :         path = btrfs_alloc_path();
     419        1284 :         if (!path)
     420             :                 return -ENOMEM;
     421             : 
     422        1284 :         key.objectid = root_id;
     423        1284 :         key.type = BTRFS_ROOT_BACKREF_KEY;
     424        1284 :         key.offset = ref_id;
     425        2568 : again:
     426        5136 :         ret = btrfs_insert_empty_item(trans, tree_root, path, &key,
     427        2568 :                                       sizeof(*ref) + name->len);
     428        2568 :         if (ret) {
     429           0 :                 btrfs_abort_transaction(trans, ret);
     430           0 :                 btrfs_free_path(path);
     431           0 :                 return ret;
     432             :         }
     433             : 
     434        2568 :         leaf = path->nodes[0];
     435        2568 :         ref = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_root_ref);
     436        2568 :         btrfs_set_root_ref_dirid(leaf, ref, dirid);
     437        2568 :         btrfs_set_root_ref_sequence(leaf, ref, sequence);
     438        2568 :         btrfs_set_root_ref_name_len(leaf, ref, name->len);
     439        2568 :         ptr = (unsigned long)(ref + 1);
     440        2568 :         write_extent_buffer(leaf, name->name, ptr, name->len);
     441        2568 :         btrfs_mark_buffer_dirty(leaf);
     442             : 
     443        2568 :         if (key.type == BTRFS_ROOT_BACKREF_KEY) {
     444        1284 :                 btrfs_release_path(path);
     445        1284 :                 key.objectid = ref_id;
     446        1284 :                 key.type = BTRFS_ROOT_REF_KEY;
     447        1284 :                 key.offset = root_id;
     448        1284 :                 goto again;
     449             :         }
     450             : 
     451        1284 :         btrfs_free_path(path);
     452        1284 :         return 0;
     453             : }
     454             : 
     455             : /*
     456             :  * Old btrfs forgets to init root_item->flags and root_item->byte_limit
     457             :  * for subvolumes. To work around this problem, we steal a bit from
     458             :  * root_item->inode_item->flags, and use it to indicate if those fields
     459             :  * have been properly initialized.
     460             :  */
     461       10101 : void btrfs_check_and_init_root_item(struct btrfs_root_item *root_item)
     462             : {
     463       10101 :         u64 inode_flags = btrfs_stack_inode_flags(&root_item->inode);
     464             : 
     465       10101 :         if (!(inode_flags & BTRFS_INODE_ROOT_ITEM_INIT)) {
     466        1111 :                 inode_flags |= BTRFS_INODE_ROOT_ITEM_INIT;
     467        1111 :                 btrfs_set_stack_inode_flags(&root_item->inode, inode_flags);
     468        1111 :                 btrfs_set_root_flags(root_item, 0);
     469        1111 :                 btrfs_set_root_limit(root_item, 0);
     470             :         }
     471       10101 : }
     472             : 
     473    40049435 : void btrfs_update_root_times(struct btrfs_trans_handle *trans,
     474             :                              struct btrfs_root *root)
     475             : {
     476    40049435 :         struct btrfs_root_item *item = &root->root_item;
     477    40049435 :         struct timespec64 ct;
     478             : 
     479    40049435 :         ktime_get_real_ts64(&ct);
     480    40050075 :         spin_lock(&root->root_item_lock);
     481    40055957 :         btrfs_set_root_ctransid(item, trans->transid);
     482    40055957 :         btrfs_set_stack_timespec_sec(&item->ctime, ct.tv_sec);
     483    40055957 :         btrfs_set_stack_timespec_nsec(&item->ctime, ct.tv_nsec);
     484    40055957 :         spin_unlock(&root->root_item_lock);
     485    40054442 : }
     486             : 
     487             : /*
     488             :  * btrfs_subvolume_reserve_metadata() - reserve space for subvolume operation
     489             :  * root: the root of the parent directory
     490             :  * rsv: block reservation
     491             :  * items: the number of items that we need do reservation
     492             :  * use_global_rsv: allow fallback to the global block reservation
     493             :  *
     494             :  * This function is used to reserve the space for snapshot/subvolume
     495             :  * creation and deletion. Those operations are different with the
     496             :  * common file/directory operations, they change two fs/file trees
     497             :  * and root tree, the number of items that the qgroup reserves is
     498             :  * different with the free space reservation. So we can not use
     499             :  * the space reservation mechanism in start_transaction().
     500             :  */
     501        1446 : int btrfs_subvolume_reserve_metadata(struct btrfs_root *root,
     502             :                                      struct btrfs_block_rsv *rsv, int items,
     503             :                                      bool use_global_rsv)
     504             : {
     505        1446 :         u64 qgroup_num_bytes = 0;
     506        1446 :         u64 num_bytes;
     507        1446 :         int ret;
     508        1446 :         struct btrfs_fs_info *fs_info = root->fs_info;
     509        1446 :         struct btrfs_block_rsv *global_rsv = &fs_info->global_block_rsv;
     510             : 
     511        2892 :         if (test_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags)) {
     512             :                 /* One for parent inode, two for dir entries */
     513         260 :                 qgroup_num_bytes = 3 * fs_info->nodesize;
     514         260 :                 ret = btrfs_qgroup_reserve_meta_prealloc(root,
     515             :                                                          qgroup_num_bytes, true,
     516             :                                                          false);
     517         260 :                 if (ret)
     518             :                         return ret;
     519             :         }
     520             : 
     521        1446 :         num_bytes = btrfs_calc_insert_metadata_size(fs_info, items);
     522        1446 :         rsv->space_info = btrfs_find_space_info(fs_info,
     523             :                                             BTRFS_BLOCK_GROUP_METADATA);
     524        1446 :         ret = btrfs_block_rsv_add(fs_info, rsv, num_bytes,
     525             :                                   BTRFS_RESERVE_FLUSH_ALL);
     526             : 
     527        1446 :         if (ret == -ENOSPC && use_global_rsv)
     528           0 :                 ret = btrfs_block_rsv_migrate(global_rsv, rsv, num_bytes, true);
     529             : 
     530        1446 :         if (ret && qgroup_num_bytes)
     531           0 :                 btrfs_qgroup_free_meta_prealloc(root, qgroup_num_bytes);
     532             : 
     533        1446 :         if (!ret) {
     534        1446 :                 spin_lock(&rsv->lock);
     535        1446 :                 rsv->qgroup_rsv_reserved += qgroup_num_bytes;
     536        1446 :                 spin_unlock(&rsv->lock);
     537             :         }
     538             :         return ret;
     539             : }
     540             : 
     541        1446 : void btrfs_subvolume_release_metadata(struct btrfs_root *root,
     542             :                                       struct btrfs_block_rsv *rsv)
     543             : {
     544        1446 :         struct btrfs_fs_info *fs_info = root->fs_info;
     545        1446 :         u64 qgroup_to_release;
     546             : 
     547        1446 :         btrfs_block_rsv_release(fs_info, rsv, (u64)-1, &qgroup_to_release);
     548        1446 :         btrfs_qgroup_convert_reserved_meta(root, qgroup_to_release);
     549        1446 : }

Generated by: LCOV version 1.14