1c1d7c514SDavid Sterba // SPDX-License-Identifier: GPL-2.0
26cbd5570SChris Mason /*
36cbd5570SChris Mason * Copyright (C) 2007 Oracle. All rights reserved.
46cbd5570SChris Mason */
56cbd5570SChris Mason
6886322e8SSachin Kamat #include <linux/err.h>
78ea05e3aSAlexander Block #include <linux/uuid.h>
83768f368SChris Mason #include "ctree.h"
9ec8eb376SJosef Bacik #include "fs.h"
10ec8eb376SJosef Bacik #include "messages.h"
115eda7b5eSChris Mason #include "transaction.h"
123768f368SChris Mason #include "disk-io.h"
1328a32d2bSJosef Bacik #include "qgroup.h"
1428a32d2bSJosef Bacik #include "space-info.h"
1507e81dc9SJosef Bacik #include "accessors.h"
1645c40c8fSJosef Bacik #include "root-tree.h"
17aa5d3003SJosef Bacik #include "orphan.h"
183768f368SChris Mason
19bf4ef679SChris Mason /*
208ea05e3aSAlexander Block * Read a root item from the tree. In case we detect a root item smaller then
218ea05e3aSAlexander Block * sizeof(root_item), we know it's an old version of the root structure and
228ea05e3aSAlexander Block * initialize all new fields to zero. The same happens if we detect mismatching
238ea05e3aSAlexander Block * generation numbers as then we know the root was once mounted with an older
248ea05e3aSAlexander Block * kernel that was not aware of the root item structure change.
258ea05e3aSAlexander Block */
btrfs_read_root_item(struct extent_buffer * eb,int slot,struct btrfs_root_item * item)26171170c1SSergei Trofimovich static void btrfs_read_root_item(struct extent_buffer *eb, int slot,
278ea05e3aSAlexander Block struct btrfs_root_item *item)
288ea05e3aSAlexander Block {
29f65e25e3SYueHaibing u32 len;
308ea05e3aSAlexander Block int need_reset = 0;
318ea05e3aSAlexander Block
323212fa14SJosef Bacik len = btrfs_item_size(eb, slot);
338ea05e3aSAlexander Block read_extent_buffer(eb, item, btrfs_item_ptr_offset(eb, slot),
34f65e25e3SYueHaibing min_t(u32, len, sizeof(*item)));
358ea05e3aSAlexander Block if (len < sizeof(*item))
368ea05e3aSAlexander Block need_reset = 1;
378ea05e3aSAlexander Block if (!need_reset && btrfs_root_generation(item)
388ea05e3aSAlexander Block != btrfs_root_generation_v2(item)) {
398ea05e3aSAlexander Block if (btrfs_root_generation_v2(item) != 0) {
40f14d104dSDavid Sterba btrfs_warn(eb->fs_info,
415d163e0eSJeff Mahoney "mismatching generation and generation_v2 found in root item. This root was probably mounted with an older kernel. Resetting all new fields.");
428ea05e3aSAlexander Block }
438ea05e3aSAlexander Block need_reset = 1;
448ea05e3aSAlexander Block }
458ea05e3aSAlexander Block if (need_reset) {
46a2c5062fSKees Cook /* Clear all members from generation_v2 onwards. */
47a2c5062fSKees Cook memset_startat(item, 0, generation_v2);
48807fc790SAndy Shevchenko generate_random_guid(item->uuid);
498ea05e3aSAlexander Block }
508ea05e3aSAlexander Block }
518ea05e3aSAlexander Block
528ea05e3aSAlexander Block /*
539580503bSDavid Sterba * Lookup the root by the key.
549580503bSDavid Sterba *
55cb517eabSMiao Xie * root: the root of the root tree
56cb517eabSMiao Xie * search_key: the key to search
57cb517eabSMiao Xie * path: the path we search
58cb517eabSMiao Xie * root_item: the root item of the tree we look for
5901327610SNicholas D Steeves * root_key: the root key of the tree we look for
60cb517eabSMiao Xie *
6101327610SNicholas D Steeves * If ->offset of 'search_key' is -1ULL, it means we are not sure the offset
62cb517eabSMiao Xie * of the search key, just lookup the root with the highest offset for a
63cb517eabSMiao Xie * given objectid.
64cb517eabSMiao Xie *
65cb517eabSMiao Xie * If we find something return 0, otherwise > 0, < 0 on error.
66d352ac68SChris Mason */
btrfs_find_root(struct btrfs_root * root,const struct btrfs_key * search_key,struct btrfs_path * path,struct btrfs_root_item * root_item,struct btrfs_key * root_key)67310712b2SOmar Sandoval int btrfs_find_root(struct btrfs_root *root, const struct btrfs_key *search_key,
68cb517eabSMiao Xie struct btrfs_path *path, struct btrfs_root_item *root_item,
69cb517eabSMiao Xie struct btrfs_key *root_key)
703768f368SChris Mason {
715f39d397SChris Mason struct btrfs_key found_key;
725f39d397SChris Mason struct extent_buffer *l;
733768f368SChris Mason int ret;
743768f368SChris Mason int slot;
753768f368SChris Mason
76cb517eabSMiao Xie ret = btrfs_search_slot(NULL, root, search_key, path, 0, 0);
773768f368SChris Mason if (ret < 0)
78cb517eabSMiao Xie return ret;
795f39d397SChris Mason
80cb517eabSMiao Xie if (search_key->offset != -1ULL) { /* the search key is exact */
81cb517eabSMiao Xie if (ret > 0)
823768f368SChris Mason goto out;
83cb517eabSMiao Xie } else {
849dcb6ed9SDavid Sterba /*
859dcb6ed9SDavid Sterba * Key with offset -1 found, there would have to exist a root
869dcb6ed9SDavid Sterba * with such id, but this is out of the valid range.
879dcb6ed9SDavid Sterba */
889dcb6ed9SDavid Sterba if (ret == 0) {
899dcb6ed9SDavid Sterba ret = -EUCLEAN;
909dcb6ed9SDavid Sterba goto out;
919dcb6ed9SDavid Sterba }
92cb517eabSMiao Xie if (path->slots[0] == 0)
93cb517eabSMiao Xie goto out;
94cb517eabSMiao Xie path->slots[0]--;
95cb517eabSMiao Xie ret = 0;
963768f368SChris Mason }
97cb517eabSMiao Xie
9876dda93cSYan, Zheng l = path->nodes[0];
99cb517eabSMiao Xie slot = path->slots[0];
100cb517eabSMiao Xie
10176dda93cSYan, Zheng btrfs_item_key_to_cpu(l, &found_key, slot);
102cb517eabSMiao Xie if (found_key.objectid != search_key->objectid ||
10376dda93cSYan, Zheng found_key.type != BTRFS_ROOT_ITEM_KEY) {
10476dda93cSYan, Zheng ret = 1;
10576dda93cSYan, Zheng goto out;
10676dda93cSYan, Zheng }
1078ea05e3aSAlexander Block
108cb517eabSMiao Xie if (root_item)
109cb517eabSMiao Xie btrfs_read_root_item(l, slot, root_item);
110cb517eabSMiao Xie if (root_key)
111cb517eabSMiao Xie memcpy(root_key, &found_key, sizeof(found_key));
1123768f368SChris Mason out:
113cb517eabSMiao Xie btrfs_release_path(path);
1143768f368SChris Mason return ret;
1153768f368SChris Mason }
1163768f368SChris Mason
btrfs_set_root_node(struct btrfs_root_item * item,struct extent_buffer * node)117bf5f32ecSMark Fasheh void btrfs_set_root_node(struct btrfs_root_item *item,
1185d4f98a2SYan Zheng struct extent_buffer *node)
1195d4f98a2SYan Zheng {
1205d4f98a2SYan Zheng btrfs_set_root_bytenr(item, node->start);
1215d4f98a2SYan Zheng btrfs_set_root_level(item, btrfs_header_level(node));
1225d4f98a2SYan Zheng btrfs_set_root_generation(item, btrfs_header_generation(node));
1235d4f98a2SYan Zheng }
1245d4f98a2SYan Zheng
125d352ac68SChris Mason /*
126d352ac68SChris Mason * copy the data in 'item' into the btree
127d352ac68SChris Mason */
btrfs_update_root(struct btrfs_trans_handle * trans,struct btrfs_root * root,struct btrfs_key * key,struct btrfs_root_item * item)128e089f05cSChris Mason int btrfs_update_root(struct btrfs_trans_handle *trans, struct btrfs_root
129e089f05cSChris Mason *root, struct btrfs_key *key, struct btrfs_root_item
130e089f05cSChris Mason *item)
1313768f368SChris Mason {
1320b246afaSJeff Mahoney struct btrfs_fs_info *fs_info = root->fs_info;
1335caf2a00SChris Mason struct btrfs_path *path;
1345f39d397SChris Mason struct extent_buffer *l;
1353768f368SChris Mason int ret;
1363768f368SChris Mason int slot;
1375f39d397SChris Mason unsigned long ptr;
1380412e58cSAlexandru Moise u32 old_len;
1393768f368SChris Mason
1405caf2a00SChris Mason path = btrfs_alloc_path();
141b45a9d8bSJeff Mahoney if (!path)
142b45a9d8bSJeff Mahoney return -ENOMEM;
143b45a9d8bSJeff Mahoney
1445caf2a00SChris Mason ret = btrfs_search_slot(trans, root, key, path, 0, 1);
14572bd2323SFilipe Manana if (ret < 0)
146005d6427SDavid Sterba goto out;
147d6667462SChris Mason
1487ac1e464SQu Wenruo if (ret > 0) {
1497ac1e464SQu Wenruo btrfs_crit(fs_info,
1507ac1e464SQu Wenruo "unable to find root key (%llu %u %llu) in tree %llu",
151*e094f480SJosef Bacik key->objectid, key->type, key->offset, btrfs_root_id(root));
1527ac1e464SQu Wenruo ret = -EUCLEAN;
1537ac1e464SQu Wenruo btrfs_abort_transaction(trans, ret);
1547ac1e464SQu Wenruo goto out;
155d6667462SChris Mason }
156d6667462SChris Mason
1575f39d397SChris Mason l = path->nodes[0];
1585caf2a00SChris Mason slot = path->slots[0];
1595f39d397SChris Mason ptr = btrfs_item_ptr_offset(l, slot);
1603212fa14SJosef Bacik old_len = btrfs_item_size(l, slot);
1618ea05e3aSAlexander Block
1628ea05e3aSAlexander Block /*
1638ea05e3aSAlexander Block * If this is the first time we update the root item which originated
1648ea05e3aSAlexander Block * from an older kernel, we need to enlarge the item size to make room
1658ea05e3aSAlexander Block * for the added fields.
1668ea05e3aSAlexander Block */
1678ea05e3aSAlexander Block if (old_len < sizeof(*item)) {
1688ea05e3aSAlexander Block btrfs_release_path(path);
1698ea05e3aSAlexander Block ret = btrfs_search_slot(trans, root, key, path,
1708ea05e3aSAlexander Block -1, 1);
171005d6427SDavid Sterba if (ret < 0) {
17266642832SJeff Mahoney btrfs_abort_transaction(trans, ret);
173005d6427SDavid Sterba goto out;
174005d6427SDavid Sterba }
175005d6427SDavid Sterba
1768ea05e3aSAlexander Block ret = btrfs_del_item(trans, root, path);
177005d6427SDavid Sterba if (ret < 0) {
17866642832SJeff Mahoney btrfs_abort_transaction(trans, ret);
179005d6427SDavid Sterba goto out;
180005d6427SDavid Sterba }
1818ea05e3aSAlexander Block btrfs_release_path(path);
1828ea05e3aSAlexander Block ret = btrfs_insert_empty_item(trans, root, path,
1838ea05e3aSAlexander Block key, sizeof(*item));
184005d6427SDavid Sterba if (ret < 0) {
18566642832SJeff Mahoney btrfs_abort_transaction(trans, ret);
186005d6427SDavid Sterba goto out;
187005d6427SDavid Sterba }
1888ea05e3aSAlexander Block l = path->nodes[0];
1898ea05e3aSAlexander Block slot = path->slots[0];
1908ea05e3aSAlexander Block ptr = btrfs_item_ptr_offset(l, slot);
1918ea05e3aSAlexander Block }
1928ea05e3aSAlexander Block
1938ea05e3aSAlexander Block /*
1948ea05e3aSAlexander Block * Update generation_v2 so at the next mount we know the new root
1958ea05e3aSAlexander Block * fields are valid.
1968ea05e3aSAlexander Block */
1978ea05e3aSAlexander Block btrfs_set_root_generation_v2(item, btrfs_root_generation(item));
1988ea05e3aSAlexander Block
1995f39d397SChris Mason write_extent_buffer(l, item, ptr, sizeof(*item));
20050564b65SFilipe Manana btrfs_mark_buffer_dirty(trans, path->nodes[0]);
2013768f368SChris Mason out:
2025caf2a00SChris Mason btrfs_free_path(path);
2033768f368SChris Mason return ret;
2043768f368SChris Mason }
2053768f368SChris Mason
btrfs_insert_root(struct btrfs_trans_handle * trans,struct btrfs_root * root,const struct btrfs_key * key,struct btrfs_root_item * item)206d16cb050SJeff Mahoney int btrfs_insert_root(struct btrfs_trans_handle *trans, struct btrfs_root *root,
207310712b2SOmar Sandoval const struct btrfs_key *key, struct btrfs_root_item *item)
2083768f368SChris Mason {
2098ea05e3aSAlexander Block /*
2108ea05e3aSAlexander Block * Make sure generation v1 and v2 match. See update_root for details.
2118ea05e3aSAlexander Block */
2128ea05e3aSAlexander Block btrfs_set_root_generation_v2(item, btrfs_root_generation(item));
213d16cb050SJeff Mahoney return btrfs_insert_item(trans, root, key, item, sizeof(*item));
2143768f368SChris Mason }
2153768f368SChris Mason
btrfs_find_orphan_roots(struct btrfs_fs_info * fs_info)2166bccf3abSJeff Mahoney int btrfs_find_orphan_roots(struct btrfs_fs_info *fs_info)
21776dda93cSYan, Zheng {
2186bccf3abSJeff Mahoney struct btrfs_root *tree_root = fs_info->tree_root;
21976dda93cSYan, Zheng struct extent_buffer *leaf;
22076dda93cSYan, Zheng struct btrfs_path *path;
22176dda93cSYan, Zheng struct btrfs_key key;
222d68fc57bSYan, Zheng struct btrfs_root *root;
22376dda93cSYan, Zheng int err = 0;
22476dda93cSYan, Zheng int ret;
22576dda93cSYan, Zheng
22676dda93cSYan, Zheng path = btrfs_alloc_path();
22776dda93cSYan, Zheng if (!path)
22876dda93cSYan, Zheng return -ENOMEM;
22976dda93cSYan, Zheng
23076dda93cSYan, Zheng key.objectid = BTRFS_ORPHAN_OBJECTID;
23176dda93cSYan, Zheng key.type = BTRFS_ORPHAN_ITEM_KEY;
23276dda93cSYan, Zheng key.offset = 0;
23376dda93cSYan, Zheng
23476dda93cSYan, Zheng while (1) {
23556e9357aSDavid Sterba u64 root_objectid;
23656e9357aSDavid Sterba
23776dda93cSYan, Zheng ret = btrfs_search_slot(NULL, tree_root, &key, path, 0, 0);
23876dda93cSYan, Zheng if (ret < 0) {
23976dda93cSYan, Zheng err = ret;
24076dda93cSYan, Zheng break;
24176dda93cSYan, Zheng }
24276dda93cSYan, Zheng
24376dda93cSYan, Zheng leaf = path->nodes[0];
24476dda93cSYan, Zheng if (path->slots[0] >= btrfs_header_nritems(leaf)) {
24576dda93cSYan, Zheng ret = btrfs_next_leaf(tree_root, path);
24676dda93cSYan, Zheng if (ret < 0)
24776dda93cSYan, Zheng err = ret;
24876dda93cSYan, Zheng if (ret != 0)
24976dda93cSYan, Zheng break;
25076dda93cSYan, Zheng leaf = path->nodes[0];
25176dda93cSYan, Zheng }
25276dda93cSYan, Zheng
25376dda93cSYan, Zheng btrfs_item_key_to_cpu(leaf, &key, path->slots[0]);
254b3b4aa74SDavid Sterba btrfs_release_path(path);
25576dda93cSYan, Zheng
25676dda93cSYan, Zheng if (key.objectid != BTRFS_ORPHAN_OBJECTID ||
25776dda93cSYan, Zheng key.type != BTRFS_ORPHAN_ITEM_KEY)
25876dda93cSYan, Zheng break;
25976dda93cSYan, Zheng
26056e9357aSDavid Sterba root_objectid = key.offset;
261d68fc57bSYan, Zheng key.offset++;
262d68fc57bSYan, Zheng
26356e9357aSDavid Sterba root = btrfs_get_fs_root(fs_info, root_objectid, false);
264886322e8SSachin Kamat err = PTR_ERR_OR_ZERO(root);
26568a7342cSJosef Bacik if (err && err != -ENOENT) {
26676dda93cSYan, Zheng break;
26768a7342cSJosef Bacik } else if (err == -ENOENT) {
26868a7342cSJosef Bacik struct btrfs_trans_handle *trans;
26968a7342cSJosef Bacik
27068a7342cSJosef Bacik btrfs_release_path(path);
27168a7342cSJosef Bacik
27268a7342cSJosef Bacik trans = btrfs_join_transaction(tree_root);
27368a7342cSJosef Bacik if (IS_ERR(trans)) {
27468a7342cSJosef Bacik err = PTR_ERR(trans);
2750b246afaSJeff Mahoney btrfs_handle_fs_error(fs_info, err,
2765d163e0eSJeff Mahoney "Failed to start trans to delete orphan item");
27768a7342cSJosef Bacik break;
27868a7342cSJosef Bacik }
27968a7342cSJosef Bacik err = btrfs_del_orphan_item(trans, tree_root,
28056e9357aSDavid Sterba root_objectid);
2813a45bb20SJeff Mahoney btrfs_end_transaction(trans);
28268a7342cSJosef Bacik if (err) {
2830b246afaSJeff Mahoney btrfs_handle_fs_error(fs_info, err,
2845d163e0eSJeff Mahoney "Failed to delete root orphan item");
28568a7342cSJosef Bacik break;
28668a7342cSJosef Bacik }
28768a7342cSJosef Bacik continue;
28876dda93cSYan, Zheng }
28976dda93cSYan, Zheng
290e59d18b4SJosef Bacik WARN_ON(!test_bit(BTRFS_ROOT_ORPHAN_ITEM_INSERTED, &root->state));
29178c52d9eSJosef Bacik if (btrfs_root_refs(&root->root_item) == 0) {
292b4be6aefSJosef Bacik struct btrfs_key drop_key;
293b4be6aefSJosef Bacik
294b4be6aefSJosef Bacik btrfs_disk_key_to_cpu(&drop_key, &root->root_item.drop_progress);
295b4be6aefSJosef Bacik /*
296b4be6aefSJosef Bacik * If we have a non-zero drop_progress then we know we
297b4be6aefSJosef Bacik * made it partly through deleting this snapshot, and
298b4be6aefSJosef Bacik * thus we need to make sure we block any balance from
299b4be6aefSJosef Bacik * happening until this snapshot is completely dropped.
300b4be6aefSJosef Bacik */
301b4be6aefSJosef Bacik if (drop_key.objectid != 0 || drop_key.type != 0 ||
302b4be6aefSJosef Bacik drop_key.offset != 0) {
303b4be6aefSJosef Bacik set_bit(BTRFS_FS_UNFINISHED_DROPS, &fs_info->flags);
304b4be6aefSJosef Bacik set_bit(BTRFS_ROOT_UNFINISHED_DROP, &root->state);
305b4be6aefSJosef Bacik }
306b4be6aefSJosef Bacik
30778c52d9eSJosef Bacik set_bit(BTRFS_ROOT_DEAD_TREE, &root->state);
30814927d95SMiao Xie btrfs_add_dead_root(root);
30976dda93cSYan, Zheng }
31000246528SJosef Bacik btrfs_put_root(root);
31178c52d9eSJosef Bacik }
31276dda93cSYan, Zheng
31376dda93cSYan, Zheng btrfs_free_path(path);
31476dda93cSYan, Zheng return err;
31576dda93cSYan, Zheng }
31676dda93cSYan, Zheng
3171cd5447eSJeff Mahoney /* drop the root item for 'key' from the tree root */
btrfs_del_root(struct btrfs_trans_handle * trans,const struct btrfs_key * key)3181cd5447eSJeff Mahoney int btrfs_del_root(struct btrfs_trans_handle *trans,
319ab9ce7d4SLu Fengqi const struct btrfs_key *key)
3203768f368SChris Mason {
321ab9ce7d4SLu Fengqi struct btrfs_root *root = trans->fs_info->tree_root;
3225caf2a00SChris Mason struct btrfs_path *path;
3233768f368SChris Mason int ret;
3243768f368SChris Mason
3255caf2a00SChris Mason path = btrfs_alloc_path();
326db5b493aSTsutomu Itoh if (!path)
327db5b493aSTsutomu Itoh return -ENOMEM;
3285caf2a00SChris Mason ret = btrfs_search_slot(trans, root, key, path, -1, 1);
3293768f368SChris Mason if (ret < 0)
3303768f368SChris Mason goto out;
3310fe29838SDavid Sterba if (ret != 0) {
3320fe29838SDavid Sterba /* The root must exist but we did not find it by the key. */
3330fe29838SDavid Sterba ret = -EUCLEAN;
3340fe29838SDavid Sterba goto out;
3350fe29838SDavid Sterba }
336c5739bbaSChris Mason
3375caf2a00SChris Mason ret = btrfs_del_item(trans, root, path);
3383768f368SChris Mason out:
3395caf2a00SChris Mason btrfs_free_path(path);
3403768f368SChris Mason return ret;
3413768f368SChris Mason }
3420660b5afSChris Mason
btrfs_del_root_ref(struct btrfs_trans_handle * trans,u64 root_id,u64 ref_id,u64 dirid,u64 * sequence,const struct fscrypt_str * name)3433ee1c553SLu Fengqi int btrfs_del_root_ref(struct btrfs_trans_handle *trans, u64 root_id,
344e43eec81SSweet Tea Dorminy u64 ref_id, u64 dirid, u64 *sequence,
3456db75318SSweet Tea Dorminy const struct fscrypt_str *name)
3460660b5afSChris Mason {
3473ee1c553SLu Fengqi struct btrfs_root *tree_root = trans->fs_info->tree_root;
3480660b5afSChris Mason struct btrfs_path *path;
3494df27c4dSYan, Zheng struct btrfs_root_ref *ref;
3504df27c4dSYan, Zheng struct extent_buffer *leaf;
3514df27c4dSYan, Zheng struct btrfs_key key;
3524df27c4dSYan, Zheng unsigned long ptr;
3534df27c4dSYan, Zheng int ret;
3540660b5afSChris Mason
3550660b5afSChris Mason path = btrfs_alloc_path();
3564df27c4dSYan, Zheng if (!path)
3574df27c4dSYan, Zheng return -ENOMEM;
3580660b5afSChris Mason
3590660b5afSChris Mason key.objectid = root_id;
3604df27c4dSYan, Zheng key.type = BTRFS_ROOT_BACKREF_KEY;
3610660b5afSChris Mason key.offset = ref_id;
3624df27c4dSYan, Zheng again:
3630660b5afSChris Mason ret = btrfs_search_slot(trans, tree_root, &key, path, -1, 1);
36447bf225aSFilipe Manana if (ret < 0) {
3658289ed9fSQu Wenruo goto out;
36647bf225aSFilipe Manana } else if (ret == 0) {
3674df27c4dSYan, Zheng leaf = path->nodes[0];
3684df27c4dSYan, Zheng ref = btrfs_item_ptr(leaf, path->slots[0],
3694df27c4dSYan, Zheng struct btrfs_root_ref);
3704df27c4dSYan, Zheng ptr = (unsigned long)(ref + 1);
371423a716cSJosef Bacik if ((btrfs_root_ref_dirid(leaf, ref) != dirid) ||
372e43eec81SSweet Tea Dorminy (btrfs_root_ref_name_len(leaf, ref) != name->len) ||
373e43eec81SSweet Tea Dorminy memcmp_extent_buffer(leaf, name->name, ptr, name->len)) {
3741fdbd03dSFilipe Manana ret = -ENOENT;
375423a716cSJosef Bacik goto out;
376423a716cSJosef Bacik }
3774df27c4dSYan, Zheng *sequence = btrfs_root_ref_sequence(leaf, ref);
3780660b5afSChris Mason
3790660b5afSChris Mason ret = btrfs_del_item(trans, tree_root, path);
3801fdbd03dSFilipe Manana if (ret)
3811fdbd03dSFilipe Manana goto out;
3821fdbd03dSFilipe Manana } else {
3831fdbd03dSFilipe Manana ret = -ENOENT;
38465a246c5STsutomu Itoh goto out;
38565a246c5STsutomu Itoh }
3864df27c4dSYan, Zheng
3874df27c4dSYan, Zheng if (key.type == BTRFS_ROOT_BACKREF_KEY) {
388b3b4aa74SDavid Sterba btrfs_release_path(path);
3894df27c4dSYan, Zheng key.objectid = ref_id;
3904df27c4dSYan, Zheng key.type = BTRFS_ROOT_REF_KEY;
3914df27c4dSYan, Zheng key.offset = root_id;
3924df27c4dSYan, Zheng goto again;
3934df27c4dSYan, Zheng }
3940660b5afSChris Mason
39565a246c5STsutomu Itoh out:
3960660b5afSChris Mason btrfs_free_path(path);
3971fdbd03dSFilipe Manana return ret;
3980660b5afSChris Mason }
3990660b5afSChris Mason
4000660b5afSChris Mason /*
4010660b5afSChris Mason * add a btrfs_root_ref item. type is either BTRFS_ROOT_REF_KEY
4020660b5afSChris Mason * or BTRFS_ROOT_BACKREF_KEY.
4030660b5afSChris Mason *
4040660b5afSChris Mason * The dirid, sequence, name and name_len refer to the directory entry
4050660b5afSChris Mason * that is referencing the root.
4060660b5afSChris Mason *
4070660b5afSChris Mason * For a forward ref, the root_id is the id of the tree referencing
4080660b5afSChris Mason * the root and ref_id is the id of the subvol or snapshot.
4090660b5afSChris Mason *
4100660b5afSChris Mason * For a back ref the root_id is the id of the subvol or snapshot and
4110660b5afSChris Mason * ref_id is the id of the tree referencing it.
41279787eaaSJeff Mahoney *
41379787eaaSJeff Mahoney * Will return 0, -ENOMEM, or anything from the CoW path
4140660b5afSChris Mason */
btrfs_add_root_ref(struct btrfs_trans_handle * trans,u64 root_id,u64 ref_id,u64 dirid,u64 sequence,const struct fscrypt_str * name)4156025c19fSLu Fengqi int btrfs_add_root_ref(struct btrfs_trans_handle *trans, u64 root_id,
416e43eec81SSweet Tea Dorminy u64 ref_id, u64 dirid, u64 sequence,
4176db75318SSweet Tea Dorminy const struct fscrypt_str *name)
4180660b5afSChris Mason {
4196025c19fSLu Fengqi struct btrfs_root *tree_root = trans->fs_info->tree_root;
4200660b5afSChris Mason struct btrfs_key key;
4210660b5afSChris Mason int ret;
4220660b5afSChris Mason struct btrfs_path *path;
4230660b5afSChris Mason struct btrfs_root_ref *ref;
4240660b5afSChris Mason struct extent_buffer *leaf;
4250660b5afSChris Mason unsigned long ptr;
4260660b5afSChris Mason
4270660b5afSChris Mason path = btrfs_alloc_path();
4284df27c4dSYan, Zheng if (!path)
4294df27c4dSYan, Zheng return -ENOMEM;
4300660b5afSChris Mason
4310660b5afSChris Mason key.objectid = root_id;
4324df27c4dSYan, Zheng key.type = BTRFS_ROOT_BACKREF_KEY;
4330660b5afSChris Mason key.offset = ref_id;
4344df27c4dSYan, Zheng again:
4350660b5afSChris Mason ret = btrfs_insert_empty_item(trans, tree_root, path, &key,
436e43eec81SSweet Tea Dorminy sizeof(*ref) + name->len);
43779787eaaSJeff Mahoney if (ret) {
43866642832SJeff Mahoney btrfs_abort_transaction(trans, ret);
43979787eaaSJeff Mahoney btrfs_free_path(path);
44079787eaaSJeff Mahoney return ret;
44179787eaaSJeff Mahoney }
4420660b5afSChris Mason
4430660b5afSChris Mason leaf = path->nodes[0];
4440660b5afSChris Mason ref = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_root_ref);
4450660b5afSChris Mason btrfs_set_root_ref_dirid(leaf, ref, dirid);
4460660b5afSChris Mason btrfs_set_root_ref_sequence(leaf, ref, sequence);
447e43eec81SSweet Tea Dorminy btrfs_set_root_ref_name_len(leaf, ref, name->len);
4480660b5afSChris Mason ptr = (unsigned long)(ref + 1);
449e43eec81SSweet Tea Dorminy write_extent_buffer(leaf, name->name, ptr, name->len);
45050564b65SFilipe Manana btrfs_mark_buffer_dirty(trans, leaf);
4510660b5afSChris Mason
4524df27c4dSYan, Zheng if (key.type == BTRFS_ROOT_BACKREF_KEY) {
453b3b4aa74SDavid Sterba btrfs_release_path(path);
4544df27c4dSYan, Zheng key.objectid = ref_id;
4554df27c4dSYan, Zheng key.type = BTRFS_ROOT_REF_KEY;
4564df27c4dSYan, Zheng key.offset = root_id;
4574df27c4dSYan, Zheng goto again;
4584df27c4dSYan, Zheng }
4594df27c4dSYan, Zheng
4600660b5afSChris Mason btrfs_free_path(path);
4614df27c4dSYan, Zheng return 0;
4620660b5afSChris Mason }
46308fe4db1SLi Zefan
46408fe4db1SLi Zefan /*
46508fe4db1SLi Zefan * Old btrfs forgets to init root_item->flags and root_item->byte_limit
46608fe4db1SLi Zefan * for subvolumes. To work around this problem, we steal a bit from
46708fe4db1SLi Zefan * root_item->inode_item->flags, and use it to indicate if those fields
46808fe4db1SLi Zefan * have been properly initialized.
46908fe4db1SLi Zefan */
btrfs_check_and_init_root_item(struct btrfs_root_item * root_item)47008fe4db1SLi Zefan void btrfs_check_and_init_root_item(struct btrfs_root_item *root_item)
47108fe4db1SLi Zefan {
4723cae210fSQu Wenruo u64 inode_flags = btrfs_stack_inode_flags(&root_item->inode);
47308fe4db1SLi Zefan
47408fe4db1SLi Zefan if (!(inode_flags & BTRFS_INODE_ROOT_ITEM_INIT)) {
47508fe4db1SLi Zefan inode_flags |= BTRFS_INODE_ROOT_ITEM_INIT;
4763cae210fSQu Wenruo btrfs_set_stack_inode_flags(&root_item->inode, inode_flags);
4773cae210fSQu Wenruo btrfs_set_root_flags(root_item, 0);
4783cae210fSQu Wenruo btrfs_set_root_limit(root_item, 0);
47908fe4db1SLi Zefan }
48008fe4db1SLi Zefan }
4818ea05e3aSAlexander Block
btrfs_update_root_times(struct btrfs_trans_handle * trans,struct btrfs_root * root)4828ea05e3aSAlexander Block void btrfs_update_root_times(struct btrfs_trans_handle *trans,
4838ea05e3aSAlexander Block struct btrfs_root *root)
4848ea05e3aSAlexander Block {
4858ea05e3aSAlexander Block struct btrfs_root_item *item = &root->root_item;
48695582b00SDeepa Dinamani struct timespec64 ct;
4878ea05e3aSAlexander Block
48895582b00SDeepa Dinamani ktime_get_real_ts64(&ct);
4895f3ab90aSAnand Jain spin_lock(&root->root_item_lock);
4903cae210fSQu Wenruo btrfs_set_root_ctransid(item, trans->transid);
4913cae210fSQu Wenruo btrfs_set_stack_timespec_sec(&item->ctime, ct.tv_sec);
4923cae210fSQu Wenruo btrfs_set_stack_timespec_nsec(&item->ctime, ct.tv_nsec);
4935f3ab90aSAnand Jain spin_unlock(&root->root_item_lock);
4948ea05e3aSAlexander Block }
49528a32d2bSJosef Bacik
49628a32d2bSJosef Bacik /*
4979580503bSDavid Sterba * Reserve space for subvolume operation.
4989580503bSDavid Sterba *
49928a32d2bSJosef Bacik * root: the root of the parent directory
50028a32d2bSJosef Bacik * rsv: block reservation
50128a32d2bSJosef Bacik * items: the number of items that we need do reservation
50228a32d2bSJosef Bacik * use_global_rsv: allow fallback to the global block reservation
50328a32d2bSJosef Bacik *
50428a32d2bSJosef Bacik * This function is used to reserve the space for snapshot/subvolume
50528a32d2bSJosef Bacik * creation and deletion. Those operations are different with the
50628a32d2bSJosef Bacik * common file/directory operations, they change two fs/file trees
50728a32d2bSJosef Bacik * and root tree, the number of items that the qgroup reserves is
50828a32d2bSJosef Bacik * different with the free space reservation. So we can not use
50928a32d2bSJosef Bacik * the space reservation mechanism in start_transaction().
51028a32d2bSJosef Bacik */
btrfs_subvolume_reserve_metadata(struct btrfs_root * root,struct btrfs_block_rsv * rsv,int items,bool use_global_rsv)51128a32d2bSJosef Bacik int btrfs_subvolume_reserve_metadata(struct btrfs_root *root,
51228a32d2bSJosef Bacik struct btrfs_block_rsv *rsv, int items,
51328a32d2bSJosef Bacik bool use_global_rsv)
51428a32d2bSJosef Bacik {
51528a32d2bSJosef Bacik u64 qgroup_num_bytes = 0;
51628a32d2bSJosef Bacik u64 num_bytes;
51728a32d2bSJosef Bacik int ret;
51828a32d2bSJosef Bacik struct btrfs_fs_info *fs_info = root->fs_info;
51928a32d2bSJosef Bacik struct btrfs_block_rsv *global_rsv = &fs_info->global_block_rsv;
52028a32d2bSJosef Bacik
521182940f4SBoris Burkov if (btrfs_qgroup_enabled(fs_info)) {
52228a32d2bSJosef Bacik /* One for parent inode, two for dir entries */
52328a32d2bSJosef Bacik qgroup_num_bytes = 3 * fs_info->nodesize;
52428a32d2bSJosef Bacik ret = btrfs_qgroup_reserve_meta_prealloc(root,
525d4135134SFilipe Manana qgroup_num_bytes, true,
526d4135134SFilipe Manana false);
52728a32d2bSJosef Bacik if (ret)
52828a32d2bSJosef Bacik return ret;
52928a32d2bSJosef Bacik }
53028a32d2bSJosef Bacik
5312bd36e7bSJosef Bacik num_bytes = btrfs_calc_insert_metadata_size(fs_info, items);
53228a32d2bSJosef Bacik rsv->space_info = btrfs_find_space_info(fs_info,
53328a32d2bSJosef Bacik BTRFS_BLOCK_GROUP_METADATA);
5349270501cSJosef Bacik ret = btrfs_block_rsv_add(fs_info, rsv, num_bytes,
53528a32d2bSJosef Bacik BTRFS_RESERVE_FLUSH_ALL);
53628a32d2bSJosef Bacik
53728a32d2bSJosef Bacik if (ret == -ENOSPC && use_global_rsv)
53828a32d2bSJosef Bacik ret = btrfs_block_rsv_migrate(global_rsv, rsv, num_bytes, true);
53928a32d2bSJosef Bacik
54028a32d2bSJosef Bacik if (ret && qgroup_num_bytes)
54128a32d2bSJosef Bacik btrfs_qgroup_free_meta_prealloc(root, qgroup_num_bytes);
54228a32d2bSJosef Bacik
543e85fde51SQu Wenruo if (!ret) {
544e85fde51SQu Wenruo spin_lock(&rsv->lock);
545e85fde51SQu Wenruo rsv->qgroup_rsv_reserved += qgroup_num_bytes;
546e85fde51SQu Wenruo spin_unlock(&rsv->lock);
547e85fde51SQu Wenruo }
54828a32d2bSJosef Bacik return ret;
54928a32d2bSJosef Bacik }
550