LCOV - code coverage report
Current view: top level - fs/btrfs - root-tree.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 196 0.0 %
Date: 2014-02-18 Functions: 0 12 0.0 %
Branches: 0 102 0.0 %

           Branch data     Line data    Source code
       1                 :            : /*
       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                 :            : 
      19                 :            : #include <linux/uuid.h>
      20                 :            : #include "ctree.h"
      21                 :            : #include "transaction.h"
      22                 :            : #include "disk-io.h"
      23                 :            : #include "print-tree.h"
      24                 :            : 
      25                 :            : /*
      26                 :            :  * Read a root item from the tree. In case we detect a root item smaller then
      27                 :            :  * sizeof(root_item), we know it's an old version of the root structure and
      28                 :            :  * initialize all new fields to zero. The same happens if we detect mismatching
      29                 :            :  * generation numbers as then we know the root was once mounted with an older
      30                 :            :  * kernel that was not aware of the root item structure change.
      31                 :            :  */
      32                 :          0 : static void btrfs_read_root_item(struct extent_buffer *eb, int slot,
      33                 :            :                                 struct btrfs_root_item *item)
      34                 :            : {
      35                 :            :         uuid_le uuid;
      36                 :            :         int len;
      37                 :            :         int need_reset = 0;
      38                 :            : 
      39                 :          0 :         len = btrfs_item_size_nr(eb, slot);
      40                 :          0 :         read_extent_buffer(eb, item, btrfs_item_ptr_offset(eb, slot),
      41                 :          0 :                         min_t(int, len, (int)sizeof(*item)));
      42         [ #  # ]:          0 :         if (len < sizeof(*item))
      43                 :            :                 need_reset = 1;
      44 [ #  # ][ #  # ]:          0 :         if (!need_reset && btrfs_root_generation(item)
      45                 :            :                 != btrfs_root_generation_v2(item)) {
      46         [ #  # ]:          0 :                 if (btrfs_root_generation_v2(item) != 0) {
      47                 :          0 :                         printk(KERN_WARNING "btrfs: mismatching "
      48                 :            :                                         "generation and generation_v2 "
      49                 :            :                                         "found in root item. This root "
      50                 :            :                                         "was probably mounted with an "
      51                 :            :                                         "older kernel. Resetting all "
      52                 :            :                                         "new fields.\n");
      53                 :            :                 }
      54                 :            :                 need_reset = 1;
      55                 :            :         }
      56         [ #  # ]:          0 :         if (need_reset) {
      57                 :          0 :                 memset(&item->generation_v2, 0,
      58                 :            :                         sizeof(*item) - offsetof(struct btrfs_root_item,
      59                 :            :                                         generation_v2));
      60                 :            : 
      61                 :          0 :                 uuid_le_gen(&uuid);
      62                 :          0 :                 memcpy(item->uuid, uuid.b, BTRFS_UUID_SIZE);
      63                 :            :         }
      64                 :          0 : }
      65                 :            : 
      66                 :            : /*
      67                 :            :  * btrfs_find_root - lookup the root by the key.
      68                 :            :  * root: the root of the root tree
      69                 :            :  * search_key: the key to search
      70                 :            :  * path: the path we search
      71                 :            :  * root_item: the root item of the tree we look for
      72                 :            :  * root_key: the reak key of the tree we look for
      73                 :            :  *
      74                 :            :  * If ->offset of 'seach_key' is -1ULL, it means we are not sure the offset
      75                 :            :  * of the search key, just lookup the root with the highest offset for a
      76                 :            :  * given objectid.
      77                 :            :  *
      78                 :            :  * If we find something return 0, otherwise > 0, < 0 on error.
      79                 :            :  */
      80                 :          0 : int btrfs_find_root(struct btrfs_root *root, struct btrfs_key *search_key,
      81                 :            :                     struct btrfs_path *path, struct btrfs_root_item *root_item,
      82                 :            :                     struct btrfs_key *root_key)
      83                 :            : {
      84                 :            :         struct btrfs_key found_key;
      85                 :            :         struct extent_buffer *l;
      86                 :            :         int ret;
      87                 :            :         int slot;
      88                 :            : 
      89                 :          0 :         ret = btrfs_search_slot(NULL, root, search_key, path, 0, 0);
      90         [ #  # ]:          0 :         if (ret < 0)
      91                 :            :                 return ret;
      92                 :            : 
      93         [ #  # ]:          0 :         if (search_key->offset != -1ULL) {   /* the search key is exact */
      94         [ #  # ]:          0 :                 if (ret > 0)
      95                 :            :                         goto out;
      96                 :            :         } else {
      97         [ #  # ]:          0 :                 BUG_ON(ret == 0);               /* Logical error */
      98         [ #  # ]:          0 :                 if (path->slots[0] == 0)
      99                 :            :                         goto out;
     100                 :          0 :                 path->slots[0]--;
     101                 :            :                 ret = 0;
     102                 :            :         }
     103                 :            : 
     104                 :          0 :         l = path->nodes[0];
     105                 :          0 :         slot = path->slots[0];
     106                 :            : 
     107                 :            :         btrfs_item_key_to_cpu(l, &found_key, slot);
     108 [ #  # ][ #  # ]:          0 :         if (found_key.objectid != search_key->objectid ||
     109                 :            :             found_key.type != BTRFS_ROOT_ITEM_KEY) {
     110                 :            :                 ret = 1;
     111                 :            :                 goto out;
     112                 :            :         }
     113                 :            : 
     114         [ #  # ]:          0 :         if (root_item)
     115                 :          0 :                 btrfs_read_root_item(l, slot, root_item);
     116         [ #  # ]:          0 :         if (root_key)
     117                 :          0 :                 memcpy(root_key, &found_key, sizeof(found_key));
     118                 :            : out:
     119                 :          0 :         btrfs_release_path(path);
     120                 :          0 :         return ret;
     121                 :            : }
     122                 :            : 
     123                 :          0 : void btrfs_set_root_node(struct btrfs_root_item *item,
     124                 :          0 :                          struct extent_buffer *node)
     125                 :            : {
     126                 :          0 :         btrfs_set_root_bytenr(item, node->start);
     127                 :            :         btrfs_set_root_level(item, btrfs_header_level(node));
     128                 :            :         btrfs_set_root_generation(item, btrfs_header_generation(node));
     129                 :          0 : }
     130                 :            : 
     131                 :            : /*
     132                 :            :  * copy the data in 'item' into the btree
     133                 :            :  */
     134                 :          0 : int btrfs_update_root(struct btrfs_trans_handle *trans, struct btrfs_root
     135                 :            :                       *root, struct btrfs_key *key, struct btrfs_root_item
     136                 :            :                       *item)
     137                 :            : {
     138                 :            :         struct btrfs_path *path;
     139                 :            :         struct extent_buffer *l;
     140                 :            :         int ret;
     141                 :            :         int slot;
     142                 :            :         unsigned long ptr;
     143                 :            :         int old_len;
     144                 :            : 
     145                 :          0 :         path = btrfs_alloc_path();
     146         [ #  # ]:          0 :         if (!path)
     147                 :            :                 return -ENOMEM;
     148                 :            : 
     149                 :          0 :         ret = btrfs_search_slot(trans, root, key, path, 0, 1);
     150         [ #  # ]:          0 :         if (ret < 0) {
     151                 :          0 :                 btrfs_abort_transaction(trans, root, ret);
     152                 :          0 :                 goto out;
     153                 :            :         }
     154                 :            : 
     155         [ #  # ]:          0 :         if (ret != 0) {
     156                 :          0 :                 btrfs_print_leaf(root, path->nodes[0]);
     157                 :          0 :                 printk(KERN_CRIT "unable to update root key %llu %u %llu\n",
     158                 :          0 :                        key->objectid, key->type, key->offset);
     159                 :          0 :                 BUG_ON(1);
     160                 :            :         }
     161                 :            : 
     162                 :          0 :         l = path->nodes[0];
     163                 :          0 :         slot = path->slots[0];
     164                 :          0 :         ptr = btrfs_item_ptr_offset(l, slot);
     165                 :            :         old_len = btrfs_item_size_nr(l, slot);
     166                 :            : 
     167                 :            :         /*
     168                 :            :          * If this is the first time we update the root item which originated
     169                 :            :          * from an older kernel, we need to enlarge the item size to make room
     170                 :            :          * for the added fields.
     171                 :            :          */
     172         [ #  # ]:          0 :         if (old_len < sizeof(*item)) {
     173                 :          0 :                 btrfs_release_path(path);
     174                 :          0 :                 ret = btrfs_search_slot(trans, root, key, path,
     175                 :            :                                 -1, 1);
     176         [ #  # ]:          0 :                 if (ret < 0) {
     177                 :          0 :                         btrfs_abort_transaction(trans, root, ret);
     178                 :          0 :                         goto out;
     179                 :            :                 }
     180                 :            : 
     181                 :            :                 ret = btrfs_del_item(trans, root, path);
     182         [ #  # ]:          0 :                 if (ret < 0) {
     183                 :          0 :                         btrfs_abort_transaction(trans, root, ret);
     184                 :          0 :                         goto out;
     185                 :            :                 }
     186                 :          0 :                 btrfs_release_path(path);
     187                 :            :                 ret = btrfs_insert_empty_item(trans, root, path,
     188                 :            :                                 key, sizeof(*item));
     189         [ #  # ]:          0 :                 if (ret < 0) {
     190                 :          0 :                         btrfs_abort_transaction(trans, root, ret);
     191                 :          0 :                         goto out;
     192                 :            :                 }
     193                 :          0 :                 l = path->nodes[0];
     194                 :          0 :                 slot = path->slots[0];
     195                 :          0 :                 ptr = btrfs_item_ptr_offset(l, slot);
     196                 :            :         }
     197                 :            : 
     198                 :            :         /*
     199                 :            :          * Update generation_v2 so at the next mount we know the new root
     200                 :            :          * fields are valid.
     201                 :            :          */
     202                 :            :         btrfs_set_root_generation_v2(item, btrfs_root_generation(item));
     203                 :            : 
     204                 :          0 :         write_extent_buffer(l, item, ptr, sizeof(*item));
     205                 :          0 :         btrfs_mark_buffer_dirty(path->nodes[0]);
     206                 :            : out:
     207                 :          0 :         btrfs_free_path(path);
     208                 :          0 :         return ret;
     209                 :            : }
     210                 :            : 
     211                 :          0 : int btrfs_insert_root(struct btrfs_trans_handle *trans, struct btrfs_root *root,
     212                 :            :                       struct btrfs_key *key, struct btrfs_root_item *item)
     213                 :            : {
     214                 :            :         /*
     215                 :            :          * Make sure generation v1 and v2 match. See update_root for details.
     216                 :            :          */
     217                 :            :         btrfs_set_root_generation_v2(item, btrfs_root_generation(item));
     218                 :          0 :         return btrfs_insert_item(trans, root, key, item, sizeof(*item));
     219                 :            : }
     220                 :            : 
     221                 :          0 : int btrfs_find_orphan_roots(struct btrfs_root *tree_root)
     222                 :            : {
     223                 :          0 :         struct extent_buffer *leaf;
     224                 :            :         struct btrfs_path *path;
     225                 :            :         struct btrfs_key key;
     226                 :            :         struct btrfs_key root_key;
     227                 :            :         struct btrfs_root *root;
     228                 :            :         int err = 0;
     229                 :            :         int ret;
     230                 :            :         bool can_recover = true;
     231                 :            : 
     232                 :            :         if (tree_root->fs_info->sb->s_flags & MS_RDONLY)
     233                 :            :                 can_recover = false;
     234                 :            : 
     235                 :          0 :         path = btrfs_alloc_path();
     236         [ #  # ]:          0 :         if (!path)
     237                 :            :                 return -ENOMEM;
     238                 :            : 
     239                 :          0 :         key.objectid = BTRFS_ORPHAN_OBJECTID;
     240                 :          0 :         key.type = BTRFS_ORPHAN_ITEM_KEY;
     241                 :          0 :         key.offset = 0;
     242                 :            : 
     243                 :          0 :         root_key.type = BTRFS_ROOT_ITEM_KEY;
     244                 :          0 :         root_key.offset = (u64)-1;
     245                 :            : 
     246                 :            :         while (1) {
     247                 :          0 :                 ret = btrfs_search_slot(NULL, tree_root, &key, path, 0, 0);
     248         [ #  # ]:          0 :                 if (ret < 0) {
     249                 :            :                         err = ret;
     250                 :            :                         break;
     251                 :            :                 }
     252                 :            : 
     253                 :          0 :                 leaf = path->nodes[0];
     254         [ #  # ]:          0 :                 if (path->slots[0] >= btrfs_header_nritems(leaf)) {
     255                 :          0 :                         ret = btrfs_next_leaf(tree_root, path);
     256         [ #  # ]:          0 :                         if (ret < 0)
     257                 :            :                                 err = ret;
     258         [ #  # ]:          0 :                         if (ret != 0)
     259                 :            :                                 break;
     260                 :          0 :                         leaf = path->nodes[0];
     261                 :            :                 }
     262                 :            : 
     263                 :          0 :                 btrfs_item_key_to_cpu(leaf, &key, path->slots[0]);
     264                 :          0 :                 btrfs_release_path(path);
     265                 :            : 
     266 [ #  # ][ #  # ]:          0 :                 if (key.objectid != BTRFS_ORPHAN_OBJECTID ||
     267                 :          0 :                     key.type != BTRFS_ORPHAN_ITEM_KEY)
     268                 :            :                         break;
     269                 :            : 
     270                 :          0 :                 root_key.objectid = key.offset;
     271                 :          0 :                 key.offset++;
     272                 :            : 
     273                 :          0 :                 root = btrfs_read_fs_root(tree_root, &root_key);
     274                 :            :                 err = PTR_RET(root);
     275         [ #  # ]:          0 :                 if (err && err != -ENOENT) {
     276                 :            :                         break;
     277         [ #  # ]:          0 :                 } else if (err == -ENOENT) {
     278                 :            :                         struct btrfs_trans_handle *trans;
     279                 :            : 
     280                 :          0 :                         btrfs_release_path(path);
     281                 :            : 
     282                 :          0 :                         trans = btrfs_join_transaction(tree_root);
     283         [ #  # ]:          0 :                         if (IS_ERR(trans)) {
     284                 :            :                                 err = PTR_ERR(trans);
     285                 :          0 :                                 btrfs_error(tree_root->fs_info, err,
     286                 :            :                                             "Failed to start trans to delete "
     287                 :            :                                             "orphan item");
     288                 :          0 :                                 break;
     289                 :            :                         }
     290                 :          0 :                         err = btrfs_del_orphan_item(trans, tree_root,
     291                 :            :                                                     root_key.objectid);
     292                 :          0 :                         btrfs_end_transaction(trans, tree_root);
     293         [ #  # ]:          0 :                         if (err) {
     294                 :          0 :                                 btrfs_error(tree_root->fs_info, err,
     295                 :            :                                             "Failed to delete root orphan "
     296                 :            :                                             "item");
     297                 :          0 :                                 break;
     298                 :            :                         }
     299                 :          0 :                         continue;
     300                 :            :                 }
     301                 :            : 
     302                 :          0 :                 err = btrfs_init_fs_root(root);
     303         [ #  # ]:          0 :                 if (err) {
     304                 :          0 :                         btrfs_free_fs_root(root);
     305                 :          0 :                         break;
     306                 :            :                 }
     307                 :            : 
     308                 :          0 :                 root->orphan_item_inserted = 1;
     309                 :            : 
     310                 :          0 :                 err = btrfs_insert_fs_root(root->fs_info, root);
     311         [ #  # ]:          0 :                 if (err) {
     312         [ #  # ]:          0 :                         BUG_ON(err == -EEXIST);
     313                 :          0 :                         btrfs_free_fs_root(root);
     314                 :          0 :                         break;
     315                 :            :                 }
     316                 :            : 
     317         [ #  # ]:          0 :                 if (btrfs_root_refs(&root->root_item) == 0)
     318                 :          0 :                         btrfs_add_dead_root(root);
     319                 :            :         }
     320                 :            : 
     321                 :          0 :         btrfs_free_path(path);
     322                 :          0 :         return err;
     323                 :            : }
     324                 :            : 
     325                 :            : /* drop the root item for 'key' from 'root' */
     326                 :          0 : int btrfs_del_root(struct btrfs_trans_handle *trans, struct btrfs_root *root,
     327                 :            :                    struct btrfs_key *key)
     328                 :            : {
     329                 :            :         struct btrfs_path *path;
     330                 :            :         int ret;
     331                 :            : 
     332                 :          0 :         path = btrfs_alloc_path();
     333         [ #  # ]:          0 :         if (!path)
     334                 :            :                 return -ENOMEM;
     335                 :          0 :         ret = btrfs_search_slot(trans, root, key, path, -1, 1);
     336         [ #  # ]:          0 :         if (ret < 0)
     337                 :            :                 goto out;
     338                 :            : 
     339         [ #  # ]:          0 :         BUG_ON(ret != 0);
     340                 :            : 
     341                 :            :         ret = btrfs_del_item(trans, root, path);
     342                 :            : out:
     343                 :          0 :         btrfs_free_path(path);
     344                 :          0 :         return ret;
     345                 :            : }
     346                 :            : 
     347                 :          0 : int btrfs_del_root_ref(struct btrfs_trans_handle *trans,
     348                 :            :                        struct btrfs_root *tree_root,
     349                 :            :                        u64 root_id, u64 ref_id, u64 dirid, u64 *sequence,
     350                 :            :                        const char *name, int name_len)
     351                 :            : 
     352                 :            : {
     353                 :            :         struct btrfs_path *path;
     354                 :            :         struct btrfs_root_ref *ref;
     355                 :            :         struct extent_buffer *leaf;
     356                 :            :         struct btrfs_key key;
     357                 :            :         unsigned long ptr;
     358                 :            :         int err = 0;
     359                 :            :         int ret;
     360                 :            : 
     361                 :          0 :         path = btrfs_alloc_path();
     362         [ #  # ]:          0 :         if (!path)
     363                 :            :                 return -ENOMEM;
     364                 :            : 
     365                 :          0 :         key.objectid = root_id;
     366                 :          0 :         key.type = BTRFS_ROOT_BACKREF_KEY;
     367                 :          0 :         key.offset = ref_id;
     368                 :            : again:
     369                 :          0 :         ret = btrfs_search_slot(trans, tree_root, &key, path, -1, 1);
     370         [ #  # ]:          0 :         BUG_ON(ret < 0);
     371         [ #  # ]:          0 :         if (ret == 0) {
     372                 :          0 :                 leaf = path->nodes[0];
     373                 :          0 :                 ref = btrfs_item_ptr(leaf, path->slots[0],
     374                 :            :                                      struct btrfs_root_ref);
     375                 :            : 
     376         [ #  # ]:          0 :                 WARN_ON(btrfs_root_ref_dirid(leaf, ref) != dirid);
     377         [ #  # ]:          0 :                 WARN_ON(btrfs_root_ref_name_len(leaf, ref) != name_len);
     378                 :          0 :                 ptr = (unsigned long)(ref + 1);
     379         [ #  # ]:          0 :                 WARN_ON(memcmp_extent_buffer(leaf, name, ptr, name_len));
     380                 :          0 :                 *sequence = btrfs_root_ref_sequence(leaf, ref);
     381                 :            : 
     382                 :            :                 ret = btrfs_del_item(trans, tree_root, path);
     383         [ #  # ]:          0 :                 if (ret) {
     384                 :            :                         err = ret;
     385                 :            :                         goto out;
     386                 :            :                 }
     387                 :            :         } else
     388                 :            :                 err = -ENOENT;
     389                 :            : 
     390         [ #  # ]:          0 :         if (key.type == BTRFS_ROOT_BACKREF_KEY) {
     391                 :          0 :                 btrfs_release_path(path);
     392                 :          0 :                 key.objectid = ref_id;
     393                 :          0 :                 key.type = BTRFS_ROOT_REF_KEY;
     394                 :          0 :                 key.offset = root_id;
     395                 :          0 :                 goto again;
     396                 :            :         }
     397                 :            : 
     398                 :            : out:
     399                 :          0 :         btrfs_free_path(path);
     400                 :          0 :         return err;
     401                 :            : }
     402                 :            : 
     403                 :          0 : int btrfs_find_root_ref(struct btrfs_root *tree_root,
     404                 :            :                    struct btrfs_path *path,
     405                 :            :                    u64 root_id, u64 ref_id)
     406                 :            : {
     407                 :            :         struct btrfs_key key;
     408                 :            :         int ret;
     409                 :            : 
     410                 :          0 :         key.objectid = root_id;
     411                 :          0 :         key.type = BTRFS_ROOT_REF_KEY;
     412                 :          0 :         key.offset = ref_id;
     413                 :            : 
     414                 :          0 :         ret = btrfs_search_slot(NULL, tree_root, &key, path, 0, 0);
     415                 :          0 :         return ret;
     416                 :            : }
     417                 :            : 
     418                 :            : /*
     419                 :            :  * add a btrfs_root_ref item.  type is either BTRFS_ROOT_REF_KEY
     420                 :            :  * or BTRFS_ROOT_BACKREF_KEY.
     421                 :            :  *
     422                 :            :  * The dirid, sequence, name and name_len refer to the directory entry
     423                 :            :  * that is referencing the root.
     424                 :            :  *
     425                 :            :  * For a forward ref, the root_id is the id of the tree referencing
     426                 :            :  * the root and ref_id is the id of the subvol  or snapshot.
     427                 :            :  *
     428                 :            :  * For a back ref the root_id is the id of the subvol or snapshot and
     429                 :            :  * ref_id is the id of the tree referencing it.
     430                 :            :  *
     431                 :            :  * Will return 0, -ENOMEM, or anything from the CoW path
     432                 :            :  */
     433                 :          0 : int btrfs_add_root_ref(struct btrfs_trans_handle *trans,
     434                 :            :                        struct btrfs_root *tree_root,
     435                 :            :                        u64 root_id, u64 ref_id, u64 dirid, u64 sequence,
     436                 :            :                        const char *name, int name_len)
     437                 :            : {
     438                 :            :         struct btrfs_key key;
     439                 :            :         int ret;
     440                 :            :         struct btrfs_path *path;
     441                 :            :         struct btrfs_root_ref *ref;
     442                 :            :         struct extent_buffer *leaf;
     443                 :            :         unsigned long ptr;
     444                 :            : 
     445                 :          0 :         path = btrfs_alloc_path();
     446         [ #  # ]:          0 :         if (!path)
     447                 :            :                 return -ENOMEM;
     448                 :            : 
     449                 :          0 :         key.objectid = root_id;
     450                 :          0 :         key.type = BTRFS_ROOT_BACKREF_KEY;
     451                 :          0 :         key.offset = ref_id;
     452                 :            : again:
     453                 :          0 :         ret = btrfs_insert_empty_item(trans, tree_root, path, &key,
     454                 :            :                                       sizeof(*ref) + name_len);
     455         [ #  # ]:          0 :         if (ret) {
     456                 :          0 :                 btrfs_abort_transaction(trans, tree_root, ret);
     457                 :          0 :                 btrfs_free_path(path);
     458                 :          0 :                 return ret;
     459                 :            :         }
     460                 :            : 
     461                 :          0 :         leaf = path->nodes[0];
     462                 :          0 :         ref = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_root_ref);
     463                 :            :         btrfs_set_root_ref_dirid(leaf, ref, dirid);
     464                 :            :         btrfs_set_root_ref_sequence(leaf, ref, sequence);
     465                 :          0 :         btrfs_set_root_ref_name_len(leaf, ref, name_len);
     466                 :          0 :         ptr = (unsigned long)(ref + 1);
     467                 :          0 :         write_extent_buffer(leaf, name, ptr, name_len);
     468                 :          0 :         btrfs_mark_buffer_dirty(leaf);
     469                 :            : 
     470         [ #  # ]:          0 :         if (key.type == BTRFS_ROOT_BACKREF_KEY) {
     471                 :          0 :                 btrfs_release_path(path);
     472                 :          0 :                 key.objectid = ref_id;
     473                 :          0 :                 key.type = BTRFS_ROOT_REF_KEY;
     474                 :          0 :                 key.offset = root_id;
     475                 :          0 :                 goto again;
     476                 :            :         }
     477                 :            : 
     478                 :          0 :         btrfs_free_path(path);
     479                 :          0 :         return 0;
     480                 :            : }
     481                 :            : 
     482                 :            : /*
     483                 :            :  * Old btrfs forgets to init root_item->flags and root_item->byte_limit
     484                 :            :  * for subvolumes. To work around this problem, we steal a bit from
     485                 :            :  * root_item->inode_item->flags, and use it to indicate if those fields
     486                 :            :  * have been properly initialized.
     487                 :            :  */
     488                 :          0 : void btrfs_check_and_init_root_item(struct btrfs_root_item *root_item)
     489                 :            : {
     490                 :            :         u64 inode_flags = btrfs_stack_inode_flags(&root_item->inode);
     491                 :            : 
     492         [ #  # ]:          0 :         if (!(inode_flags & BTRFS_INODE_ROOT_ITEM_INIT)) {
     493                 :          0 :                 inode_flags |= BTRFS_INODE_ROOT_ITEM_INIT;
     494                 :            :                 btrfs_set_stack_inode_flags(&root_item->inode, inode_flags);
     495                 :            :                 btrfs_set_root_flags(root_item, 0);
     496                 :            :                 btrfs_set_root_limit(root_item, 0);
     497                 :            :         }
     498                 :          0 : }
     499                 :            : 
     500                 :          0 : void btrfs_update_root_times(struct btrfs_trans_handle *trans,
     501                 :            :                              struct btrfs_root *root)
     502                 :            : {
     503                 :            :         struct btrfs_root_item *item = &root->root_item;
     504                 :          0 :         struct timespec ct = CURRENT_TIME;
     505                 :            : 
     506                 :            :         spin_lock(&root->root_item_lock);
     507                 :          0 :         btrfs_set_root_ctransid(item, trans->transid);
     508                 :          0 :         btrfs_set_stack_timespec_sec(&item->ctime, ct.tv_sec);
     509                 :          0 :         btrfs_set_stack_timespec_nsec(&item->ctime, ct.tv_nsec);
     510                 :            :         spin_unlock(&root->root_item_lock);
     511                 :          0 : }

Generated by: LCOV version 1.9