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/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 */
  32static 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        len = btrfs_item_size_nr(eb, slot);
  40        read_extent_buffer(eb, item, btrfs_item_ptr_offset(eb, slot),
  41                        min_t(int, len, (int)sizeof(*item)));
  42        if (len < sizeof(*item))
  43                need_reset = 1;
  44        if (!need_reset && btrfs_root_generation(item)
  45                != btrfs_root_generation_v2(item)) {
  46                if (btrfs_root_generation_v2(item) != 0) {
  47                        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        if (need_reset) {
  57                memset(&item->generation_v2, 0,
  58                        sizeof(*item) - offsetof(struct btrfs_root_item,
  59                                        generation_v2));
  60
  61                uuid_le_gen(&uuid);
  62                memcpy(item->uuid, uuid.b, BTRFS_UUID_SIZE);
  63        }
  64}
  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 */
  80int 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        ret = btrfs_search_slot(NULL, root, search_key, path, 0, 0);
  90        if (ret < 0)
  91                return ret;
  92
  93        if (search_key->offset != -1ULL) {      /* the search key is exact */
  94                if (ret > 0)
  95                        goto out;
  96        } else {
  97                BUG_ON(ret == 0);               /* Logical error */
  98                if (path->slots[0] == 0)
  99                        goto out;
 100                path->slots[0]--;
 101                ret = 0;
 102        }
 103
 104        l = path->nodes[0];
 105        slot = path->slots[0];
 106
 107        btrfs_item_key_to_cpu(l, &found_key, slot);
 108        if (found_key.objectid != search_key->objectid ||
 109            found_key.type != BTRFS_ROOT_ITEM_KEY) {
 110                ret = 1;
 111                goto out;
 112        }
 113
 114        if (root_item)
 115                btrfs_read_root_item(l, slot, root_item);
 116        if (root_key)
 117                memcpy(root_key, &found_key, sizeof(found_key));
 118out:
 119        btrfs_release_path(path);
 120        return ret;
 121}
 122
 123void btrfs_set_root_node(struct btrfs_root_item *item,
 124                         struct extent_buffer *node)
 125{
 126        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}
 130
 131/*
 132 * copy the data in 'item' into the btree
 133 */
 134int 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        path = btrfs_alloc_path();
 146        if (!path)
 147                return -ENOMEM;
 148
 149        ret = btrfs_search_slot(trans, root, key, path, 0, 1);
 150        if (ret < 0) {
 151                btrfs_abort_transaction(trans, root, ret);
 152                goto out;
 153        }
 154
 155        if (ret != 0) {
 156                btrfs_print_leaf(root, path->nodes[0]);
 157                printk(KERN_CRIT "unable to update root key %llu %u %llu\n",
 158                       key->objectid, key->type, key->offset);
 159                BUG_ON(1);
 160        }
 161
 162        l = path->nodes[0];
 163        slot = path->slots[0];
 164        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        if (old_len < sizeof(*item)) {
 173                btrfs_release_path(path);
 174                ret = btrfs_search_slot(trans, root, key, path,
 175                                -1, 1);
 176                if (ret < 0) {
 177                        btrfs_abort_transaction(trans, root, ret);
 178                        goto out;
 179                }
 180
 181                ret = btrfs_del_item(trans, root, path);
 182                if (ret < 0) {
 183                        btrfs_abort_transaction(trans, root, ret);
 184                        goto out;
 185                }
 186                btrfs_release_path(path);
 187                ret = btrfs_insert_empty_item(trans, root, path,
 188                                key, sizeof(*item));
 189                if (ret < 0) {
 190                        btrfs_abort_transaction(trans, root, ret);
 191                        goto out;
 192                }
 193                l = path->nodes[0];
 194                slot = path->slots[0];
 195                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        write_extent_buffer(l, item, ptr, sizeof(*item));
 205        btrfs_mark_buffer_dirty(path->nodes[0]);
 206out:
 207        btrfs_free_path(path);
 208        return ret;
 209}
 210
 211int 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        return btrfs_insert_item(trans, root, key, item, sizeof(*item));
 219}
 220
 221int btrfs_find_orphan_roots(struct btrfs_root *tree_root)
 222{
 223        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        path = btrfs_alloc_path();
 236        if (!path)
 237                return -ENOMEM;
 238
 239        key.objectid = BTRFS_ORPHAN_OBJECTID;
 240        key.type = BTRFS_ORPHAN_ITEM_KEY;
 241        key.offset = 0;
 242
 243        root_key.type = BTRFS_ROOT_ITEM_KEY;
 244        root_key.offset = (u64)-1;
 245
 246        while (1) {
 247                ret = btrfs_search_slot(NULL, tree_root, &key, path, 0, 0);
 248                if (ret < 0) {
 249                        err = ret;
 250                        break;
 251                }
 252
 253                leaf = path->nodes[0];
 254                if (path->slots[0] >= btrfs_header_nritems(leaf)) {
 255                        ret = btrfs_next_leaf(tree_root, path);
 256                        if (ret < 0)
 257                                err = ret;
 258                        if (ret != 0)
 259                                break;
 260                        leaf = path->nodes[0];
 261                }
 262
 263                btrfs_item_key_to_cpu(leaf, &key, path->slots[0]);
 264                btrfs_release_path(path);
 265
 266                if (key.objectid != BTRFS_ORPHAN_OBJECTID ||
 267                    key.type != BTRFS_ORPHAN_ITEM_KEY)
 268                        break;
 269
 270                root_key.objectid = key.offset;
 271                key.offset++;
 272
 273                root = btrfs_read_fs_root(tree_root, &root_key);
 274                err = PTR_RET(root);
 275                if (err && err != -ENOENT) {
 276                        break;
 277                } else if (err == -ENOENT) {
 278                        struct btrfs_trans_handle *trans;
 279
 280                        btrfs_release_path(path);
 281
 282                        trans = btrfs_join_transaction(tree_root);
 283                        if (IS_ERR(trans)) {
 284                                err = PTR_ERR(trans);
 285                                btrfs_error(tree_root->fs_info, err,
 286                                            "Failed to start trans to delete "
 287                                            "orphan item");
 288                                break;
 289                        }
 290                        err = btrfs_del_orphan_item(trans, tree_root,
 291                                                    root_key.objectid);
 292                        btrfs_end_transaction(trans, tree_root);
 293                        if (err) {
 294                                btrfs_error(tree_root->fs_info, err,
 295                                            "Failed to delete root orphan "
 296                                            "item");
 297                                break;
 298                        }
 299                        continue;
 300                }
 301
 302                err = btrfs_init_fs_root(root);
 303                if (err) {
 304                        btrfs_free_fs_root(root);
 305                        break;
 306                }
 307
 308                root->orphan_item_inserted = 1;
 309
 310                err = btrfs_insert_fs_root(root->fs_info, root);
 311                if (err) {
 312                        BUG_ON(err == -EEXIST);
 313                        btrfs_free_fs_root(root);
 314                        break;
 315                }
 316
 317                if (btrfs_root_refs(&root->root_item) == 0)
 318                        btrfs_add_dead_root(root);
 319        }
 320
 321        btrfs_free_path(path);
 322        return err;
 323}
 324
 325/* drop the root item for 'key' from 'root' */
 326int 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        path = btrfs_alloc_path();
 333        if (!path)
 334                return -ENOMEM;
 335        ret = btrfs_search_slot(trans, root, key, path, -1, 1);
 336        if (ret < 0)
 337                goto out;
 338
 339        BUG_ON(ret != 0);
 340
 341        ret = btrfs_del_item(trans, root, path);
 342out:
 343        btrfs_free_path(path);
 344        return ret;
 345}
 346
 347int 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        path = btrfs_alloc_path();
 362        if (!path)
 363                return -ENOMEM;
 364
 365        key.objectid = root_id;
 366        key.type = BTRFS_ROOT_BACKREF_KEY;
 367        key.offset = ref_id;
 368again:
 369        ret = btrfs_search_slot(trans, tree_root, &key, path, -1, 1);
 370        BUG_ON(ret < 0);
 371        if (ret == 0) {
 372                leaf = path->nodes[0];
 373                ref = btrfs_item_ptr(leaf, path->slots[0],
 374                                     struct btrfs_root_ref);
 375
 376                WARN_ON(btrfs_root_ref_dirid(leaf, ref) != dirid);
 377                WARN_ON(btrfs_root_ref_name_len(leaf, ref) != name_len);
 378                ptr = (unsigned long)(ref + 1);
 379                WARN_ON(memcmp_extent_buffer(leaf, name, ptr, name_len));
 380                *sequence = btrfs_root_ref_sequence(leaf, ref);
 381
 382                ret = btrfs_del_item(trans, tree_root, path);
 383                if (ret) {
 384                        err = ret;
 385                        goto out;
 386                }
 387        } else
 388                err = -ENOENT;
 389
 390        if (key.type == BTRFS_ROOT_BACKREF_KEY) {
 391                btrfs_release_path(path);
 392                key.objectid = ref_id;
 393                key.type = BTRFS_ROOT_REF_KEY;
 394                key.offset = root_id;
 395                goto again;
 396        }
 397
 398out:
 399        btrfs_free_path(path);
 400        return err;
 401}
 402
 403int 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        key.objectid = root_id;
 411        key.type = BTRFS_ROOT_REF_KEY;
 412        key.offset = ref_id;
 413
 414        ret = btrfs_search_slot(NULL, tree_root, &key, path, 0, 0);
 415        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 */
 433int 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        path = btrfs_alloc_path();
 446        if (!path)
 447                return -ENOMEM;
 448
 449        key.objectid = root_id;
 450        key.type = BTRFS_ROOT_BACKREF_KEY;
 451        key.offset = ref_id;
 452again:
 453        ret = btrfs_insert_empty_item(trans, tree_root, path, &key,
 454                                      sizeof(*ref) + name_len);
 455        if (ret) {
 456                btrfs_abort_transaction(trans, tree_root, ret);
 457                btrfs_free_path(path);
 458                return ret;
 459        }
 460
 461        leaf = path->nodes[0];
 462        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        btrfs_set_root_ref_name_len(leaf, ref, name_len);
 466        ptr = (unsigned long)(ref + 1);
 467        write_extent_buffer(leaf, name, ptr, name_len);
 468        btrfs_mark_buffer_dirty(leaf);
 469
 470        if (key.type == BTRFS_ROOT_BACKREF_KEY) {
 471                btrfs_release_path(path);
 472                key.objectid = ref_id;
 473                key.type = BTRFS_ROOT_REF_KEY;
 474                key.offset = root_id;
 475                goto again;
 476        }
 477
 478        btrfs_free_path(path);
 479        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 */
 488void 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        if (!(inode_flags & BTRFS_INODE_ROOT_ITEM_INIT)) {
 493                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}
 499
 500void 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        struct timespec ct = CURRENT_TIME;
 505
 506        spin_lock(&root->root_item_lock);
 507        btrfs_set_root_ctransid(item, trans->transid);
 508        btrfs_set_stack_timespec_sec(&item->ctime, ct.tv_sec);
 509        btrfs_set_stack_timespec_nsec(&item->ctime, ct.tv_nsec);
 510        spin_unlock(&root->root_item_lock);
 511}
 512