root-tree.c revision db5b493ac78e46c7b6bad22cd25d8041564cd8ea
16cbd55707802b98843f953d1ae6d8f5bcd9a76c0Chris Mason/*
26cbd55707802b98843f953d1ae6d8f5bcd9a76c0Chris Mason * Copyright (C) 2007 Oracle.  All rights reserved.
36cbd55707802b98843f953d1ae6d8f5bcd9a76c0Chris Mason *
46cbd55707802b98843f953d1ae6d8f5bcd9a76c0Chris Mason * This program is free software; you can redistribute it and/or
56cbd55707802b98843f953d1ae6d8f5bcd9a76c0Chris Mason * modify it under the terms of the GNU General Public
66cbd55707802b98843f953d1ae6d8f5bcd9a76c0Chris Mason * License v2 as published by the Free Software Foundation.
76cbd55707802b98843f953d1ae6d8f5bcd9a76c0Chris Mason *
86cbd55707802b98843f953d1ae6d8f5bcd9a76c0Chris Mason * This program is distributed in the hope that it will be useful,
96cbd55707802b98843f953d1ae6d8f5bcd9a76c0Chris Mason * but WITHOUT ANY WARRANTY; without even the implied warranty of
106cbd55707802b98843f953d1ae6d8f5bcd9a76c0Chris Mason * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
116cbd55707802b98843f953d1ae6d8f5bcd9a76c0Chris Mason * General Public License for more details.
126cbd55707802b98843f953d1ae6d8f5bcd9a76c0Chris Mason *
136cbd55707802b98843f953d1ae6d8f5bcd9a76c0Chris Mason * You should have received a copy of the GNU General Public
146cbd55707802b98843f953d1ae6d8f5bcd9a76c0Chris Mason * License along with this program; if not, write to the
156cbd55707802b98843f953d1ae6d8f5bcd9a76c0Chris Mason * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
166cbd55707802b98843f953d1ae6d8f5bcd9a76c0Chris Mason * Boston, MA 021110-1307, USA.
176cbd55707802b98843f953d1ae6d8f5bcd9a76c0Chris Mason */
186cbd55707802b98843f953d1ae6d8f5bcd9a76c0Chris Mason
193768f3689fc76ecea17414936dff7a02746a4355Chris Mason#include "ctree.h"
205eda7b5e9b0bed864dd18284c7df9b3c8207dad7Chris Mason#include "transaction.h"
213768f3689fc76ecea17414936dff7a02746a4355Chris Mason#include "disk-io.h"
223768f3689fc76ecea17414936dff7a02746a4355Chris Mason#include "print-tree.h"
233768f3689fc76ecea17414936dff7a02746a4355Chris Mason
24bf4ef67924d87b0addb32f084e83a9283496350eChris Mason/*
25d352ac68148b69937d39ca5d48bcc4478e118dbfChris Mason *  search forward for a root, starting with objectid 'search_start'
26d352ac68148b69937d39ca5d48bcc4478e118dbfChris Mason *  if a root key is found, the objectid we find is filled into 'found_objectid'
27d352ac68148b69937d39ca5d48bcc4478e118dbfChris Mason *  and 0 is returned.  < 0 is returned on error, 1 if there is nothing
28d352ac68148b69937d39ca5d48bcc4478e118dbfChris Mason *  left in the tree.
29bf4ef67924d87b0addb32f084e83a9283496350eChris Mason */
30bf4ef67924d87b0addb32f084e83a9283496350eChris Masonint btrfs_search_root(struct btrfs_root *root, u64 search_start,
31bf4ef67924d87b0addb32f084e83a9283496350eChris Mason		      u64 *found_objectid)
32bf4ef67924d87b0addb32f084e83a9283496350eChris Mason{
33bf4ef67924d87b0addb32f084e83a9283496350eChris Mason	struct btrfs_path *path;
34bf4ef67924d87b0addb32f084e83a9283496350eChris Mason	struct btrfs_key search_key;
35bf4ef67924d87b0addb32f084e83a9283496350eChris Mason	int ret;
36bf4ef67924d87b0addb32f084e83a9283496350eChris Mason
37bf4ef67924d87b0addb32f084e83a9283496350eChris Mason	root = root->fs_info->tree_root;
38bf4ef67924d87b0addb32f084e83a9283496350eChris Mason	search_key.objectid = search_start;
39bf4ef67924d87b0addb32f084e83a9283496350eChris Mason	search_key.type = (u8)-1;
40bf4ef67924d87b0addb32f084e83a9283496350eChris Mason	search_key.offset = (u64)-1;
41bf4ef67924d87b0addb32f084e83a9283496350eChris Mason
42bf4ef67924d87b0addb32f084e83a9283496350eChris Mason	path = btrfs_alloc_path();
43bf4ef67924d87b0addb32f084e83a9283496350eChris Mason	BUG_ON(!path);
44bf4ef67924d87b0addb32f084e83a9283496350eChris Masonagain:
45bf4ef67924d87b0addb32f084e83a9283496350eChris Mason	ret = btrfs_search_slot(NULL, root, &search_key, path, 0, 0);
46bf4ef67924d87b0addb32f084e83a9283496350eChris Mason	if (ret < 0)
47bf4ef67924d87b0addb32f084e83a9283496350eChris Mason		goto out;
48bf4ef67924d87b0addb32f084e83a9283496350eChris Mason	if (ret == 0) {
49bf4ef67924d87b0addb32f084e83a9283496350eChris Mason		ret = 1;
50bf4ef67924d87b0addb32f084e83a9283496350eChris Mason		goto out;
51bf4ef67924d87b0addb32f084e83a9283496350eChris Mason	}
52bf4ef67924d87b0addb32f084e83a9283496350eChris Mason	if (path->slots[0] >= btrfs_header_nritems(path->nodes[0])) {
53bf4ef67924d87b0addb32f084e83a9283496350eChris Mason		ret = btrfs_next_leaf(root, path);
54bf4ef67924d87b0addb32f084e83a9283496350eChris Mason		if (ret)
55bf4ef67924d87b0addb32f084e83a9283496350eChris Mason			goto out;
56bf4ef67924d87b0addb32f084e83a9283496350eChris Mason	}
57bf4ef67924d87b0addb32f084e83a9283496350eChris Mason	btrfs_item_key_to_cpu(path->nodes[0], &search_key, path->slots[0]);
58bf4ef67924d87b0addb32f084e83a9283496350eChris Mason	if (search_key.type != BTRFS_ROOT_ITEM_KEY) {
59bf4ef67924d87b0addb32f084e83a9283496350eChris Mason		search_key.offset++;
60bf4ef67924d87b0addb32f084e83a9283496350eChris Mason		btrfs_release_path(root, path);
61bf4ef67924d87b0addb32f084e83a9283496350eChris Mason		goto again;
62bf4ef67924d87b0addb32f084e83a9283496350eChris Mason	}
63bf4ef67924d87b0addb32f084e83a9283496350eChris Mason	ret = 0;
64bf4ef67924d87b0addb32f084e83a9283496350eChris Mason	*found_objectid = search_key.objectid;
65bf4ef67924d87b0addb32f084e83a9283496350eChris Mason
66bf4ef67924d87b0addb32f084e83a9283496350eChris Masonout:
67bf4ef67924d87b0addb32f084e83a9283496350eChris Mason	btrfs_free_path(path);
68bf4ef67924d87b0addb32f084e83a9283496350eChris Mason	return ret;
69bf4ef67924d87b0addb32f084e83a9283496350eChris Mason}
70bf4ef67924d87b0addb32f084e83a9283496350eChris Mason
71d352ac68148b69937d39ca5d48bcc4478e118dbfChris Mason/*
72d352ac68148b69937d39ca5d48bcc4478e118dbfChris Mason * lookup the root with the highest offset for a given objectid.  The key we do
73d352ac68148b69937d39ca5d48bcc4478e118dbfChris Mason * find is copied into 'key'.  If we find something return 0, otherwise 1, < 0
74d352ac68148b69937d39ca5d48bcc4478e118dbfChris Mason * on error.
75d352ac68148b69937d39ca5d48bcc4478e118dbfChris Mason */
763768f3689fc76ecea17414936dff7a02746a4355Chris Masonint btrfs_find_last_root(struct btrfs_root *root, u64 objectid,
773768f3689fc76ecea17414936dff7a02746a4355Chris Mason			struct btrfs_root_item *item, struct btrfs_key *key)
783768f3689fc76ecea17414936dff7a02746a4355Chris Mason{
795caf2a002901f0fde475371c4bf1c553b51884afChris Mason	struct btrfs_path *path;
803768f3689fc76ecea17414936dff7a02746a4355Chris Mason	struct btrfs_key search_key;
815f39d397dfbe140a14edecd4e73c34ce23c4f9eeChris Mason	struct btrfs_key found_key;
825f39d397dfbe140a14edecd4e73c34ce23c4f9eeChris Mason	struct extent_buffer *l;
833768f3689fc76ecea17414936dff7a02746a4355Chris Mason	int ret;
843768f3689fc76ecea17414936dff7a02746a4355Chris Mason	int slot;
853768f3689fc76ecea17414936dff7a02746a4355Chris Mason
863768f3689fc76ecea17414936dff7a02746a4355Chris Mason	search_key.objectid = objectid;
870660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason	search_key.type = BTRFS_ROOT_ITEM_KEY;
885eda7b5e9b0bed864dd18284c7df9b3c8207dad7Chris Mason	search_key.offset = (u64)-1;
893768f3689fc76ecea17414936dff7a02746a4355Chris Mason
905caf2a002901f0fde475371c4bf1c553b51884afChris Mason	path = btrfs_alloc_path();
91db5b493ac78e46c7b6bad22cd25d8041564cd8eaTsutomu Itoh	if (!path)
92db5b493ac78e46c7b6bad22cd25d8041564cd8eaTsutomu Itoh		return -ENOMEM;
935caf2a002901f0fde475371c4bf1c553b51884afChris Mason	ret = btrfs_search_slot(NULL, root, &search_key, path, 0, 0);
943768f3689fc76ecea17414936dff7a02746a4355Chris Mason	if (ret < 0)
953768f3689fc76ecea17414936dff7a02746a4355Chris Mason		goto out;
965f39d397dfbe140a14edecd4e73c34ce23c4f9eeChris Mason
973768f3689fc76ecea17414936dff7a02746a4355Chris Mason	BUG_ON(ret == 0);
9876dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng	if (path->slots[0] == 0) {
9976dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng		ret = 1;
10076dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng		goto out;
10176dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng	}
1025f39d397dfbe140a14edecd4e73c34ce23c4f9eeChris Mason	l = path->nodes[0];
1035caf2a002901f0fde475371c4bf1c553b51884afChris Mason	slot = path->slots[0] - 1;
1045f39d397dfbe140a14edecd4e73c34ce23c4f9eeChris Mason	btrfs_item_key_to_cpu(l, &found_key, slot);
10576dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng	if (found_key.objectid != objectid ||
10676dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng	    found_key.type != BTRFS_ROOT_ITEM_KEY) {
1073768f3689fc76ecea17414936dff7a02746a4355Chris Mason		ret = 1;
1083768f3689fc76ecea17414936dff7a02746a4355Chris Mason		goto out;
1093768f3689fc76ecea17414936dff7a02746a4355Chris Mason	}
11076dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng	if (item)
11176dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng		read_extent_buffer(l, item, btrfs_item_ptr_offset(l, slot),
11276dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng				   sizeof(*item));
11376dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng	if (key)
11476dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng		memcpy(key, &found_key, sizeof(found_key));
1153768f3689fc76ecea17414936dff7a02746a4355Chris Mason	ret = 0;
1163768f3689fc76ecea17414936dff7a02746a4355Chris Masonout:
1175caf2a002901f0fde475371c4bf1c553b51884afChris Mason	btrfs_free_path(path);
1183768f3689fc76ecea17414936dff7a02746a4355Chris Mason	return ret;
1193768f3689fc76ecea17414936dff7a02746a4355Chris Mason}
1203768f3689fc76ecea17414936dff7a02746a4355Chris Mason
1215d4f98a28c7d334091c1b7744f48a1acdd2a4ae0Yan Zhengint btrfs_set_root_node(struct btrfs_root_item *item,
1225d4f98a28c7d334091c1b7744f48a1acdd2a4ae0Yan Zheng			struct extent_buffer *node)
1235d4f98a28c7d334091c1b7744f48a1acdd2a4ae0Yan Zheng{
1245d4f98a28c7d334091c1b7744f48a1acdd2a4ae0Yan Zheng	btrfs_set_root_bytenr(item, node->start);
1255d4f98a28c7d334091c1b7744f48a1acdd2a4ae0Yan Zheng	btrfs_set_root_level(item, btrfs_header_level(node));
1265d4f98a28c7d334091c1b7744f48a1acdd2a4ae0Yan Zheng	btrfs_set_root_generation(item, btrfs_header_generation(node));
1275d4f98a28c7d334091c1b7744f48a1acdd2a4ae0Yan Zheng	return 0;
1285d4f98a28c7d334091c1b7744f48a1acdd2a4ae0Yan Zheng}
1295d4f98a28c7d334091c1b7744f48a1acdd2a4ae0Yan Zheng
130d352ac68148b69937d39ca5d48bcc4478e118dbfChris Mason/*
131d352ac68148b69937d39ca5d48bcc4478e118dbfChris Mason * copy the data in 'item' into the btree
132d352ac68148b69937d39ca5d48bcc4478e118dbfChris Mason */
133e089f05c18ab36ed5fa7e2319052e03ab800d518Chris Masonint btrfs_update_root(struct btrfs_trans_handle *trans, struct btrfs_root
134e089f05c18ab36ed5fa7e2319052e03ab800d518Chris Mason		      *root, struct btrfs_key *key, struct btrfs_root_item
135e089f05c18ab36ed5fa7e2319052e03ab800d518Chris Mason		      *item)
1363768f3689fc76ecea17414936dff7a02746a4355Chris Mason{
1375caf2a002901f0fde475371c4bf1c553b51884afChris Mason	struct btrfs_path *path;
1385f39d397dfbe140a14edecd4e73c34ce23c4f9eeChris Mason	struct extent_buffer *l;
1393768f3689fc76ecea17414936dff7a02746a4355Chris Mason	int ret;
1403768f3689fc76ecea17414936dff7a02746a4355Chris Mason	int slot;
1415f39d397dfbe140a14edecd4e73c34ce23c4f9eeChris Mason	unsigned long ptr;
1423768f3689fc76ecea17414936dff7a02746a4355Chris Mason
1435caf2a002901f0fde475371c4bf1c553b51884afChris Mason	path = btrfs_alloc_path();
1445caf2a002901f0fde475371c4bf1c553b51884afChris Mason	BUG_ON(!path);
1455caf2a002901f0fde475371c4bf1c553b51884afChris Mason	ret = btrfs_search_slot(trans, root, key, path, 0, 1);
1463768f3689fc76ecea17414936dff7a02746a4355Chris Mason	if (ret < 0)
1473768f3689fc76ecea17414936dff7a02746a4355Chris Mason		goto out;
148d666746207a01546e55bdaa4b721d1890faaf6e8Chris Mason
149d666746207a01546e55bdaa4b721d1890faaf6e8Chris Mason	if (ret != 0) {
150d666746207a01546e55bdaa4b721d1890faaf6e8Chris Mason		btrfs_print_leaf(root, path->nodes[0]);
151d397712bcc6a759a560fd247e6053ecae091f958Chris Mason		printk(KERN_CRIT "unable to update root key %llu %u %llu\n",
152d397712bcc6a759a560fd247e6053ecae091f958Chris Mason		       (unsigned long long)key->objectid, key->type,
153d397712bcc6a759a560fd247e6053ecae091f958Chris Mason		       (unsigned long long)key->offset);
154d666746207a01546e55bdaa4b721d1890faaf6e8Chris Mason		BUG_ON(1);
155d666746207a01546e55bdaa4b721d1890faaf6e8Chris Mason	}
156d666746207a01546e55bdaa4b721d1890faaf6e8Chris Mason
1575f39d397dfbe140a14edecd4e73c34ce23c4f9eeChris Mason	l = path->nodes[0];
1585caf2a002901f0fde475371c4bf1c553b51884afChris Mason	slot = path->slots[0];
1595f39d397dfbe140a14edecd4e73c34ce23c4f9eeChris Mason	ptr = btrfs_item_ptr_offset(l, slot);
1605f39d397dfbe140a14edecd4e73c34ce23c4f9eeChris Mason	write_extent_buffer(l, item, ptr, sizeof(*item));
1615caf2a002901f0fde475371c4bf1c553b51884afChris Mason	btrfs_mark_buffer_dirty(path->nodes[0]);
1623768f3689fc76ecea17414936dff7a02746a4355Chris Masonout:
1635caf2a002901f0fde475371c4bf1c553b51884afChris Mason	btrfs_free_path(path);
1643768f3689fc76ecea17414936dff7a02746a4355Chris Mason	return ret;
1653768f3689fc76ecea17414936dff7a02746a4355Chris Mason}
1663768f3689fc76ecea17414936dff7a02746a4355Chris Mason
167e089f05c18ab36ed5fa7e2319052e03ab800d518Chris Masonint btrfs_insert_root(struct btrfs_trans_handle *trans, struct btrfs_root
168e089f05c18ab36ed5fa7e2319052e03ab800d518Chris Mason		      *root, struct btrfs_key *key, struct btrfs_root_item
169e089f05c18ab36ed5fa7e2319052e03ab800d518Chris Mason		      *item)
1703768f3689fc76ecea17414936dff7a02746a4355Chris Mason{
1713768f3689fc76ecea17414936dff7a02746a4355Chris Mason	int ret;
172e089f05c18ab36ed5fa7e2319052e03ab800d518Chris Mason	ret = btrfs_insert_item(trans, root, key, item, sizeof(*item));
1733768f3689fc76ecea17414936dff7a02746a4355Chris Mason	return ret;
1743768f3689fc76ecea17414936dff7a02746a4355Chris Mason}
1753768f3689fc76ecea17414936dff7a02746a4355Chris Mason
176d352ac68148b69937d39ca5d48bcc4478e118dbfChris Mason/*
177d352ac68148b69937d39ca5d48bcc4478e118dbfChris Mason * at mount time we want to find all the old transaction snapshots that were in
178d397712bcc6a759a560fd247e6053ecae091f958Chris Mason * the process of being deleted if we crashed.  This is any root item with an
179d397712bcc6a759a560fd247e6053ecae091f958Chris Mason * offset lower than the latest root.  They need to be queued for deletion to
180d397712bcc6a759a560fd247e6053ecae091f958Chris Mason * finish what was happening when we crashed.
181d352ac68148b69937d39ca5d48bcc4478e118dbfChris Mason */
1825d4f98a28c7d334091c1b7744f48a1acdd2a4ae0Yan Zhengint btrfs_find_dead_roots(struct btrfs_root *root, u64 objectid)
1835eda7b5e9b0bed864dd18284c7df9b3c8207dad7Chris Mason{
1845eda7b5e9b0bed864dd18284c7df9b3c8207dad7Chris Mason	struct btrfs_root *dead_root;
1855eda7b5e9b0bed864dd18284c7df9b3c8207dad7Chris Mason	struct btrfs_root_item *ri;
1865eda7b5e9b0bed864dd18284c7df9b3c8207dad7Chris Mason	struct btrfs_key key;
187a7a16fd772620605c76e8ac8bdbc8ccc9e3df1a0Chris Mason	struct btrfs_key found_key;
1885eda7b5e9b0bed864dd18284c7df9b3c8207dad7Chris Mason	struct btrfs_path *path;
1895eda7b5e9b0bed864dd18284c7df9b3c8207dad7Chris Mason	int ret;
1905eda7b5e9b0bed864dd18284c7df9b3c8207dad7Chris Mason	u32 nritems;
1915f39d397dfbe140a14edecd4e73c34ce23c4f9eeChris Mason	struct extent_buffer *leaf;
1925eda7b5e9b0bed864dd18284c7df9b3c8207dad7Chris Mason	int slot;
1935eda7b5e9b0bed864dd18284c7df9b3c8207dad7Chris Mason
1945ce14bbcdd1b5d9233d26a1e89faf3a26c820c58Chris Mason	key.objectid = objectid;
1955eda7b5e9b0bed864dd18284c7df9b3c8207dad7Chris Mason	btrfs_set_key_type(&key, BTRFS_ROOT_ITEM_KEY);
1965eda7b5e9b0bed864dd18284c7df9b3c8207dad7Chris Mason	key.offset = 0;
1975eda7b5e9b0bed864dd18284c7df9b3c8207dad7Chris Mason	path = btrfs_alloc_path();
1985eda7b5e9b0bed864dd18284c7df9b3c8207dad7Chris Mason	if (!path)
1995eda7b5e9b0bed864dd18284c7df9b3c8207dad7Chris Mason		return -ENOMEM;
200a7a16fd772620605c76e8ac8bdbc8ccc9e3df1a0Chris Mason
201a7a16fd772620605c76e8ac8bdbc8ccc9e3df1a0Chris Masonagain:
2025eda7b5e9b0bed864dd18284c7df9b3c8207dad7Chris Mason	ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
2035eda7b5e9b0bed864dd18284c7df9b3c8207dad7Chris Mason	if (ret < 0)
2045eda7b5e9b0bed864dd18284c7df9b3c8207dad7Chris Mason		goto err;
205d397712bcc6a759a560fd247e6053ecae091f958Chris Mason	while (1) {
2065f39d397dfbe140a14edecd4e73c34ce23c4f9eeChris Mason		leaf = path->nodes[0];
2075f39d397dfbe140a14edecd4e73c34ce23c4f9eeChris Mason		nritems = btrfs_header_nritems(leaf);
2085eda7b5e9b0bed864dd18284c7df9b3c8207dad7Chris Mason		slot = path->slots[0];
2095eda7b5e9b0bed864dd18284c7df9b3c8207dad7Chris Mason		if (slot >= nritems) {
2105eda7b5e9b0bed864dd18284c7df9b3c8207dad7Chris Mason			ret = btrfs_next_leaf(root, path);
2115eda7b5e9b0bed864dd18284c7df9b3c8207dad7Chris Mason			if (ret)
2125eda7b5e9b0bed864dd18284c7df9b3c8207dad7Chris Mason				break;
2135f39d397dfbe140a14edecd4e73c34ce23c4f9eeChris Mason			leaf = path->nodes[0];
2145f39d397dfbe140a14edecd4e73c34ce23c4f9eeChris Mason			nritems = btrfs_header_nritems(leaf);
2155eda7b5e9b0bed864dd18284c7df9b3c8207dad7Chris Mason			slot = path->slots[0];
2165eda7b5e9b0bed864dd18284c7df9b3c8207dad7Chris Mason		}
2175f39d397dfbe140a14edecd4e73c34ce23c4f9eeChris Mason		btrfs_item_key_to_cpu(leaf, &key, slot);
2185eda7b5e9b0bed864dd18284c7df9b3c8207dad7Chris Mason		if (btrfs_key_type(&key) != BTRFS_ROOT_ITEM_KEY)
2195eda7b5e9b0bed864dd18284c7df9b3c8207dad7Chris Mason			goto next;
2205ce14bbcdd1b5d9233d26a1e89faf3a26c820c58Chris Mason
2215ce14bbcdd1b5d9233d26a1e89faf3a26c820c58Chris Mason		if (key.objectid < objectid)
2225ce14bbcdd1b5d9233d26a1e89faf3a26c820c58Chris Mason			goto next;
2235ce14bbcdd1b5d9233d26a1e89faf3a26c820c58Chris Mason
2245ce14bbcdd1b5d9233d26a1e89faf3a26c820c58Chris Mason		if (key.objectid > objectid)
2255ce14bbcdd1b5d9233d26a1e89faf3a26c820c58Chris Mason			break;
2265ce14bbcdd1b5d9233d26a1e89faf3a26c820c58Chris Mason
2275eda7b5e9b0bed864dd18284c7df9b3c8207dad7Chris Mason		ri = btrfs_item_ptr(leaf, slot, struct btrfs_root_item);
2285f39d397dfbe140a14edecd4e73c34ce23c4f9eeChris Mason		if (btrfs_disk_root_refs(leaf, ri) != 0)
2295eda7b5e9b0bed864dd18284c7df9b3c8207dad7Chris Mason			goto next;
2305ce14bbcdd1b5d9233d26a1e89faf3a26c820c58Chris Mason
231a7a16fd772620605c76e8ac8bdbc8ccc9e3df1a0Chris Mason		memcpy(&found_key, &key, sizeof(key));
232a7a16fd772620605c76e8ac8bdbc8ccc9e3df1a0Chris Mason		key.offset++;
233a7a16fd772620605c76e8ac8bdbc8ccc9e3df1a0Chris Mason		btrfs_release_path(root, path);
234e02119d5a7b4396c5a872582fddc8bd6d305a70aChris Mason		dead_root =
235e02119d5a7b4396c5a872582fddc8bd6d305a70aChris Mason			btrfs_read_fs_root_no_radix(root->fs_info->tree_root,
236e02119d5a7b4396c5a872582fddc8bd6d305a70aChris Mason						    &found_key);
237a1f396304fb7e5f18e4ea81c294415375f1c814cAneesh		if (IS_ERR(dead_root)) {
238a1f396304fb7e5f18e4ea81c294415375f1c814cAneesh			ret = PTR_ERR(dead_root);
2395eda7b5e9b0bed864dd18284c7df9b3c8207dad7Chris Mason			goto err;
2405eda7b5e9b0bed864dd18284c7df9b3c8207dad7Chris Mason		}
2415ce14bbcdd1b5d9233d26a1e89faf3a26c820c58Chris Mason
2425d4f98a28c7d334091c1b7744f48a1acdd2a4ae0Yan Zheng		ret = btrfs_add_dead_root(dead_root);
2435eda7b5e9b0bed864dd18284c7df9b3c8207dad7Chris Mason		if (ret)
2445eda7b5e9b0bed864dd18284c7df9b3c8207dad7Chris Mason			goto err;
245a7a16fd772620605c76e8ac8bdbc8ccc9e3df1a0Chris Mason		goto again;
2465eda7b5e9b0bed864dd18284c7df9b3c8207dad7Chris Masonnext:
2475eda7b5e9b0bed864dd18284c7df9b3c8207dad7Chris Mason		slot++;
2485eda7b5e9b0bed864dd18284c7df9b3c8207dad7Chris Mason		path->slots[0]++;
2495eda7b5e9b0bed864dd18284c7df9b3c8207dad7Chris Mason	}
2505eda7b5e9b0bed864dd18284c7df9b3c8207dad7Chris Mason	ret = 0;
2515eda7b5e9b0bed864dd18284c7df9b3c8207dad7Chris Masonerr:
2525eda7b5e9b0bed864dd18284c7df9b3c8207dad7Chris Mason	btrfs_free_path(path);
2535eda7b5e9b0bed864dd18284c7df9b3c8207dad7Chris Mason	return ret;
2545eda7b5e9b0bed864dd18284c7df9b3c8207dad7Chris Mason}
2555eda7b5e9b0bed864dd18284c7df9b3c8207dad7Chris Mason
25676dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zhengint btrfs_find_orphan_roots(struct btrfs_root *tree_root)
25776dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng{
25876dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng	struct extent_buffer *leaf;
25976dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng	struct btrfs_path *path;
26076dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng	struct btrfs_key key;
261d68fc57b7e3245cfacf2e3b47acfed1946a11786Yan, Zheng	struct btrfs_key root_key;
262d68fc57b7e3245cfacf2e3b47acfed1946a11786Yan, Zheng	struct btrfs_root *root;
26376dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng	int err = 0;
26476dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng	int ret;
26576dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng
26676dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng	path = btrfs_alloc_path();
26776dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng	if (!path)
26876dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng		return -ENOMEM;
26976dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng
27076dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng	key.objectid = BTRFS_ORPHAN_OBJECTID;
27176dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng	key.type = BTRFS_ORPHAN_ITEM_KEY;
27276dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng	key.offset = 0;
27376dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng
274d68fc57b7e3245cfacf2e3b47acfed1946a11786Yan, Zheng	root_key.type = BTRFS_ROOT_ITEM_KEY;
275d68fc57b7e3245cfacf2e3b47acfed1946a11786Yan, Zheng	root_key.offset = (u64)-1;
276d68fc57b7e3245cfacf2e3b47acfed1946a11786Yan, Zheng
27776dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng	while (1) {
27876dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng		ret = btrfs_search_slot(NULL, tree_root, &key, path, 0, 0);
27976dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng		if (ret < 0) {
28076dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng			err = ret;
28176dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng			break;
28276dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng		}
28376dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng
28476dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng		leaf = path->nodes[0];
28576dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng		if (path->slots[0] >= btrfs_header_nritems(leaf)) {
28676dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng			ret = btrfs_next_leaf(tree_root, path);
28776dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng			if (ret < 0)
28876dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng				err = ret;
28976dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng			if (ret != 0)
29076dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng				break;
29176dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng			leaf = path->nodes[0];
29276dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng		}
29376dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng
29476dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng		btrfs_item_key_to_cpu(leaf, &key, path->slots[0]);
29576dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng		btrfs_release_path(tree_root, path);
29676dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng
29776dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng		if (key.objectid != BTRFS_ORPHAN_OBJECTID ||
29876dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng		    key.type != BTRFS_ORPHAN_ITEM_KEY)
29976dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng			break;
30076dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng
301d68fc57b7e3245cfacf2e3b47acfed1946a11786Yan, Zheng		root_key.objectid = key.offset;
302d68fc57b7e3245cfacf2e3b47acfed1946a11786Yan, Zheng		key.offset++;
303d68fc57b7e3245cfacf2e3b47acfed1946a11786Yan, Zheng
304d68fc57b7e3245cfacf2e3b47acfed1946a11786Yan, Zheng		root = btrfs_read_fs_root_no_name(tree_root->fs_info,
305d68fc57b7e3245cfacf2e3b47acfed1946a11786Yan, Zheng						  &root_key);
306d68fc57b7e3245cfacf2e3b47acfed1946a11786Yan, Zheng		if (!IS_ERR(root))
307d68fc57b7e3245cfacf2e3b47acfed1946a11786Yan, Zheng			continue;
308d68fc57b7e3245cfacf2e3b47acfed1946a11786Yan, Zheng
309d68fc57b7e3245cfacf2e3b47acfed1946a11786Yan, Zheng		ret = PTR_ERR(root);
310d68fc57b7e3245cfacf2e3b47acfed1946a11786Yan, Zheng		if (ret != -ENOENT) {
31176dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng			err = ret;
31276dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng			break;
31376dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng		}
31476dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng
315d68fc57b7e3245cfacf2e3b47acfed1946a11786Yan, Zheng		ret = btrfs_find_dead_roots(tree_root, root_key.objectid);
316d68fc57b7e3245cfacf2e3b47acfed1946a11786Yan, Zheng		if (ret) {
317d68fc57b7e3245cfacf2e3b47acfed1946a11786Yan, Zheng			err = ret;
318d68fc57b7e3245cfacf2e3b47acfed1946a11786Yan, Zheng			break;
319d68fc57b7e3245cfacf2e3b47acfed1946a11786Yan, Zheng		}
32076dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng	}
32176dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng
32276dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng	btrfs_free_path(path);
32376dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng	return err;
32476dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng}
32576dda93c6ae2c1dc3e6cde34569d6aca26b0c918Yan, Zheng
326d352ac68148b69937d39ca5d48bcc4478e118dbfChris Mason/* drop the root item for 'key' from 'root' */
327e089f05c18ab36ed5fa7e2319052e03ab800d518Chris Masonint btrfs_del_root(struct btrfs_trans_handle *trans, struct btrfs_root *root,
328e089f05c18ab36ed5fa7e2319052e03ab800d518Chris Mason		   struct btrfs_key *key)
3293768f3689fc76ecea17414936dff7a02746a4355Chris Mason{
3305caf2a002901f0fde475371c4bf1c553b51884afChris Mason	struct btrfs_path *path;
3313768f3689fc76ecea17414936dff7a02746a4355Chris Mason	int ret;
332c5739bba5260a59cebd20a51a55080592c8d3b07Chris Mason	struct btrfs_root_item *ri;
3335f39d397dfbe140a14edecd4e73c34ce23c4f9eeChris Mason	struct extent_buffer *leaf;
3343768f3689fc76ecea17414936dff7a02746a4355Chris Mason
3355caf2a002901f0fde475371c4bf1c553b51884afChris Mason	path = btrfs_alloc_path();
336db5b493ac78e46c7b6bad22cd25d8041564cd8eaTsutomu Itoh	if (!path)
337db5b493ac78e46c7b6bad22cd25d8041564cd8eaTsutomu Itoh		return -ENOMEM;
3385caf2a002901f0fde475371c4bf1c553b51884afChris Mason	ret = btrfs_search_slot(trans, root, key, path, -1, 1);
3393768f3689fc76ecea17414936dff7a02746a4355Chris Mason	if (ret < 0)
3403768f3689fc76ecea17414936dff7a02746a4355Chris Mason		goto out;
341edbd8d4efe4ddaf29a175ae504e2c9a05a96ebeeChris Mason
3423768f3689fc76ecea17414936dff7a02746a4355Chris Mason	BUG_ON(ret != 0);
3435f39d397dfbe140a14edecd4e73c34ce23c4f9eeChris Mason	leaf = path->nodes[0];
3445f39d397dfbe140a14edecd4e73c34ce23c4f9eeChris Mason	ri = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_root_item);
345c5739bba5260a59cebd20a51a55080592c8d3b07Chris Mason
3465eda7b5e9b0bed864dd18284c7df9b3c8207dad7Chris Mason	ret = btrfs_del_item(trans, root, path);
3473768f3689fc76ecea17414936dff7a02746a4355Chris Masonout:
3485caf2a002901f0fde475371c4bf1c553b51884afChris Mason	btrfs_free_path(path);
3493768f3689fc76ecea17414936dff7a02746a4355Chris Mason	return ret;
3503768f3689fc76ecea17414936dff7a02746a4355Chris Mason}
3510660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason
3520660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Masonint btrfs_del_root_ref(struct btrfs_trans_handle *trans,
3530660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason		       struct btrfs_root *tree_root,
3544df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng		       u64 root_id, u64 ref_id, u64 dirid, u64 *sequence,
3554df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng		       const char *name, int name_len)
3564df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng
3570660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason{
3584df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng	struct btrfs_path *path;
3594df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng	struct btrfs_root_ref *ref;
3604df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng	struct extent_buffer *leaf;
3610660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason	struct btrfs_key key;
3624df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng	unsigned long ptr;
3634df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng	int err = 0;
3640660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason	int ret;
3650660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason
3660660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason	path = btrfs_alloc_path();
3674df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng	if (!path)
3684df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng		return -ENOMEM;
3690660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason
3700660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason	key.objectid = root_id;
3714df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng	key.type = BTRFS_ROOT_BACKREF_KEY;
3720660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason	key.offset = ref_id;
3734df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zhengagain:
3740660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason	ret = btrfs_search_slot(trans, tree_root, &key, path, -1, 1);
3754df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng	BUG_ON(ret < 0);
3764df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng	if (ret == 0) {
3774df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng		leaf = path->nodes[0];
3784df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng		ref = btrfs_item_ptr(leaf, path->slots[0],
3794df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng				     struct btrfs_root_ref);
3804df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng
3814df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng		WARN_ON(btrfs_root_ref_dirid(leaf, ref) != dirid);
3824df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng		WARN_ON(btrfs_root_ref_name_len(leaf, ref) != name_len);
3834df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng		ptr = (unsigned long)(ref + 1);
3844df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng		WARN_ON(memcmp_extent_buffer(leaf, name, ptr, name_len));
3854df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng		*sequence = btrfs_root_ref_sequence(leaf, ref);
3864df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng
3874df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng		ret = btrfs_del_item(trans, tree_root, path);
3884df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng		BUG_ON(ret);
3894df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng	} else
3904df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng		err = -ENOENT;
3914df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng
3924df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng	if (key.type == BTRFS_ROOT_BACKREF_KEY) {
3934df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng		btrfs_release_path(tree_root, path);
3944df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng		key.objectid = ref_id;
3954df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng		key.type = BTRFS_ROOT_REF_KEY;
3964df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng		key.offset = root_id;
3974df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng		goto again;
3984df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng	}
3990660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason
4000660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason	btrfs_free_path(path);
4014df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng	return err;
4020660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason}
4030660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason
404ea9e8b11bd1252dcbc23afefcf1a52ec6aa3c113Chris Masonint btrfs_find_root_ref(struct btrfs_root *tree_root,
405ea9e8b11bd1252dcbc23afefcf1a52ec6aa3c113Chris Mason		   struct btrfs_path *path,
406ea9e8b11bd1252dcbc23afefcf1a52ec6aa3c113Chris Mason		   u64 root_id, u64 ref_id)
407ea9e8b11bd1252dcbc23afefcf1a52ec6aa3c113Chris Mason{
408ea9e8b11bd1252dcbc23afefcf1a52ec6aa3c113Chris Mason	struct btrfs_key key;
409ea9e8b11bd1252dcbc23afefcf1a52ec6aa3c113Chris Mason	int ret;
410ea9e8b11bd1252dcbc23afefcf1a52ec6aa3c113Chris Mason
411ea9e8b11bd1252dcbc23afefcf1a52ec6aa3c113Chris Mason	key.objectid = root_id;
412ea9e8b11bd1252dcbc23afefcf1a52ec6aa3c113Chris Mason	key.type = BTRFS_ROOT_REF_KEY;
413ea9e8b11bd1252dcbc23afefcf1a52ec6aa3c113Chris Mason	key.offset = ref_id;
414ea9e8b11bd1252dcbc23afefcf1a52ec6aa3c113Chris Mason
415ea9e8b11bd1252dcbc23afefcf1a52ec6aa3c113Chris Mason	ret = btrfs_search_slot(NULL, tree_root, &key, path, 0, 0);
416ea9e8b11bd1252dcbc23afefcf1a52ec6aa3c113Chris Mason	return ret;
417ea9e8b11bd1252dcbc23afefcf1a52ec6aa3c113Chris Mason}
418ea9e8b11bd1252dcbc23afefcf1a52ec6aa3c113Chris Mason
4190660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason/*
4200660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason * add a btrfs_root_ref item.  type is either BTRFS_ROOT_REF_KEY
4210660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason * or BTRFS_ROOT_BACKREF_KEY.
4220660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason *
4230660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason * The dirid, sequence, name and name_len refer to the directory entry
4240660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason * that is referencing the root.
4250660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason *
4260660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason * For a forward ref, the root_id is the id of the tree referencing
4270660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason * the root and ref_id is the id of the subvol  or snapshot.
4280660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason *
4290660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason * For a back ref the root_id is the id of the subvol or snapshot and
4300660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason * ref_id is the id of the tree referencing it.
4310660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason */
4320660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Masonint btrfs_add_root_ref(struct btrfs_trans_handle *trans,
4330660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason		       struct btrfs_root *tree_root,
4344df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng		       u64 root_id, u64 ref_id, u64 dirid, u64 sequence,
4350660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason		       const char *name, int name_len)
4360660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason{
4370660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason	struct btrfs_key key;
4380660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason	int ret;
4390660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason	struct btrfs_path *path;
4400660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason	struct btrfs_root_ref *ref;
4410660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason	struct extent_buffer *leaf;
4420660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason	unsigned long ptr;
4430660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason
4440660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason	path = btrfs_alloc_path();
4454df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng	if (!path)
4464df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng		return -ENOMEM;
4470660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason
4480660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason	key.objectid = root_id;
4494df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng	key.type = BTRFS_ROOT_BACKREF_KEY;
4500660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason	key.offset = ref_id;
4514df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zhengagain:
4520660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason	ret = btrfs_insert_empty_item(trans, tree_root, path, &key,
4530660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason				      sizeof(*ref) + name_len);
4540660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason	BUG_ON(ret);
4550660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason
4560660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason	leaf = path->nodes[0];
4570660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason	ref = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_root_ref);
4580660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason	btrfs_set_root_ref_dirid(leaf, ref, dirid);
4590660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason	btrfs_set_root_ref_sequence(leaf, ref, sequence);
4600660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason	btrfs_set_root_ref_name_len(leaf, ref, name_len);
4610660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason	ptr = (unsigned long)(ref + 1);
4620660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason	write_extent_buffer(leaf, name, ptr, name_len);
4630660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason	btrfs_mark_buffer_dirty(leaf);
4640660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason
4654df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng	if (key.type == BTRFS_ROOT_BACKREF_KEY) {
4664df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng		btrfs_release_path(tree_root, path);
4674df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng		key.objectid = ref_id;
4684df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng		key.type = BTRFS_ROOT_REF_KEY;
4694df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng		key.offset = root_id;
4704df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng		goto again;
4714df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng	}
4724df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng
4730660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason	btrfs_free_path(path);
4744df27c4d5cc1dda54ed7d0a8389347f2df359cf9Yan, Zheng	return 0;
4750660b5af3f7ac0fac69de975914e1f4a3a586fb3Chris Mason}
476