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