diff options
author | Josef Bacik <josef@redhat.com> | 2010-10-22 15:26:53 -0400 |
---|---|---|
committer | Josef Bacik <josef@redhat.com> | 2010-10-22 15:55:03 -0400 |
commit | 0e78340f3c1fc603e8016c8ac304766bcc65506e (patch) | |
tree | a86dfd1d78a577e8d799e90f105ccfdc881dec0a /fs | |
parent | 8bb8ab2e93f9c3c9453e13be0f37d344a32a3a6d (diff) |
Btrfs: fix error handling in btrfs_get_sb
If we failed to find the root subvol id, or the subvol=<name>, we would
deactivate the locked super and close the devices. The problem is at this point
we have gotten the SB all setup, which includes setting super_operations, so
when we'd deactiveate the super, we'd do a close_ctree() which closes the
devices, so we'd end up closing the devices twice. So if you do something like
this
mount /dev/sda1 /mnt/test1
mount /dev/sda1 /mnt/test2 -o subvol=xxx
umount /mnt/test1
it would blow up (if subvol xxx doesn't exist). This patch fixes that problem.
Thanks,
Signed-off-by: Josef Bacik <josef@redhat.com>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/btrfs/super.c | 7 |
1 files changed, 3 insertions, 4 deletions
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index afab6ca14d03..d1867cda92a7 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c | |||
@@ -629,7 +629,7 @@ static int btrfs_get_sb(struct file_system_type *fs_type, int flags, | |||
629 | if (IS_ERR(root)) { | 629 | if (IS_ERR(root)) { |
630 | error = PTR_ERR(root); | 630 | error = PTR_ERR(root); |
631 | deactivate_locked_super(s); | 631 | deactivate_locked_super(s); |
632 | goto error; | 632 | goto error_free_subvol_name; |
633 | } | 633 | } |
634 | /* if they gave us a subvolume name bind mount into that */ | 634 | /* if they gave us a subvolume name bind mount into that */ |
635 | if (strcmp(subvol_name, ".")) { | 635 | if (strcmp(subvol_name, ".")) { |
@@ -643,14 +643,14 @@ static int btrfs_get_sb(struct file_system_type *fs_type, int flags, | |||
643 | deactivate_locked_super(s); | 643 | deactivate_locked_super(s); |
644 | error = PTR_ERR(new_root); | 644 | error = PTR_ERR(new_root); |
645 | dput(root); | 645 | dput(root); |
646 | goto error_close_devices; | 646 | goto error_free_subvol_name; |
647 | } | 647 | } |
648 | if (!new_root->d_inode) { | 648 | if (!new_root->d_inode) { |
649 | dput(root); | 649 | dput(root); |
650 | dput(new_root); | 650 | dput(new_root); |
651 | deactivate_locked_super(s); | 651 | deactivate_locked_super(s); |
652 | error = -ENXIO; | 652 | error = -ENXIO; |
653 | goto error_close_devices; | 653 | goto error_free_subvol_name; |
654 | } | 654 | } |
655 | dput(root); | 655 | dput(root); |
656 | root = new_root; | 656 | root = new_root; |
@@ -668,7 +668,6 @@ error_close_devices: | |||
668 | btrfs_close_devices(fs_devices); | 668 | btrfs_close_devices(fs_devices); |
669 | error_free_subvol_name: | 669 | error_free_subvol_name: |
670 | kfree(subvol_name); | 670 | kfree(subvol_name); |
671 | error: | ||
672 | return error; | 671 | return error; |
673 | } | 672 | } |
674 | 673 | ||