diff options
author | Chris Mason <chris.mason@oracle.com> | 2007-04-09 10:42:37 -0400 |
---|---|---|
committer | David Woodhouse <dwmw2@hera.kernel.org> | 2007-04-09 10:42:37 -0400 |
commit | 0f7d52f4431c530b4f39c524448c688bb7754de5 (patch) | |
tree | 1ba4f62a2b7230456e1b4850ddad339148f44b3e /fs/btrfs/super.c | |
parent | d6e4a428eb8f92bbb3537ccabadfb1195efb432b (diff) |
Btrfs: groundwork for subvolume and snapshot roots
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/super.c')
-rw-r--r-- | fs/btrfs/super.c | 39 |
1 files changed, 22 insertions, 17 deletions
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 66d9fb2288c3..3c9236ca889c 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c | |||
@@ -436,7 +436,6 @@ int fixup_tree_root_location(struct btrfs_root *root, | |||
436 | { | 436 | { |
437 | struct btrfs_path *path; | 437 | struct btrfs_path *path; |
438 | struct btrfs_root_item *ri; | 438 | struct btrfs_root_item *ri; |
439 | int ret; | ||
440 | 439 | ||
441 | if (btrfs_key_type(location) != BTRFS_ROOT_ITEM_KEY) | 440 | if (btrfs_key_type(location) != BTRFS_ROOT_ITEM_KEY) |
442 | return 0; | 441 | return 0; |
@@ -447,22 +446,19 @@ int fixup_tree_root_location(struct btrfs_root *root, | |||
447 | BUG_ON(!path); | 446 | BUG_ON(!path); |
448 | mutex_lock(&root->fs_info->fs_mutex); | 447 | mutex_lock(&root->fs_info->fs_mutex); |
449 | 448 | ||
450 | ret = btrfs_lookup_inode(NULL, root, path, location, 0); | 449 | *sub_root = btrfs_read_fs_root(root->fs_info, location); |
451 | if (ret) | 450 | if (IS_ERR(*sub_root)) |
452 | goto out; | 451 | return PTR_ERR(*sub_root); |
453 | ri = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]), | 452 | |
454 | path->slots[0], | 453 | ri = &(*sub_root)->root_item; |
455 | struct btrfs_root_item); | ||
456 | location->objectid = btrfs_root_dirid(ri); | 454 | location->objectid = btrfs_root_dirid(ri); |
457 | location->flags = 0; | 455 | location->flags = 0; |
458 | btrfs_set_key_type(location, BTRFS_INODE_ITEM_KEY); | 456 | btrfs_set_key_type(location, BTRFS_INODE_ITEM_KEY); |
459 | location->offset = 0; | 457 | location->offset = 0; |
460 | /* FIXME properly select the root */ | 458 | |
461 | *sub_root = root->fs_info->fs_root; | ||
462 | out: | ||
463 | btrfs_free_path(path); | 459 | btrfs_free_path(path); |
464 | mutex_unlock(&root->fs_info->fs_mutex); | 460 | mutex_unlock(&root->fs_info->fs_mutex); |
465 | return ret; | 461 | return 0; |
466 | } | 462 | } |
467 | 463 | ||
468 | 464 | ||
@@ -494,6 +490,15 @@ static struct dentry *btrfs_lookup(struct inode *dir, struct dentry *dentry, | |||
494 | if (!inode) | 490 | if (!inode) |
495 | return ERR_PTR(-EACCES); | 491 | return ERR_PTR(-EACCES); |
496 | if (inode->i_state & I_NEW) { | 492 | if (inode->i_state & I_NEW) { |
493 | if (sub_root != root) { | ||
494 | ret = radix_tree_insert( | ||
495 | &root->fs_info->fs_roots_radix, | ||
496 | (unsigned long)sub_root, | ||
497 | sub_root); | ||
498 | printk("adding new root for inode %lu\n", inode->i_ino); | ||
499 | igrab(inode); | ||
500 | sub_root->inode = inode; | ||
501 | } | ||
497 | BTRFS_I(inode)->root = sub_root; | 502 | BTRFS_I(inode)->root = sub_root; |
498 | memcpy(&BTRFS_I(inode)->location, &location, | 503 | memcpy(&BTRFS_I(inode)->location, &location, |
499 | sizeof(location)); | 504 | sizeof(location)); |
@@ -605,7 +610,7 @@ static int btrfs_fill_super(struct super_block * sb, void * data, int silent) | |||
605 | struct inode * inode; | 610 | struct inode * inode; |
606 | struct dentry * root_dentry; | 611 | struct dentry * root_dentry; |
607 | struct btrfs_super_block *disk_super; | 612 | struct btrfs_super_block *disk_super; |
608 | struct btrfs_root *root; | 613 | struct btrfs_root *tree_root; |
609 | struct btrfs_inode *bi; | 614 | struct btrfs_inode *bi; |
610 | 615 | ||
611 | sb->s_maxbytes = MAX_LFS_FILESIZE; | 616 | sb->s_maxbytes = MAX_LFS_FILESIZE; |
@@ -613,14 +618,14 @@ static int btrfs_fill_super(struct super_block * sb, void * data, int silent) | |||
613 | sb->s_op = &btrfs_super_ops; | 618 | sb->s_op = &btrfs_super_ops; |
614 | sb->s_time_gran = 1; | 619 | sb->s_time_gran = 1; |
615 | 620 | ||
616 | root = open_ctree(sb); | 621 | tree_root = open_ctree(sb); |
617 | 622 | ||
618 | if (!root) { | 623 | if (!tree_root) { |
619 | printk("btrfs: open_ctree failed\n"); | 624 | printk("btrfs: open_ctree failed\n"); |
620 | return -EIO; | 625 | return -EIO; |
621 | } | 626 | } |
622 | sb->s_fs_info = root; | 627 | sb->s_fs_info = tree_root; |
623 | disk_super = root->fs_info->disk_super; | 628 | disk_super = tree_root->fs_info->disk_super; |
624 | printk("read in super total blocks %Lu root %Lu\n", | 629 | printk("read in super total blocks %Lu root %Lu\n", |
625 | btrfs_super_total_blocks(disk_super), | 630 | btrfs_super_total_blocks(disk_super), |
626 | btrfs_super_root_dir(disk_super)); | 631 | btrfs_super_root_dir(disk_super)); |
@@ -630,7 +635,7 @@ static int btrfs_fill_super(struct super_block * sb, void * data, int silent) | |||
630 | bi->location.objectid = inode->i_ino; | 635 | bi->location.objectid = inode->i_ino; |
631 | bi->location.offset = 0; | 636 | bi->location.offset = 0; |
632 | bi->location.flags = 0; | 637 | bi->location.flags = 0; |
633 | bi->root = root->fs_info->tree_root; | 638 | bi->root = tree_root; |
634 | btrfs_set_key_type(&bi->location, BTRFS_INODE_ITEM_KEY); | 639 | btrfs_set_key_type(&bi->location, BTRFS_INODE_ITEM_KEY); |
635 | 640 | ||
636 | if (!inode) | 641 | if (!inode) |