btrfs-progs: Rename OPEN_CTREE_FS_PARTIAL to OPEN_CTREE_TEMPORARY_SUPER
[platform/upstream/btrfs-progs.git] / inode.c
1 /*
2  * Copyright (C) 2014 Fujitsu.  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
19 /*
20  * Unlike inode.c in kernel, which can use most of the kernel infrastructure
21  * like inode/dentry things, in user-land, we can only use inode number to
22  * do directly operation on extent buffer, which may cause extra searching,
23  * but should not be a huge problem since progs is less performance sensitive.
24  */
25 #include <sys/stat.h>
26
27 #include "ctree.h"
28 #include "transaction.h"
29 #include "disk-io.h"
30 #include "time.h"
31 #include "messages.h"
32
33 /*
34  * Find a free inode index for later btrfs_add_link().
35  * Currently just search from the largest dir_index and +1.
36  */
37 static int btrfs_find_free_dir_index(struct btrfs_root *root, u64 dir_ino,
38                                      u64 *ret_ino)
39 {
40         struct btrfs_path *path;
41         struct btrfs_key key;
42         struct btrfs_key found_key;
43         u64 ret_val = 2;
44         int ret = 0;
45
46         if (!ret_ino)
47                 return 0;
48
49         path = btrfs_alloc_path();
50         if (!path)
51                 return -ENOMEM;
52
53         key.objectid = dir_ino;
54         key.type = BTRFS_DIR_INDEX_KEY;
55         key.offset = (u64)-1;
56
57         ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
58         if (ret < 0)
59                 goto out;
60         ret = 0;
61         if (path->slots[0] == 0) {
62                 ret = btrfs_prev_leaf(root, path);
63                 if (ret < 0)
64                         goto out;
65                 if (ret > 0) {
66                         /*
67                          * This shouldn't happen since there must be a leaf
68                          * containing the DIR_ITEM.
69                          * Can only happen when the previous leaf is corrupted.
70                          */
71                         ret = -EIO;
72                         goto out;
73                 }
74         } else {
75                 path->slots[0]--;
76         }
77         btrfs_item_key_to_cpu(path->nodes[0], &found_key, path->slots[0]);
78         if (found_key.objectid != dir_ino ||
79             found_key.type != BTRFS_DIR_INDEX_KEY)
80                 goto out;
81         ret_val = found_key.offset + 1;
82 out:
83         btrfs_free_path(path);
84         if (ret == 0)
85                 *ret_ino = ret_val;
86         return ret;
87 }
88
89 /* Check the dir_item/index conflicts before insert */
90 int check_dir_conflict(struct btrfs_root *root, char *name, int namelen,
91                        u64 dir, u64 index)
92 {
93         struct btrfs_path *path;
94         struct btrfs_key key;
95         struct btrfs_inode_item *inode_item;
96         struct btrfs_dir_item *dir_item;
97         int ret = 0;
98
99         path = btrfs_alloc_path();
100         if (!path)
101                 return -ENOMEM;
102
103         /* Given dir exists? */
104         key.objectid = dir;
105         key.type = BTRFS_INODE_ITEM_KEY;
106         key.offset = 0;
107         ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
108         if (ret < 0)
109                 goto out;
110         if (ret > 0) {
111                 ret = -ENOENT;
112                 goto out;
113         }
114
115         /* Is it a dir? */
116         inode_item = btrfs_item_ptr(path->nodes[0], path->slots[0],
117                                     struct btrfs_inode_item);
118         if (!(btrfs_inode_mode(path->nodes[0], inode_item) & S_IFDIR)) {
119                 ret = -ENOTDIR;
120                 goto out;
121         }
122         btrfs_release_path(path);
123
124         /* Name conflicting? */
125         dir_item = btrfs_lookup_dir_item(NULL, root, path, dir, name,
126                                          namelen, 0);
127         if (IS_ERR(dir_item)) {
128                 ret = PTR_ERR(dir_item);
129                 goto out;
130         }
131         if (dir_item) {
132                 ret = -EEXIST;
133                 goto out;
134         }
135         btrfs_release_path(path);
136
137         /* Index conflicting? */
138         dir_item = btrfs_lookup_dir_index(NULL, root, path, dir, name,
139                                           namelen, index, 0);
140         if (IS_ERR(dir_item) && PTR_ERR(dir_item) == -ENOENT)
141                 dir_item = NULL;
142         if (IS_ERR(dir_item)) {
143                 ret = PTR_ERR(dir_item);
144                 goto out;
145         }
146         if (dir_item) {
147                 ret = -EEXIST;
148                 goto out;
149         }
150
151 out:
152         btrfs_free_path(path);
153         return ret;
154 }
155
156 /*
157  * Add dir_item/index for 'parent_ino' if add_backref is true, also insert a
158  * backref from the ino to parent dir and update the nlink(Kernel version does
159  * not do this thing)
160  *
161  * Currently only supports adding link from an inode to another inode.
162  */
163 int btrfs_add_link(struct btrfs_trans_handle *trans, struct btrfs_root *root,
164                    u64 ino, u64 parent_ino, char *name, int namelen,
165                    u8 type, u64 *index, int add_backref, int ignore_existed)
166 {
167         struct btrfs_path *path;
168         struct btrfs_key key;
169         struct btrfs_inode_item *inode_item;
170         u32 nlink;
171         u64 inode_size;
172         u64 ret_index = 0;
173         int ret = 0;
174
175         path = btrfs_alloc_path();
176         if (!path)
177                 return -ENOMEM;
178
179         if (index && *index) {
180                 ret_index = *index;
181         } else {
182                 ret = btrfs_find_free_dir_index(root, parent_ino, &ret_index);
183                 if (ret < 0)
184                         goto out;
185         }
186
187         ret = check_dir_conflict(root, name, namelen, parent_ino, ret_index);
188         if (ret < 0 && !(ignore_existed && ret == -EEXIST))
189                 goto out;
190
191         /* Add inode ref */
192         if (add_backref) {
193                 ret = btrfs_insert_inode_ref(trans, root, name, namelen,
194                                              ino, parent_ino, ret_index);
195                 if (ret < 0 && !(ignore_existed && ret == -EEXIST))
196                         goto out;
197
198                 /* do not update nlinks if existed */
199                 if (!ret) {
200                         /* Update nlinks for the inode */
201                         key.objectid = ino;
202                         key.type = BTRFS_INODE_ITEM_KEY;
203                         key.offset = 0;
204                         ret = btrfs_search_slot(trans, root, &key, path, 1, 1);
205                         if (ret) {
206                                 if (ret > 0)
207                                         ret = -ENOENT;
208                                 goto out;
209                         }
210                         inode_item = btrfs_item_ptr(path->nodes[0],
211                                     path->slots[0], struct btrfs_inode_item);
212                         nlink = btrfs_inode_nlink(path->nodes[0], inode_item);
213                         nlink++;
214                         btrfs_set_inode_nlink(path->nodes[0], inode_item,
215                                               nlink);
216                         btrfs_mark_buffer_dirty(path->nodes[0]);
217                         btrfs_release_path(path);
218                 }
219         }
220
221         /* Add dir_item and dir_index */
222         key.objectid = ino;
223         key.type = BTRFS_INODE_ITEM_KEY;
224         key.offset = 0;
225         ret = btrfs_insert_dir_item(trans, root, name, namelen, parent_ino,
226                                     &key, type, ret_index);
227         if (ret < 0)
228                 goto out;
229
230         /* Update inode size of the parent inode */
231         key.objectid = parent_ino;
232         key.type = BTRFS_INODE_ITEM_KEY;
233         key.offset = 0;
234         ret = btrfs_search_slot(trans, root, &key, path, 1, 1);
235         if (ret)
236                 goto out;
237         inode_item = btrfs_item_ptr(path->nodes[0], path->slots[0],
238                                     struct btrfs_inode_item);
239         inode_size = btrfs_inode_size(path->nodes[0], inode_item);
240         inode_size += namelen * 2;
241         btrfs_set_inode_size(path->nodes[0], inode_item, inode_size);
242         btrfs_mark_buffer_dirty(path->nodes[0]);
243         btrfs_release_path(path);
244
245 out:
246         btrfs_free_path(path);
247         if (ret == 0 && index)
248                 *index = ret_index;
249         return ret;
250 }
251
252 int btrfs_add_orphan_item(struct btrfs_trans_handle *trans,
253                           struct btrfs_root *root, struct btrfs_path *path,
254                           u64 ino)
255 {
256         struct btrfs_key key;
257
258         key.objectid = BTRFS_ORPHAN_OBJECTID;
259         key.type = BTRFS_ORPHAN_ITEM_KEY;
260         key.offset = ino;
261
262         return btrfs_insert_empty_item(trans, root, path, &key, 0);
263 }
264
265 /*
266  * Unlink an inode, which will remove its backref and corresponding dir_index/
267  * dir_item if any of them exists.
268  *
269  * If an inode's nlink is reduced to 0 and 'add_orphan' is true, it will be
270  * added to orphan inode and waiting to be deleted by next kernel mount.
271  */
272 int btrfs_unlink(struct btrfs_trans_handle *trans, struct btrfs_root *root,
273                  u64 ino, u64 parent_ino, u64 index, const char *name,
274                  int namelen, int add_orphan)
275 {
276         struct btrfs_path *path;
277         struct btrfs_key key;
278         struct btrfs_inode_item *inode_item;
279         struct btrfs_inode_ref *inode_ref;
280         struct btrfs_dir_item *dir_item;
281         u64 inode_size;
282         u32 nlinks;
283         int del_inode_ref = 0;
284         int del_dir_item = 0;
285         int del_dir_index = 0;
286         int ret = 0;
287
288         path = btrfs_alloc_path();
289         if (!path)
290                 return -ENOMEM;
291
292         /* check the ref and backref exists */
293         inode_ref = btrfs_lookup_inode_ref(trans, root, path, name, namelen,
294                                            ino, parent_ino, 0);
295         if (IS_ERR(inode_ref)) {
296                 ret = PTR_ERR(inode_ref);
297                 goto out;
298         }
299         if (inode_ref)
300                 del_inode_ref = 1;
301         btrfs_release_path(path);
302
303         dir_item = btrfs_lookup_dir_item(NULL, root, path, parent_ino,
304                                          name, namelen, 0);
305         if (IS_ERR(dir_item)) {
306                 ret = PTR_ERR(dir_item);
307                 goto out;
308         }
309         if (dir_item)
310                 del_dir_item = 1;
311         btrfs_release_path(path);
312
313         dir_item = btrfs_lookup_dir_index(NULL, root, path, parent_ino,
314                                           name, namelen, index, 0);
315         /*
316          * Since lookup_dir_index() will return -ENOENT when not found,
317          * we need to do extra check.
318          */
319         if (IS_ERR(dir_item) && PTR_ERR(dir_item) == -ENOENT)
320                 dir_item = NULL;
321         if (IS_ERR(dir_item)) {
322                 ret = PTR_ERR(dir_item);
323                 goto out;
324         }
325         if (dir_item)
326                 del_dir_index = 1;
327         btrfs_release_path(path);
328
329         if (!del_inode_ref && !del_dir_item && !del_dir_index) {
330                 /* All not found, shouldn't happen */
331                 ret = -ENOENT;
332                 goto out;
333         }
334
335         if (del_inode_ref) {
336                 /* Only decrease nlink when deleting inode_ref */
337                 key.objectid = ino;
338                 key.type = BTRFS_INODE_ITEM_KEY;
339                 key.offset = 0;
340                 ret = btrfs_search_slot(trans, root, &key, path, -1, 1);
341                 if (ret) {
342                         if (ret > 0)
343                                 ret = -ENOENT;
344                         goto out;
345                 }
346                 inode_item = btrfs_item_ptr(path->nodes[0], path->slots[0],
347                                             struct btrfs_inode_item);
348                 nlinks = btrfs_inode_nlink(path->nodes[0], inode_item);
349                 if (nlinks > 0)
350                         nlinks--;
351                 btrfs_set_inode_nlink(path->nodes[0], inode_item, nlinks);
352                 btrfs_mark_buffer_dirty(path->nodes[0]);
353                 btrfs_release_path(path);
354
355                 /* For nlinks == 0, add it to orphan list if needed */
356                 if (nlinks == 0 && add_orphan) {
357                         ret = btrfs_add_orphan_item(trans, root, path, ino);
358                         if (ret < 0)
359                                 goto out;
360                         btrfs_mark_buffer_dirty(path->nodes[0]);
361                         btrfs_release_path(path);
362                 }
363
364                 ret = btrfs_del_inode_ref(trans, root, name, namelen, ino,
365                                           parent_ino, &index);
366                 if (ret < 0)
367                         goto out;
368         }
369
370         if (del_dir_index) {
371                 dir_item = btrfs_lookup_dir_index(trans, root, path,
372                                                   parent_ino, name, namelen,
373                                                   index, -1);
374                 if (IS_ERR(dir_item)) {
375                         ret = PTR_ERR(dir_item);
376                         goto out;
377                 }
378                 if (!dir_item) {
379                         ret = -ENOENT;
380                         goto out;
381                 }
382                 ret = btrfs_delete_one_dir_name(trans, root, path, dir_item);
383                 if (ret)
384                         goto out;
385                 btrfs_release_path(path);
386
387                 /* Update inode size of the parent inode */
388                 key.objectid = parent_ino;
389                 key.type = BTRFS_INODE_ITEM_KEY;
390                 key.offset = 0;
391                 ret = btrfs_search_slot(trans, root, &key, path, 1, 1);
392                 if (ret)
393                         goto out;
394                 inode_item = btrfs_item_ptr(path->nodes[0], path->slots[0],
395                                             struct btrfs_inode_item);
396                 inode_size = btrfs_inode_size(path->nodes[0], inode_item);
397                 if (inode_size >= namelen)
398                         inode_size -= namelen;
399                 btrfs_set_inode_size(path->nodes[0], inode_item, inode_size);
400                 btrfs_mark_buffer_dirty(path->nodes[0]);
401                 btrfs_release_path(path);
402         }
403
404         if (del_dir_item) {
405                 dir_item = btrfs_lookup_dir_item(trans, root, path, parent_ino,
406                                                  name, namelen, -1);
407                 if (IS_ERR(dir_item)) {
408                         ret = PTR_ERR(dir_item);
409                         goto out;
410                 }
411                 if (!dir_item) {
412                         ret = -ENOENT;
413                         goto out;
414                 }
415                 ret = btrfs_delete_one_dir_name(trans, root, path, dir_item);
416                 if (ret < 0)
417                         goto out;
418                 btrfs_release_path(path);
419
420                 /* Update inode size of the parent inode */
421                 key.objectid = parent_ino;
422                 key.type = BTRFS_INODE_ITEM_KEY;
423                 key.offset = 0;
424                 ret = btrfs_search_slot(trans, root, &key, path, 1, 1);
425                 if (ret)
426                         goto out;
427                 inode_item = btrfs_item_ptr(path->nodes[0], path->slots[0],
428                                             struct btrfs_inode_item);
429                 inode_size = btrfs_inode_size(path->nodes[0], inode_item);
430                 if (inode_size >= namelen)
431                         inode_size -= namelen;
432                 btrfs_set_inode_size(path->nodes[0], inode_item, inode_size);
433                 btrfs_mark_buffer_dirty(path->nodes[0]);
434                 btrfs_release_path(path);
435         }
436
437 out:
438         btrfs_free_path(path);
439         return ret;
440 }
441
442 /* Fill inode item with 'mode'. Uid/gid to root/root */
443 static void fill_inode_item(struct btrfs_trans_handle *trans,
444                             struct btrfs_inode_item *inode_item,
445                             u32 mode, u32 nlink)
446 {
447         time_t now = time(NULL);
448
449         btrfs_set_stack_inode_generation(inode_item, trans->transid);
450         btrfs_set_stack_inode_uid(inode_item, 0);
451         btrfs_set_stack_inode_gid(inode_item, 0);
452         btrfs_set_stack_inode_size(inode_item, 0);
453         btrfs_set_stack_inode_mode(inode_item, mode);
454         btrfs_set_stack_inode_nlink(inode_item, nlink);
455         btrfs_set_stack_timespec_sec(&inode_item->atime, now);
456         btrfs_set_stack_timespec_nsec(&inode_item->atime, 0);
457         btrfs_set_stack_timespec_sec(&inode_item->mtime, now);
458         btrfs_set_stack_timespec_nsec(&inode_item->mtime, 0);
459         btrfs_set_stack_timespec_sec(&inode_item->ctime, now);
460         btrfs_set_stack_timespec_nsec(&inode_item->ctime, 0);
461 }
462
463 /*
464  * Unlike kernel btrfs_new_inode(), we only create the INODE_ITEM, without
465  * its backref.
466  * The backref is added by btrfs_add_link().
467  */
468 int btrfs_new_inode(struct btrfs_trans_handle *trans, struct btrfs_root *root,
469                 u64 ino, u32 mode)
470 {
471         struct btrfs_inode_item inode_item = {0};
472         int ret = 0;
473
474         fill_inode_item(trans, &inode_item, mode, 0);
475         ret = btrfs_insert_inode(trans, root, ino, &inode_item);
476         return ret;
477 }
478
479 /*
480  * Change inode flags to given value
481  */
482 int btrfs_change_inode_flags(struct btrfs_trans_handle *trans,
483                              struct btrfs_root *root, u64 ino, u64 flags)
484 {
485         struct btrfs_inode_item *item;
486         struct btrfs_path *path;
487         struct btrfs_key key;
488         int ret;
489
490         path = btrfs_alloc_path();
491         if (!path)
492                 return -ENOMEM;
493
494         key.objectid = ino;
495         key.type = BTRFS_INODE_ITEM_KEY;
496         key.offset = 0;
497
498         ret = btrfs_search_slot(trans, root, &key, path, 0, 1);
499         if (ret > 0) {
500                 ret = -ENOENT;
501                 goto out;
502         }
503         if (ret < 0)
504                 goto out;
505
506         item = btrfs_item_ptr(path->nodes[0], path->slots[0],
507                               struct btrfs_inode_item);
508         btrfs_set_inode_flags(path->nodes[0], item, flags);
509         btrfs_mark_buffer_dirty(path->nodes[0]);
510 out:
511         btrfs_free_path(path);
512         return ret;
513 }
514
515 /*
516  * Make a dir under the parent inode 'parent_ino' with 'name'
517  * and 'mode', The owner will be root/root.
518  */
519 int btrfs_mkdir(struct btrfs_trans_handle *trans, struct btrfs_root *root,
520                 char *name, int namelen, u64 parent_ino, u64 *ino, int mode)
521 {
522         struct btrfs_dir_item *dir_item;
523         struct btrfs_path *path;
524         u64 ret_ino = 0;
525         int ret = 0;
526
527         path = btrfs_alloc_path();
528         if (!path)
529                 return -ENOMEM;
530
531         if (ino && *ino)
532                 ret_ino = *ino;
533
534         dir_item = btrfs_lookup_dir_item(NULL, root, path, parent_ino,
535                                          name, namelen, 0);
536         if (IS_ERR(dir_item)) {
537                 ret = PTR_ERR(dir_item);
538                 goto out;
539         }
540
541         if (dir_item) {
542                 struct btrfs_key found_key;
543
544                 /*
545                  * Already have conflicting name, check if it is a dir.
546                  * Either way, no need to continue.
547                  */
548                 btrfs_dir_item_key_to_cpu(path->nodes[0], dir_item, &found_key);
549                 ret_ino = found_key.objectid;
550                 if (btrfs_dir_type(path->nodes[0], dir_item) != BTRFS_FT_DIR)
551                         ret = -EEXIST;
552                 goto out;
553         }
554
555         if (!ret_ino)
556                 /*
557                  * This is *UNSAFE* if some leaf is corrupted,
558                  * only used as a fallback method. Caller should either
559                  * ensure the fs is OK or pass ino with unused inode number.
560                  */
561                 ret = btrfs_find_free_objectid(NULL, root, parent_ino,
562                                                &ret_ino);
563         if (ret)
564                 goto out;
565         ret = btrfs_new_inode(trans, root, ret_ino, mode | S_IFDIR);
566         if (ret)
567                 goto out;
568         ret = btrfs_add_link(trans, root, ret_ino, parent_ino, name, namelen,
569                              BTRFS_FT_DIR, NULL, 1, 0);
570         if (ret)
571                 goto out;
572 out:
573         btrfs_free_path(path);
574         if (ret == 0 && ino)
575                 *ino = ret_ino;
576         return ret;
577 }
578
579 struct btrfs_root *btrfs_mksubvol(struct btrfs_root *root,
580                                   const char *base, u64 root_objectid,
581                                   bool convert)
582 {
583         struct btrfs_trans_handle *trans;
584         struct btrfs_fs_info *fs_info = root->fs_info;
585         struct btrfs_root *tree_root = fs_info->tree_root;
586         struct btrfs_root *new_root = NULL;
587         struct btrfs_path path;
588         struct btrfs_inode_item *inode_item;
589         struct extent_buffer *leaf;
590         struct btrfs_key key;
591         u64 dirid = btrfs_root_dirid(&root->root_item);
592         u64 index = 2;
593         char buf[BTRFS_NAME_LEN + 1]; /* for snprintf null */
594         int len;
595         int i;
596         int ret;
597
598         len = strlen(base);
599         if (len == 0 || len > BTRFS_NAME_LEN)
600                 return NULL;
601
602         btrfs_init_path(&path);
603         key.objectid = dirid;
604         key.type = BTRFS_DIR_INDEX_KEY;
605         key.offset = (u64)-1;
606
607         ret = btrfs_search_slot(NULL, root, &key, &path, 0, 0);
608         if (ret <= 0) {
609                 error("search for DIR_INDEX dirid %llu failed: %d",
610                                 (unsigned long long)dirid, ret);
611                 goto fail;
612         }
613
614         if (path.slots[0] > 0) {
615                 path.slots[0]--;
616                 btrfs_item_key_to_cpu(path.nodes[0], &key, path.slots[0]);
617                 if (key.objectid == dirid && key.type == BTRFS_DIR_INDEX_KEY)
618                         index = key.offset + 1;
619         }
620         btrfs_release_path(&path);
621
622         trans = btrfs_start_transaction(root, 1);
623         if (IS_ERR(trans)) {
624                 error("unable to start transaction");
625                 goto fail;
626         }
627
628         key.objectid = dirid;
629         key.offset = 0;
630         key.type =  BTRFS_INODE_ITEM_KEY;
631
632         ret = btrfs_lookup_inode(trans, root, &path, &key, 1);
633         if (ret) {
634                 error("search for INODE_ITEM %llu failed: %d",
635                                 (unsigned long long)dirid, ret);
636                 goto fail;
637         }
638         leaf = path.nodes[0];
639         inode_item = btrfs_item_ptr(leaf, path.slots[0],
640                                     struct btrfs_inode_item);
641
642         key.objectid = root_objectid;
643         key.offset = (u64)-1;
644         key.type = BTRFS_ROOT_ITEM_KEY;
645
646         memcpy(buf, base, len);
647         if (convert) {
648                 for (i = 0; i < 1024; i++) {
649                         ret = btrfs_insert_dir_item(trans, root, buf, len,
650                                         dirid, &key, BTRFS_FT_DIR, index);
651                         if (ret != -EEXIST)
652                                 break;
653                         len = snprintf(buf, ARRAY_SIZE(buf), "%s%d", base, i);
654                         if (len < 1 || len > BTRFS_NAME_LEN) {
655                                 ret = -EINVAL;
656                                 break;
657                         }
658                 }
659         } else {
660                 ret = btrfs_insert_dir_item(trans, root, buf, len, dirid, &key,
661                                             BTRFS_FT_DIR, index);
662         }
663         if (ret)
664                 goto fail;
665
666         btrfs_set_inode_size(leaf, inode_item, len * 2 +
667                              btrfs_inode_size(leaf, inode_item));
668         btrfs_mark_buffer_dirty(leaf);
669         btrfs_release_path(&path);
670
671         /* add the backref first */
672         ret = btrfs_add_root_ref(trans, tree_root, root_objectid,
673                                  BTRFS_ROOT_BACKREF_KEY,
674                                  root->root_key.objectid,
675                                  dirid, index, buf, len);
676         if (ret) {
677                 error("unable to add root backref for %llu: %d",
678                                 root->root_key.objectid, ret);
679                 goto fail;
680         }
681
682         /* now add the forward ref */
683         ret = btrfs_add_root_ref(trans, tree_root, root->root_key.objectid,
684                                  BTRFS_ROOT_REF_KEY, root_objectid,
685                                  dirid, index, buf, len);
686         if (ret) {
687                 error("unable to add root ref for %llu: %d",
688                                 root->root_key.objectid, ret);
689                 goto fail;
690         }
691
692         ret = btrfs_commit_transaction(trans, root);
693         if (ret) {
694                 error("transaction commit failed: %d", ret);
695                 goto fail;
696         }
697
698         new_root = btrfs_read_fs_root(fs_info, &key);
699         if (IS_ERR(new_root)) {
700                 error("unable to fs read root: %lu", PTR_ERR(new_root));
701                 new_root = NULL;
702         }
703 fail:
704         btrfs_init_path(&path);
705         return new_root;
706 }