diff options
| -rw-r--r-- | fs/btrfs/ctree.h | 2 | ||||
| -rw-r--r-- | fs/btrfs/export.c | 4 | ||||
| -rw-r--r-- | fs/btrfs/inode.c | 10 | ||||
| -rw-r--r-- | fs/btrfs/relocation.c | 2 | ||||
| -rw-r--r-- | fs/btrfs/super.c | 172 | ||||
| -rw-r--r-- | fs/btrfs/tree-log.c | 2 |
6 files changed, 158 insertions, 34 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index abbce4d90c1b..07d956977a07 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h | |||
| @@ -2335,7 +2335,7 @@ int btrfs_init_cachep(void); | |||
| 2335 | void btrfs_destroy_cachep(void); | 2335 | void btrfs_destroy_cachep(void); |
| 2336 | long btrfs_ioctl_trans_end(struct file *file); | 2336 | long btrfs_ioctl_trans_end(struct file *file); |
| 2337 | struct inode *btrfs_iget(struct super_block *s, struct btrfs_key *location, | 2337 | struct inode *btrfs_iget(struct super_block *s, struct btrfs_key *location, |
| 2338 | struct btrfs_root *root); | 2338 | struct btrfs_root *root, int *was_new); |
| 2339 | int btrfs_commit_write(struct file *file, struct page *page, | 2339 | int btrfs_commit_write(struct file *file, struct page *page, |
| 2340 | unsigned from, unsigned to); | 2340 | unsigned from, unsigned to); |
| 2341 | struct extent_map *btrfs_get_extent(struct inode *inode, struct page *page, | 2341 | struct extent_map *btrfs_get_extent(struct inode *inode, struct page *page, |
diff --git a/fs/btrfs/export.c b/fs/btrfs/export.c index ba5c3fd5ab8c..951ef09b82f4 100644 --- a/fs/btrfs/export.c +++ b/fs/btrfs/export.c | |||
| @@ -95,7 +95,7 @@ static struct dentry *btrfs_get_dentry(struct super_block *sb, u64 objectid, | |||
| 95 | btrfs_set_key_type(&key, BTRFS_INODE_ITEM_KEY); | 95 | btrfs_set_key_type(&key, BTRFS_INODE_ITEM_KEY); |
| 96 | key.offset = 0; | 96 | key.offset = 0; |
| 97 | 97 | ||
| 98 | inode = btrfs_iget(sb, &key, root); | 98 | inode = btrfs_iget(sb, &key, root, NULL); |
| 99 | if (IS_ERR(inode)) { | 99 | if (IS_ERR(inode)) { |
| 100 | err = PTR_ERR(inode); | 100 | err = PTR_ERR(inode); |
| 101 | goto fail; | 101 | goto fail; |
| @@ -223,7 +223,7 @@ static struct dentry *btrfs_get_parent(struct dentry *child) | |||
| 223 | 223 | ||
| 224 | key.type = BTRFS_INODE_ITEM_KEY; | 224 | key.type = BTRFS_INODE_ITEM_KEY; |
| 225 | key.offset = 0; | 225 | key.offset = 0; |
| 226 | dentry = d_obtain_alias(btrfs_iget(root->fs_info->sb, &key, root)); | 226 | dentry = d_obtain_alias(btrfs_iget(root->fs_info->sb, &key, root, NULL)); |
| 227 | if (!IS_ERR(dentry)) | 227 | if (!IS_ERR(dentry)) |
| 228 | dentry->d_op = &btrfs_dentry_operations; | 228 | dentry->d_op = &btrfs_dentry_operations; |
| 229 | return dentry; | 229 | return dentry; |
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 4deb280f8969..7d10d1ccb0fe 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
| @@ -2153,7 +2153,7 @@ void btrfs_orphan_cleanup(struct btrfs_root *root) | |||
| 2153 | found_key.objectid = found_key.offset; | 2153 | found_key.objectid = found_key.offset; |
| 2154 | found_key.type = BTRFS_INODE_ITEM_KEY; | 2154 | found_key.type = BTRFS_INODE_ITEM_KEY; |
| 2155 | found_key.offset = 0; | 2155 | found_key.offset = 0; |
| 2156 | inode = btrfs_iget(root->fs_info->sb, &found_key, root); | 2156 | inode = btrfs_iget(root->fs_info->sb, &found_key, root, NULL); |
| 2157 | if (IS_ERR(inode)) | 2157 | if (IS_ERR(inode)) |
| 2158 | break; | 2158 | break; |
| 2159 | 2159 | ||
| @@ -3687,7 +3687,7 @@ static struct inode *btrfs_iget_locked(struct super_block *s, | |||
| 3687 | * Returns in *is_new if the inode was read from disk | 3687 | * Returns in *is_new if the inode was read from disk |
| 3688 | */ | 3688 | */ |
| 3689 | struct inode *btrfs_iget(struct super_block *s, struct btrfs_key *location, | 3689 | struct inode *btrfs_iget(struct super_block *s, struct btrfs_key *location, |
| 3690 | struct btrfs_root *root) | 3690 | struct btrfs_root *root, int *new) |
| 3691 | { | 3691 | { |
| 3692 | struct inode *inode; | 3692 | struct inode *inode; |
| 3693 | 3693 | ||
| @@ -3702,6 +3702,8 @@ struct inode *btrfs_iget(struct super_block *s, struct btrfs_key *location, | |||
| 3702 | 3702 | ||
| 3703 | inode_tree_add(inode); | 3703 | inode_tree_add(inode); |
| 3704 | unlock_new_inode(inode); | 3704 | unlock_new_inode(inode); |
| 3705 | if (new) | ||
| 3706 | *new = 1; | ||
| 3705 | } | 3707 | } |
| 3706 | 3708 | ||
| 3707 | return inode; | 3709 | return inode; |
| @@ -3754,7 +3756,7 @@ struct inode *btrfs_lookup_dentry(struct inode *dir, struct dentry *dentry) | |||
| 3754 | return NULL; | 3756 | return NULL; |
| 3755 | 3757 | ||
| 3756 | if (location.type == BTRFS_INODE_ITEM_KEY) { | 3758 | if (location.type == BTRFS_INODE_ITEM_KEY) { |
| 3757 | inode = btrfs_iget(dir->i_sb, &location, root); | 3759 | inode = btrfs_iget(dir->i_sb, &location, root, NULL); |
| 3758 | return inode; | 3760 | return inode; |
| 3759 | } | 3761 | } |
| 3760 | 3762 | ||
| @@ -3769,7 +3771,7 @@ struct inode *btrfs_lookup_dentry(struct inode *dir, struct dentry *dentry) | |||
| 3769 | else | 3771 | else |
| 3770 | inode = new_simple_dir(dir->i_sb, &location, sub_root); | 3772 | inode = new_simple_dir(dir->i_sb, &location, sub_root); |
| 3771 | } else { | 3773 | } else { |
| 3772 | inode = btrfs_iget(dir->i_sb, &location, sub_root); | 3774 | inode = btrfs_iget(dir->i_sb, &location, sub_root, NULL); |
| 3773 | } | 3775 | } |
| 3774 | srcu_read_unlock(&root->fs_info->subvol_srcu, index); | 3776 | srcu_read_unlock(&root->fs_info->subvol_srcu, index); |
| 3775 | 3777 | ||
diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c index 0109e5606bad..d52759daa53f 100644 --- a/fs/btrfs/relocation.c +++ b/fs/btrfs/relocation.c | |||
| @@ -3487,7 +3487,7 @@ static struct inode *create_reloc_inode(struct btrfs_fs_info *fs_info, | |||
| 3487 | key.objectid = objectid; | 3487 | key.objectid = objectid; |
| 3488 | key.type = BTRFS_INODE_ITEM_KEY; | 3488 | key.type = BTRFS_INODE_ITEM_KEY; |
| 3489 | key.offset = 0; | 3489 | key.offset = 0; |
| 3490 | inode = btrfs_iget(root->fs_info->sb, &key, root); | 3490 | inode = btrfs_iget(root->fs_info->sb, &key, root, NULL); |
| 3491 | BUG_ON(IS_ERR(inode) || is_bad_inode(inode)); | 3491 | BUG_ON(IS_ERR(inode) || is_bad_inode(inode)); |
| 3492 | BTRFS_I(inode)->index_cnt = group->key.objectid; | 3492 | BTRFS_I(inode)->index_cnt = group->key.objectid; |
| 3493 | 3493 | ||
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index f8b4521de907..f878337cee6f 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c | |||
| @@ -63,10 +63,10 @@ static void btrfs_put_super(struct super_block *sb) | |||
| 63 | } | 63 | } |
| 64 | 64 | ||
| 65 | enum { | 65 | enum { |
| 66 | Opt_degraded, Opt_subvol, Opt_device, Opt_nodatasum, Opt_nodatacow, | 66 | Opt_degraded, Opt_subvol, Opt_subvolid, Opt_device, Opt_nodatasum, |
| 67 | Opt_max_extent, Opt_max_inline, Opt_alloc_start, Opt_nobarrier, | 67 | Opt_nodatacow, Opt_max_extent, Opt_max_inline, Opt_alloc_start, |
| 68 | Opt_ssd, Opt_nossd, Opt_ssd_spread, Opt_thread_pool, Opt_noacl, | 68 | Opt_nobarrier, Opt_ssd, Opt_nossd, Opt_ssd_spread, Opt_thread_pool, |
| 69 | Opt_compress, Opt_compress_force, Opt_notreelog, Opt_ratio, | 69 | Opt_noacl, Opt_compress, Opt_compress_force, Opt_notreelog, Opt_ratio, |
| 70 | Opt_flushoncommit, | 70 | Opt_flushoncommit, |
| 71 | Opt_discard, Opt_err, | 71 | Opt_discard, Opt_err, |
| 72 | }; | 72 | }; |
| @@ -74,6 +74,7 @@ enum { | |||
| 74 | static match_table_t tokens = { | 74 | static match_table_t tokens = { |
| 75 | {Opt_degraded, "degraded"}, | 75 | {Opt_degraded, "degraded"}, |
| 76 | {Opt_subvol, "subvol=%s"}, | 76 | {Opt_subvol, "subvol=%s"}, |
| 77 | {Opt_subvolid, "subvolid=%d"}, | ||
| 77 | {Opt_device, "device=%s"}, | 78 | {Opt_device, "device=%s"}, |
| 78 | {Opt_nodatasum, "nodatasum"}, | 79 | {Opt_nodatasum, "nodatasum"}, |
| 79 | {Opt_nodatacow, "nodatacow"}, | 80 | {Opt_nodatacow, "nodatacow"}, |
| @@ -157,6 +158,7 @@ int btrfs_parse_options(struct btrfs_root *root, char *options) | |||
| 157 | btrfs_set_opt(info->mount_opt, DEGRADED); | 158 | btrfs_set_opt(info->mount_opt, DEGRADED); |
| 158 | break; | 159 | break; |
| 159 | case Opt_subvol: | 160 | case Opt_subvol: |
| 161 | case Opt_subvolid: | ||
| 160 | case Opt_device: | 162 | case Opt_device: |
| 161 | /* | 163 | /* |
| 162 | * These are parsed by btrfs_parse_early_options | 164 | * These are parsed by btrfs_parse_early_options |
| @@ -292,12 +294,13 @@ out: | |||
| 292 | * only when we need to allocate a new super block. | 294 | * only when we need to allocate a new super block. |
| 293 | */ | 295 | */ |
| 294 | static int btrfs_parse_early_options(const char *options, fmode_t flags, | 296 | static int btrfs_parse_early_options(const char *options, fmode_t flags, |
| 295 | void *holder, char **subvol_name, | 297 | void *holder, char **subvol_name, u64 *subvol_objectid, |
| 296 | struct btrfs_fs_devices **fs_devices) | 298 | struct btrfs_fs_devices **fs_devices) |
| 297 | { | 299 | { |
| 298 | substring_t args[MAX_OPT_ARGS]; | 300 | substring_t args[MAX_OPT_ARGS]; |
| 299 | char *opts, *p; | 301 | char *opts, *p; |
| 300 | int error = 0; | 302 | int error = 0; |
| 303 | int intarg; | ||
| 301 | 304 | ||
| 302 | if (!options) | 305 | if (!options) |
| 303 | goto out; | 306 | goto out; |
| @@ -320,6 +323,12 @@ static int btrfs_parse_early_options(const char *options, fmode_t flags, | |||
| 320 | case Opt_subvol: | 323 | case Opt_subvol: |
| 321 | *subvol_name = match_strdup(&args[0]); | 324 | *subvol_name = match_strdup(&args[0]); |
| 322 | break; | 325 | break; |
| 326 | case Opt_subvolid: | ||
| 327 | intarg = 0; | ||
| 328 | match_int(&args[0], &intarg); | ||
| 329 | if (intarg) | ||
| 330 | *subvol_objectid = intarg; | ||
| 331 | break; | ||
| 323 | case Opt_device: | 332 | case Opt_device: |
| 324 | error = btrfs_scan_one_device(match_strdup(&args[0]), | 333 | error = btrfs_scan_one_device(match_strdup(&args[0]), |
| 325 | flags, holder, fs_devices); | 334 | flags, holder, fs_devices); |
| @@ -347,6 +356,110 @@ static int btrfs_parse_early_options(const char *options, fmode_t flags, | |||
| 347 | return error; | 356 | return error; |
| 348 | } | 357 | } |
| 349 | 358 | ||
| 359 | static struct dentry *get_default_root(struct super_block *sb, | ||
| 360 | u64 subvol_objectid) | ||
| 361 | { | ||
| 362 | struct btrfs_root *root = sb->s_fs_info; | ||
| 363 | struct btrfs_root *new_root; | ||
| 364 | struct btrfs_dir_item *di; | ||
| 365 | struct btrfs_path *path; | ||
| 366 | struct btrfs_key location; | ||
| 367 | struct inode *inode; | ||
| 368 | struct dentry *dentry; | ||
| 369 | u64 dir_id; | ||
| 370 | int new = 0; | ||
| 371 | |||
| 372 | /* | ||
| 373 | * We have a specific subvol we want to mount, just setup location and | ||
| 374 | * go look up the root. | ||
| 375 | */ | ||
| 376 | if (subvol_objectid) { | ||
| 377 | location.objectid = subvol_objectid; | ||
| 378 | location.type = BTRFS_ROOT_ITEM_KEY; | ||
| 379 | location.offset = (u64)-1; | ||
| 380 | goto find_root; | ||
| 381 | } | ||
| 382 | |||
| 383 | path = btrfs_alloc_path(); | ||
| 384 | if (!path) | ||
| 385 | return ERR_PTR(-ENOMEM); | ||
| 386 | path->leave_spinning = 1; | ||
| 387 | |||
| 388 | /* | ||
| 389 | * Find the "default" dir item which points to the root item that we | ||
| 390 | * will mount by default if we haven't been given a specific subvolume | ||
| 391 | * to mount. | ||
| 392 | */ | ||
| 393 | dir_id = btrfs_super_root_dir(&root->fs_info->super_copy); | ||
| 394 | di = btrfs_lookup_dir_item(NULL, root, path, dir_id, "default", 7, 0); | ||
| 395 | if (!di) { | ||
| 396 | /* | ||
| 397 | * Ok the default dir item isn't there. This is weird since | ||
| 398 | * it's always been there, but don't freak out, just try and | ||
| 399 | * mount to root most subvolume. | ||
| 400 | */ | ||
| 401 | btrfs_free_path(path); | ||
| 402 | dir_id = BTRFS_FIRST_FREE_OBJECTID; | ||
| 403 | new_root = root->fs_info->fs_root; | ||
| 404 | goto setup_root; | ||
| 405 | } | ||
| 406 | |||
| 407 | btrfs_dir_item_key_to_cpu(path->nodes[0], di, &location); | ||
| 408 | btrfs_free_path(path); | ||
| 409 | |||
| 410 | find_root: | ||
| 411 | new_root = btrfs_read_fs_root_no_name(root->fs_info, &location); | ||
| 412 | if (IS_ERR(new_root)) | ||
| 413 | return ERR_PTR(PTR_ERR(new_root)); | ||
| 414 | |||
| 415 | if (btrfs_root_refs(&new_root->root_item) == 0) | ||
| 416 | return ERR_PTR(-ENOENT); | ||
| 417 | |||
| 418 | dir_id = btrfs_root_dirid(&new_root->root_item); | ||
| 419 | setup_root: | ||
| 420 | location.objectid = dir_id; | ||
| 421 | location.type = BTRFS_INODE_ITEM_KEY; | ||
| 422 | location.offset = 0; | ||
| 423 | |||
| 424 | inode = btrfs_iget(sb, &location, new_root, &new); | ||
| 425 | if (!inode) | ||
| 426 | return ERR_PTR(-ENOMEM); | ||
| 427 | |||
| 428 | /* | ||
| 429 | * If we're just mounting the root most subvol put the inode and return | ||
| 430 | * a reference to the dentry. We will have already gotten a reference | ||
| 431 | * to the inode in btrfs_fill_super so we're good to go. | ||
| 432 | */ | ||
| 433 | if (!new && sb->s_root->d_inode == inode) { | ||
| 434 | iput(inode); | ||
| 435 | return dget(sb->s_root); | ||
| 436 | } | ||
| 437 | |||
| 438 | if (new) { | ||
| 439 | const struct qstr name = { .name = "/", .len = 1 }; | ||
| 440 | |||
| 441 | /* | ||
| 442 | * New inode, we need to make the dentry a sibling of s_root so | ||
| 443 | * everything gets cleaned up properly on unmount. | ||
| 444 | */ | ||
| 445 | dentry = d_alloc(sb->s_root, &name); | ||
| 446 | if (!dentry) { | ||
| 447 | iput(inode); | ||
| 448 | return ERR_PTR(-ENOMEM); | ||
| 449 | } | ||
| 450 | d_splice_alias(inode, dentry); | ||
| 451 | } else { | ||
| 452 | /* | ||
| 453 | * We found the inode in cache, just find a dentry for it and | ||
| 454 | * put the reference to the inode we just got. | ||
| 455 | */ | ||
| 456 | dentry = d_find_alias(inode); | ||
| 457 | iput(inode); | ||
| 458 | } | ||
| 459 | |||
| 460 | return dentry; | ||
| 461 | } | ||
| 462 | |||
| 350 | static int btrfs_fill_super(struct super_block *sb, | 463 | static int btrfs_fill_super(struct super_block *sb, |
| 351 | struct btrfs_fs_devices *fs_devices, | 464 | struct btrfs_fs_devices *fs_devices, |
| 352 | void *data, int silent) | 465 | void *data, int silent) |
| @@ -380,7 +493,7 @@ static int btrfs_fill_super(struct super_block *sb, | |||
| 380 | key.objectid = BTRFS_FIRST_FREE_OBJECTID; | 493 | key.objectid = BTRFS_FIRST_FREE_OBJECTID; |
| 381 | key.type = BTRFS_INODE_ITEM_KEY; | 494 | key.type = BTRFS_INODE_ITEM_KEY; |
| 382 | key.offset = 0; | 495 | key.offset = 0; |
| 383 | inode = btrfs_iget(sb, &key, tree_root->fs_info->fs_root); | 496 | inode = btrfs_iget(sb, &key, tree_root->fs_info->fs_root, NULL); |
| 384 | if (IS_ERR(inode)) { | 497 | if (IS_ERR(inode)) { |
| 385 | err = PTR_ERR(inode); | 498 | err = PTR_ERR(inode); |
| 386 | goto fail_close; | 499 | goto fail_close; |
| @@ -392,12 +505,6 @@ static int btrfs_fill_super(struct super_block *sb, | |||
| 392 | err = -ENOMEM; | 505 | err = -ENOMEM; |
| 393 | goto fail_close; | 506 | goto fail_close; |
| 394 | } | 507 | } |
| 395 | #if 0 | ||
| 396 | /* this does the super kobj at the same time */ | ||
| 397 | err = btrfs_sysfs_add_super(tree_root->fs_info); | ||
| 398 | if (err) | ||
| 399 | goto fail_close; | ||
| 400 | #endif | ||
| 401 | 508 | ||
| 402 | sb->s_root = root_dentry; | 509 | sb->s_root = root_dentry; |
| 403 | 510 | ||
| @@ -489,19 +596,22 @@ static int btrfs_test_super(struct super_block *s, void *data) | |||
| 489 | static int btrfs_get_sb(struct file_system_type *fs_type, int flags, | 596 | static int btrfs_get_sb(struct file_system_type *fs_type, int flags, |
| 490 | const char *dev_name, void *data, struct vfsmount *mnt) | 597 | const char *dev_name, void *data, struct vfsmount *mnt) |
| 491 | { | 598 | { |
| 492 | char *subvol_name = NULL; | ||
| 493 | struct block_device *bdev = NULL; | 599 | struct block_device *bdev = NULL; |
| 494 | struct super_block *s; | 600 | struct super_block *s; |
| 495 | struct dentry *root; | 601 | struct dentry *root; |
| 496 | struct btrfs_fs_devices *fs_devices = NULL; | 602 | struct btrfs_fs_devices *fs_devices = NULL; |
| 497 | fmode_t mode = FMODE_READ; | 603 | fmode_t mode = FMODE_READ; |
| 604 | char *subvol_name = NULL; | ||
| 605 | u64 subvol_objectid = 0; | ||
| 498 | int error = 0; | 606 | int error = 0; |
| 607 | int found = 0; | ||
| 499 | 608 | ||
| 500 | if (!(flags & MS_RDONLY)) | 609 | if (!(flags & MS_RDONLY)) |
| 501 | mode |= FMODE_WRITE; | 610 | mode |= FMODE_WRITE; |
| 502 | 611 | ||
| 503 | error = btrfs_parse_early_options(data, mode, fs_type, | 612 | error = btrfs_parse_early_options(data, mode, fs_type, |
| 504 | &subvol_name, &fs_devices); | 613 | &subvol_name, &subvol_objectid, |
| 614 | &fs_devices); | ||
| 505 | if (error) | 615 | if (error) |
| 506 | return error; | 616 | return error; |
| 507 | 617 | ||
| @@ -530,6 +640,7 @@ static int btrfs_get_sb(struct file_system_type *fs_type, int flags, | |||
| 530 | goto error_close_devices; | 640 | goto error_close_devices; |
| 531 | } | 641 | } |
| 532 | 642 | ||
| 643 | found = 1; | ||
| 533 | btrfs_close_devices(fs_devices); | 644 | btrfs_close_devices(fs_devices); |
| 534 | } else { | 645 | } else { |
| 535 | char b[BDEVNAME_SIZE]; | 646 | char b[BDEVNAME_SIZE]; |
| @@ -547,25 +658,35 @@ static int btrfs_get_sb(struct file_system_type *fs_type, int flags, | |||
| 547 | s->s_flags |= MS_ACTIVE; | 658 | s->s_flags |= MS_ACTIVE; |
| 548 | } | 659 | } |
| 549 | 660 | ||
| 550 | if (!strcmp(subvol_name, ".")) | 661 | root = get_default_root(s, subvol_objectid); |
| 551 | root = dget(s->s_root); | 662 | if (IS_ERR(root)) { |
| 552 | else { | 663 | error = PTR_ERR(root); |
| 553 | mutex_lock(&s->s_root->d_inode->i_mutex); | 664 | deactivate_locked_super(s); |
| 554 | root = lookup_one_len(subvol_name, s->s_root, | 665 | goto error; |
| 666 | } | ||
| 667 | /* if they gave us a subvolume name bind mount into that */ | ||
| 668 | if (strcmp(subvol_name, ".")) { | ||
| 669 | struct dentry *new_root; | ||
| 670 | mutex_lock(&root->d_inode->i_mutex); | ||
| 671 | new_root = lookup_one_len(subvol_name, root, | ||
| 555 | strlen(subvol_name)); | 672 | strlen(subvol_name)); |
| 556 | mutex_unlock(&s->s_root->d_inode->i_mutex); | 673 | mutex_unlock(&root->d_inode->i_mutex); |
| 557 | 674 | ||
| 558 | if (IS_ERR(root)) { | 675 | if (IS_ERR(new_root)) { |
| 559 | deactivate_locked_super(s); | 676 | deactivate_locked_super(s); |
| 560 | error = PTR_ERR(root); | 677 | error = PTR_ERR(new_root); |
| 561 | goto error_free_subvol_name; | 678 | dput(root); |
| 679 | goto error_close_devices; | ||
| 562 | } | 680 | } |
| 563 | if (!root->d_inode) { | 681 | if (!new_root->d_inode) { |
| 564 | dput(root); | 682 | dput(root); |
| 683 | dput(new_root); | ||
| 565 | deactivate_locked_super(s); | 684 | deactivate_locked_super(s); |
| 566 | error = -ENXIO; | 685 | error = -ENXIO; |
| 567 | goto error_free_subvol_name; | 686 | goto error_close_devices; |
| 568 | } | 687 | } |
| 688 | dput(root); | ||
| 689 | root = new_root; | ||
| 569 | } | 690 | } |
| 570 | 691 | ||
| 571 | mnt->mnt_sb = s; | 692 | mnt->mnt_sb = s; |
| @@ -580,6 +701,7 @@ error_close_devices: | |||
| 580 | btrfs_close_devices(fs_devices); | 701 | btrfs_close_devices(fs_devices); |
| 581 | error_free_subvol_name: | 702 | error_free_subvol_name: |
| 582 | kfree(subvol_name); | 703 | kfree(subvol_name); |
| 704 | error: | ||
| 583 | return error; | 705 | return error; |
| 584 | } | 706 | } |
| 585 | 707 | ||
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index 4a9434b622ec..1255fcc8ade5 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c | |||
| @@ -445,7 +445,7 @@ static noinline struct inode *read_one_inode(struct btrfs_root *root, | |||
| 445 | key.objectid = objectid; | 445 | key.objectid = objectid; |
| 446 | key.type = BTRFS_INODE_ITEM_KEY; | 446 | key.type = BTRFS_INODE_ITEM_KEY; |
| 447 | key.offset = 0; | 447 | key.offset = 0; |
| 448 | inode = btrfs_iget(root->fs_info->sb, &key, root); | 448 | inode = btrfs_iget(root->fs_info->sb, &key, root, NULL); |
| 449 | if (IS_ERR(inode)) { | 449 | if (IS_ERR(inode)) { |
| 450 | inode = NULL; | 450 | inode = NULL; |
| 451 | } else if (is_bad_inode(inode)) { | 451 | } else if (is_bad_inode(inode)) { |
