blob: 1fd93d63707fa586281930e62027be9bdb8c2837 [file] [log] [blame]
Chris Mason6cbd5572007-06-12 09:07:21 -04001/*
2 * Copyright (C) 2007 Oracle. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public
6 * License v2 as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public
14 * License along with this program; if not, write to the
15 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
16 * Boston, MA 021110-1307, USA.
17 */
18
Chris Mason3768f362007-03-13 16:47:54 -040019#include "ctree.h"
Chris Mason5eda7b52007-06-22 14:16:25 -040020#include "transaction.h"
Chris Mason3768f362007-03-13 16:47:54 -040021#include "disk-io.h"
22#include "print-tree.h"
23
Chris Masonbf4ef672008-05-08 13:26:18 -040024/*
Chris Masond352ac62008-09-29 15:18:18 -040025 * lookup the root with the highest offset for a given objectid. The key we do
26 * find is copied into 'key'. If we find something return 0, otherwise 1, < 0
27 * on error.
28 */
Chris Mason3768f362007-03-13 16:47:54 -040029int btrfs_find_last_root(struct btrfs_root *root, u64 objectid,
30 struct btrfs_root_item *item, struct btrfs_key *key)
31{
Chris Mason5caf2a02007-04-02 11:20:42 -040032 struct btrfs_path *path;
Chris Mason3768f362007-03-13 16:47:54 -040033 struct btrfs_key search_key;
Chris Mason5f39d392007-10-15 16:14:19 -040034 struct btrfs_key found_key;
35 struct extent_buffer *l;
Chris Mason3768f362007-03-13 16:47:54 -040036 int ret;
37 int slot;
38
39 search_key.objectid = objectid;
Chris Mason0660b5a2008-11-17 20:37:39 -050040 search_key.type = BTRFS_ROOT_ITEM_KEY;
Chris Mason5eda7b52007-06-22 14:16:25 -040041 search_key.offset = (u64)-1;
Chris Mason3768f362007-03-13 16:47:54 -040042
Chris Mason5caf2a02007-04-02 11:20:42 -040043 path = btrfs_alloc_path();
Tsutomu Itohdb5b4932011-03-23 08:14:16 +000044 if (!path)
45 return -ENOMEM;
Chris Mason5caf2a02007-04-02 11:20:42 -040046 ret = btrfs_search_slot(NULL, root, &search_key, path, 0, 0);
Chris Mason3768f362007-03-13 16:47:54 -040047 if (ret < 0)
48 goto out;
Chris Mason5f39d392007-10-15 16:14:19 -040049
Chris Mason3768f362007-03-13 16:47:54 -040050 BUG_ON(ret == 0);
Yan, Zheng76dda932009-09-21 16:00:26 -040051 if (path->slots[0] == 0) {
Chris Mason3768f362007-03-13 16:47:54 -040052 ret = 1;
53 goto out;
54 }
Yan, Zheng76dda932009-09-21 16:00:26 -040055 l = path->nodes[0];
56 slot = path->slots[0] - 1;
57 btrfs_item_key_to_cpu(l, &found_key, slot);
58 if (found_key.objectid != objectid ||
59 found_key.type != BTRFS_ROOT_ITEM_KEY) {
60 ret = 1;
61 goto out;
62 }
63 if (item)
64 read_extent_buffer(l, item, btrfs_item_ptr_offset(l, slot),
65 sizeof(*item));
66 if (key)
67 memcpy(key, &found_key, sizeof(found_key));
Chris Mason3768f362007-03-13 16:47:54 -040068 ret = 0;
69out:
Chris Mason5caf2a02007-04-02 11:20:42 -040070 btrfs_free_path(path);
Chris Mason3768f362007-03-13 16:47:54 -040071 return ret;
72}
73
Mark Fashehbf5f32e2011-07-14 21:23:06 +000074void btrfs_set_root_node(struct btrfs_root_item *item,
75 struct extent_buffer *node)
Yan Zheng5d4f98a2009-06-10 10:45:14 -040076{
77 btrfs_set_root_bytenr(item, node->start);
78 btrfs_set_root_level(item, btrfs_header_level(node));
79 btrfs_set_root_generation(item, btrfs_header_generation(node));
Yan Zheng5d4f98a2009-06-10 10:45:14 -040080}
81
Chris Masond352ac62008-09-29 15:18:18 -040082/*
83 * copy the data in 'item' into the btree
84 */
Chris Masone089f052007-03-16 16:20:31 -040085int btrfs_update_root(struct btrfs_trans_handle *trans, struct btrfs_root
86 *root, struct btrfs_key *key, struct btrfs_root_item
87 *item)
Chris Mason3768f362007-03-13 16:47:54 -040088{
Chris Mason5caf2a02007-04-02 11:20:42 -040089 struct btrfs_path *path;
Chris Mason5f39d392007-10-15 16:14:19 -040090 struct extent_buffer *l;
Chris Mason3768f362007-03-13 16:47:54 -040091 int ret;
92 int slot;
Chris Mason5f39d392007-10-15 16:14:19 -040093 unsigned long ptr;
Chris Mason3768f362007-03-13 16:47:54 -040094
Chris Mason5caf2a02007-04-02 11:20:42 -040095 path = btrfs_alloc_path();
96 BUG_ON(!path);
Chris Mason5caf2a02007-04-02 11:20:42 -040097 ret = btrfs_search_slot(trans, root, key, path, 0, 1);
Chris Mason3768f362007-03-13 16:47:54 -040098 if (ret < 0)
99 goto out;
Chris Masond6667462008-01-03 14:51:00 -0500100
101 if (ret != 0) {
102 btrfs_print_leaf(root, path->nodes[0]);
Chris Masond3977122009-01-05 21:25:51 -0500103 printk(KERN_CRIT "unable to update root key %llu %u %llu\n",
104 (unsigned long long)key->objectid, key->type,
105 (unsigned long long)key->offset);
Chris Masond6667462008-01-03 14:51:00 -0500106 BUG_ON(1);
107 }
108
Chris Mason5f39d392007-10-15 16:14:19 -0400109 l = path->nodes[0];
Chris Mason5caf2a02007-04-02 11:20:42 -0400110 slot = path->slots[0];
Chris Mason5f39d392007-10-15 16:14:19 -0400111 ptr = btrfs_item_ptr_offset(l, slot);
112 write_extent_buffer(l, item, ptr, sizeof(*item));
Chris Mason5caf2a02007-04-02 11:20:42 -0400113 btrfs_mark_buffer_dirty(path->nodes[0]);
Chris Mason3768f362007-03-13 16:47:54 -0400114out:
Chris Mason5caf2a02007-04-02 11:20:42 -0400115 btrfs_free_path(path);
Chris Mason3768f362007-03-13 16:47:54 -0400116 return ret;
117}
118
Jeff Mahoneyd16cb052011-10-03 23:22:34 -0400119int btrfs_insert_root(struct btrfs_trans_handle *trans, struct btrfs_root *root,
120 struct btrfs_key *key, struct btrfs_root_item *item)
Chris Mason3768f362007-03-13 16:47:54 -0400121{
Jeff Mahoneyd16cb052011-10-03 23:22:34 -0400122 return btrfs_insert_item(trans, root, key, item, sizeof(*item));
Chris Mason3768f362007-03-13 16:47:54 -0400123}
124
Chris Masond352ac62008-09-29 15:18:18 -0400125/*
126 * at mount time we want to find all the old transaction snapshots that were in
Chris Masond3977122009-01-05 21:25:51 -0500127 * the process of being deleted if we crashed. This is any root item with an
128 * offset lower than the latest root. They need to be queued for deletion to
129 * finish what was happening when we crashed.
Chris Masond352ac62008-09-29 15:18:18 -0400130 */
Yan Zheng5d4f98a2009-06-10 10:45:14 -0400131int btrfs_find_dead_roots(struct btrfs_root *root, u64 objectid)
Chris Mason5eda7b52007-06-22 14:16:25 -0400132{
133 struct btrfs_root *dead_root;
Chris Mason5eda7b52007-06-22 14:16:25 -0400134 struct btrfs_root_item *ri;
135 struct btrfs_key key;
Chris Masona7a16fd2008-06-26 10:34:20 -0400136 struct btrfs_key found_key;
Chris Mason5eda7b52007-06-22 14:16:25 -0400137 struct btrfs_path *path;
138 int ret;
139 u32 nritems;
Chris Mason5f39d392007-10-15 16:14:19 -0400140 struct extent_buffer *leaf;
Chris Mason5eda7b52007-06-22 14:16:25 -0400141 int slot;
142
Chris Mason5ce14bb2007-09-11 11:15:39 -0400143 key.objectid = objectid;
Chris Mason5eda7b52007-06-22 14:16:25 -0400144 btrfs_set_key_type(&key, BTRFS_ROOT_ITEM_KEY);
145 key.offset = 0;
146 path = btrfs_alloc_path();
147 if (!path)
148 return -ENOMEM;
Chris Masona7a16fd2008-06-26 10:34:20 -0400149
150again:
Chris Mason5eda7b52007-06-22 14:16:25 -0400151 ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
152 if (ret < 0)
153 goto err;
Chris Masond3977122009-01-05 21:25:51 -0500154 while (1) {
Chris Mason5f39d392007-10-15 16:14:19 -0400155 leaf = path->nodes[0];
156 nritems = btrfs_header_nritems(leaf);
Chris Mason5eda7b52007-06-22 14:16:25 -0400157 slot = path->slots[0];
158 if (slot >= nritems) {
159 ret = btrfs_next_leaf(root, path);
160 if (ret)
161 break;
Chris Mason5f39d392007-10-15 16:14:19 -0400162 leaf = path->nodes[0];
163 nritems = btrfs_header_nritems(leaf);
Chris Mason5eda7b52007-06-22 14:16:25 -0400164 slot = path->slots[0];
165 }
Chris Mason5f39d392007-10-15 16:14:19 -0400166 btrfs_item_key_to_cpu(leaf, &key, slot);
Chris Mason5eda7b52007-06-22 14:16:25 -0400167 if (btrfs_key_type(&key) != BTRFS_ROOT_ITEM_KEY)
168 goto next;
Chris Mason5ce14bb2007-09-11 11:15:39 -0400169
170 if (key.objectid < objectid)
171 goto next;
172
173 if (key.objectid > objectid)
174 break;
175
Chris Mason5eda7b52007-06-22 14:16:25 -0400176 ri = btrfs_item_ptr(leaf, slot, struct btrfs_root_item);
Chris Mason5f39d392007-10-15 16:14:19 -0400177 if (btrfs_disk_root_refs(leaf, ri) != 0)
Chris Mason5eda7b52007-06-22 14:16:25 -0400178 goto next;
Chris Mason5ce14bb2007-09-11 11:15:39 -0400179
Chris Masona7a16fd2008-06-26 10:34:20 -0400180 memcpy(&found_key, &key, sizeof(key));
181 key.offset++;
David Sterbab3b4aa72011-04-21 01:20:15 +0200182 btrfs_release_path(path);
Chris Masone02119d2008-09-05 16:13:11 -0400183 dead_root =
184 btrfs_read_fs_root_no_radix(root->fs_info->tree_root,
185 &found_key);
Aneesha1f39632007-07-11 10:03:27 -0400186 if (IS_ERR(dead_root)) {
187 ret = PTR_ERR(dead_root);
Chris Mason5eda7b52007-06-22 14:16:25 -0400188 goto err;
189 }
Chris Mason5ce14bb2007-09-11 11:15:39 -0400190
Yan Zheng5d4f98a2009-06-10 10:45:14 -0400191 ret = btrfs_add_dead_root(dead_root);
Chris Mason5eda7b52007-06-22 14:16:25 -0400192 if (ret)
193 goto err;
Chris Masona7a16fd2008-06-26 10:34:20 -0400194 goto again;
Chris Mason5eda7b52007-06-22 14:16:25 -0400195next:
196 slot++;
197 path->slots[0]++;
198 }
199 ret = 0;
200err:
201 btrfs_free_path(path);
202 return ret;
203}
204
Yan, Zheng76dda932009-09-21 16:00:26 -0400205int btrfs_find_orphan_roots(struct btrfs_root *tree_root)
206{
207 struct extent_buffer *leaf;
208 struct btrfs_path *path;
209 struct btrfs_key key;
Yan, Zhengd68fc572010-05-16 10:49:58 -0400210 struct btrfs_key root_key;
211 struct btrfs_root *root;
Yan, Zheng76dda932009-09-21 16:00:26 -0400212 int err = 0;
213 int ret;
214
215 path = btrfs_alloc_path();
216 if (!path)
217 return -ENOMEM;
218
219 key.objectid = BTRFS_ORPHAN_OBJECTID;
220 key.type = BTRFS_ORPHAN_ITEM_KEY;
221 key.offset = 0;
222
Yan, Zhengd68fc572010-05-16 10:49:58 -0400223 root_key.type = BTRFS_ROOT_ITEM_KEY;
224 root_key.offset = (u64)-1;
225
Yan, Zheng76dda932009-09-21 16:00:26 -0400226 while (1) {
227 ret = btrfs_search_slot(NULL, tree_root, &key, path, 0, 0);
228 if (ret < 0) {
229 err = ret;
230 break;
231 }
232
233 leaf = path->nodes[0];
234 if (path->slots[0] >= btrfs_header_nritems(leaf)) {
235 ret = btrfs_next_leaf(tree_root, path);
236 if (ret < 0)
237 err = ret;
238 if (ret != 0)
239 break;
240 leaf = path->nodes[0];
241 }
242
243 btrfs_item_key_to_cpu(leaf, &key, path->slots[0]);
David Sterbab3b4aa72011-04-21 01:20:15 +0200244 btrfs_release_path(path);
Yan, Zheng76dda932009-09-21 16:00:26 -0400245
246 if (key.objectid != BTRFS_ORPHAN_OBJECTID ||
247 key.type != BTRFS_ORPHAN_ITEM_KEY)
248 break;
249
Yan, Zhengd68fc572010-05-16 10:49:58 -0400250 root_key.objectid = key.offset;
251 key.offset++;
252
253 root = btrfs_read_fs_root_no_name(tree_root->fs_info,
254 &root_key);
255 if (!IS_ERR(root))
256 continue;
257
258 ret = PTR_ERR(root);
259 if (ret != -ENOENT) {
Yan, Zheng76dda932009-09-21 16:00:26 -0400260 err = ret;
261 break;
262 }
263
Yan, Zhengd68fc572010-05-16 10:49:58 -0400264 ret = btrfs_find_dead_roots(tree_root, root_key.objectid);
265 if (ret) {
266 err = ret;
267 break;
268 }
Yan, Zheng76dda932009-09-21 16:00:26 -0400269 }
270
271 btrfs_free_path(path);
272 return err;
273}
274
Chris Masond352ac62008-09-29 15:18:18 -0400275/* drop the root item for 'key' from 'root' */
Chris Masone089f052007-03-16 16:20:31 -0400276int btrfs_del_root(struct btrfs_trans_handle *trans, struct btrfs_root *root,
277 struct btrfs_key *key)
Chris Mason3768f362007-03-13 16:47:54 -0400278{
Chris Mason5caf2a02007-04-02 11:20:42 -0400279 struct btrfs_path *path;
Chris Mason3768f362007-03-13 16:47:54 -0400280 int ret;
Chris Masonc5739bb2007-04-10 09:27:04 -0400281 struct btrfs_root_item *ri;
Chris Mason5f39d392007-10-15 16:14:19 -0400282 struct extent_buffer *leaf;
Chris Mason3768f362007-03-13 16:47:54 -0400283
Chris Mason5caf2a02007-04-02 11:20:42 -0400284 path = btrfs_alloc_path();
Tsutomu Itohdb5b4932011-03-23 08:14:16 +0000285 if (!path)
286 return -ENOMEM;
Chris Mason5caf2a02007-04-02 11:20:42 -0400287 ret = btrfs_search_slot(trans, root, key, path, -1, 1);
Chris Mason3768f362007-03-13 16:47:54 -0400288 if (ret < 0)
289 goto out;
Chris Masonedbd8d42007-12-21 16:27:24 -0500290
Chris Mason3768f362007-03-13 16:47:54 -0400291 BUG_ON(ret != 0);
Chris Mason5f39d392007-10-15 16:14:19 -0400292 leaf = path->nodes[0];
293 ri = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_root_item);
Chris Masonc5739bb2007-04-10 09:27:04 -0400294
Chris Mason5eda7b52007-06-22 14:16:25 -0400295 ret = btrfs_del_item(trans, root, path);
Chris Mason3768f362007-03-13 16:47:54 -0400296out:
Chris Mason5caf2a02007-04-02 11:20:42 -0400297 btrfs_free_path(path);
Chris Mason3768f362007-03-13 16:47:54 -0400298 return ret;
299}
Chris Mason0660b5a2008-11-17 20:37:39 -0500300
301int btrfs_del_root_ref(struct btrfs_trans_handle *trans,
302 struct btrfs_root *tree_root,
Yan, Zheng4df27c4d2009-09-21 15:56:00 -0400303 u64 root_id, u64 ref_id, u64 dirid, u64 *sequence,
304 const char *name, int name_len)
305
Chris Mason0660b5a2008-11-17 20:37:39 -0500306{
Chris Mason0660b5a2008-11-17 20:37:39 -0500307 struct btrfs_path *path;
Yan, Zheng4df27c4d2009-09-21 15:56:00 -0400308 struct btrfs_root_ref *ref;
309 struct extent_buffer *leaf;
310 struct btrfs_key key;
311 unsigned long ptr;
312 int err = 0;
313 int ret;
Chris Mason0660b5a2008-11-17 20:37:39 -0500314
315 path = btrfs_alloc_path();
Yan, Zheng4df27c4d2009-09-21 15:56:00 -0400316 if (!path)
317 return -ENOMEM;
Chris Mason0660b5a2008-11-17 20:37:39 -0500318
319 key.objectid = root_id;
Yan, Zheng4df27c4d2009-09-21 15:56:00 -0400320 key.type = BTRFS_ROOT_BACKREF_KEY;
Chris Mason0660b5a2008-11-17 20:37:39 -0500321 key.offset = ref_id;
Yan, Zheng4df27c4d2009-09-21 15:56:00 -0400322again:
Chris Mason0660b5a2008-11-17 20:37:39 -0500323 ret = btrfs_search_slot(trans, tree_root, &key, path, -1, 1);
Yan, Zheng4df27c4d2009-09-21 15:56:00 -0400324 BUG_ON(ret < 0);
325 if (ret == 0) {
326 leaf = path->nodes[0];
327 ref = btrfs_item_ptr(leaf, path->slots[0],
328 struct btrfs_root_ref);
Chris Mason0660b5a2008-11-17 20:37:39 -0500329
Yan, Zheng4df27c4d2009-09-21 15:56:00 -0400330 WARN_ON(btrfs_root_ref_dirid(leaf, ref) != dirid);
331 WARN_ON(btrfs_root_ref_name_len(leaf, ref) != name_len);
332 ptr = (unsigned long)(ref + 1);
333 WARN_ON(memcmp_extent_buffer(leaf, name, ptr, name_len));
334 *sequence = btrfs_root_ref_sequence(leaf, ref);
335
336 ret = btrfs_del_item(trans, tree_root, path);
Tsutomu Itoh65a246c2011-05-19 04:37:44 +0000337 if (ret) {
338 err = ret;
339 goto out;
340 }
Yan, Zheng4df27c4d2009-09-21 15:56:00 -0400341 } else
342 err = -ENOENT;
343
344 if (key.type == BTRFS_ROOT_BACKREF_KEY) {
David Sterbab3b4aa72011-04-21 01:20:15 +0200345 btrfs_release_path(path);
Yan, Zheng4df27c4d2009-09-21 15:56:00 -0400346 key.objectid = ref_id;
347 key.type = BTRFS_ROOT_REF_KEY;
348 key.offset = root_id;
349 goto again;
350 }
Chris Mason0660b5a2008-11-17 20:37:39 -0500351
Tsutomu Itoh65a246c2011-05-19 04:37:44 +0000352out:
Chris Mason0660b5a2008-11-17 20:37:39 -0500353 btrfs_free_path(path);
Yan, Zheng4df27c4d2009-09-21 15:56:00 -0400354 return err;
Chris Mason0660b5a2008-11-17 20:37:39 -0500355}
356
Chris Masonea9e8b12008-11-17 21:14:24 -0500357int btrfs_find_root_ref(struct btrfs_root *tree_root,
358 struct btrfs_path *path,
359 u64 root_id, u64 ref_id)
360{
361 struct btrfs_key key;
362 int ret;
363
364 key.objectid = root_id;
365 key.type = BTRFS_ROOT_REF_KEY;
366 key.offset = ref_id;
367
368 ret = btrfs_search_slot(NULL, tree_root, &key, path, 0, 0);
369 return ret;
370}
371
Chris Mason0660b5a2008-11-17 20:37:39 -0500372/*
373 * add a btrfs_root_ref item. type is either BTRFS_ROOT_REF_KEY
374 * or BTRFS_ROOT_BACKREF_KEY.
375 *
376 * The dirid, sequence, name and name_len refer to the directory entry
377 * that is referencing the root.
378 *
379 * For a forward ref, the root_id is the id of the tree referencing
380 * the root and ref_id is the id of the subvol or snapshot.
381 *
382 * For a back ref the root_id is the id of the subvol or snapshot and
383 * ref_id is the id of the tree referencing it.
384 */
385int btrfs_add_root_ref(struct btrfs_trans_handle *trans,
386 struct btrfs_root *tree_root,
Yan, Zheng4df27c4d2009-09-21 15:56:00 -0400387 u64 root_id, u64 ref_id, u64 dirid, u64 sequence,
Chris Mason0660b5a2008-11-17 20:37:39 -0500388 const char *name, int name_len)
389{
390 struct btrfs_key key;
391 int ret;
392 struct btrfs_path *path;
393 struct btrfs_root_ref *ref;
394 struct extent_buffer *leaf;
395 unsigned long ptr;
396
Chris Mason0660b5a2008-11-17 20:37:39 -0500397 path = btrfs_alloc_path();
Yan, Zheng4df27c4d2009-09-21 15:56:00 -0400398 if (!path)
399 return -ENOMEM;
Chris Mason0660b5a2008-11-17 20:37:39 -0500400
401 key.objectid = root_id;
Yan, Zheng4df27c4d2009-09-21 15:56:00 -0400402 key.type = BTRFS_ROOT_BACKREF_KEY;
Chris Mason0660b5a2008-11-17 20:37:39 -0500403 key.offset = ref_id;
Yan, Zheng4df27c4d2009-09-21 15:56:00 -0400404again:
Chris Mason0660b5a2008-11-17 20:37:39 -0500405 ret = btrfs_insert_empty_item(trans, tree_root, path, &key,
406 sizeof(*ref) + name_len);
407 BUG_ON(ret);
408
409 leaf = path->nodes[0];
410 ref = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_root_ref);
411 btrfs_set_root_ref_dirid(leaf, ref, dirid);
412 btrfs_set_root_ref_sequence(leaf, ref, sequence);
413 btrfs_set_root_ref_name_len(leaf, ref, name_len);
414 ptr = (unsigned long)(ref + 1);
415 write_extent_buffer(leaf, name, ptr, name_len);
416 btrfs_mark_buffer_dirty(leaf);
417
Yan, Zheng4df27c4d2009-09-21 15:56:00 -0400418 if (key.type == BTRFS_ROOT_BACKREF_KEY) {
David Sterbab3b4aa72011-04-21 01:20:15 +0200419 btrfs_release_path(path);
Yan, Zheng4df27c4d2009-09-21 15:56:00 -0400420 key.objectid = ref_id;
421 key.type = BTRFS_ROOT_REF_KEY;
422 key.offset = root_id;
423 goto again;
424 }
425
Chris Mason0660b5a2008-11-17 20:37:39 -0500426 btrfs_free_path(path);
Yan, Zheng4df27c4d2009-09-21 15:56:00 -0400427 return 0;
Chris Mason0660b5a2008-11-17 20:37:39 -0500428}
Li Zefan08fe4db2011-03-28 02:01:25 +0000429
430/*
431 * Old btrfs forgets to init root_item->flags and root_item->byte_limit
432 * for subvolumes. To work around this problem, we steal a bit from
433 * root_item->inode_item->flags, and use it to indicate if those fields
434 * have been properly initialized.
435 */
436void btrfs_check_and_init_root_item(struct btrfs_root_item *root_item)
437{
438 u64 inode_flags = le64_to_cpu(root_item->inode.flags);
439
440 if (!(inode_flags & BTRFS_INODE_ROOT_ITEM_INIT)) {
441 inode_flags |= BTRFS_INODE_ROOT_ITEM_INIT;
442 root_item->inode.flags = cpu_to_le64(inode_flags);
443 root_item->flags = 0;
444 root_item->byte_limit = 0;
445 }
446}