aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/volumes.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/volumes.c')
-rw-r--r--fs/btrfs/volumes.c93
1 files changed, 50 insertions, 43 deletions
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 92e586bc8004..4def1fdbf755 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -108,6 +108,44 @@ static noinline struct btrfs_fs_devices *find_fsid(u8 *fsid)
108 return NULL; 108 return NULL;
109} 109}
110 110
111static int
112btrfs_get_bdev_and_sb(const char *device_path, fmode_t flags, void *holder,
113 int flush, struct block_device **bdev,
114 struct buffer_head **bh)
115{
116 int ret;
117
118 *bdev = blkdev_get_by_path(device_path, flags, holder);
119
120 if (IS_ERR(*bdev)) {
121 ret = PTR_ERR(*bdev);
122 printk(KERN_INFO "btrfs: open %s failed\n", device_path);
123 goto error;
124 }
125
126 if (flush)
127 filemap_write_and_wait((*bdev)->bd_inode->i_mapping);
128 ret = set_blocksize(*bdev, 4096);
129 if (ret) {
130 blkdev_put(*bdev, flags);
131 goto error;
132 }
133 invalidate_bdev(*bdev);
134 *bh = btrfs_read_dev_super(*bdev);
135 if (!*bh) {
136 ret = -EINVAL;
137 blkdev_put(*bdev, flags);
138 goto error;
139 }
140
141 return 0;
142
143error:
144 *bdev = NULL;
145 *bh = NULL;
146 return ret;
147}
148
111static void requeue_list(struct btrfs_pending_bios *pending_bios, 149static void requeue_list(struct btrfs_pending_bios *pending_bios,
112 struct bio *head, struct bio *tail) 150 struct bio *head, struct bio *tail)
113{ 151{
@@ -637,18 +675,10 @@ static int __btrfs_open_devices(struct btrfs_fs_devices *fs_devices,
637 if (!device->name) 675 if (!device->name)
638 continue; 676 continue;
639 677
640 bdev = blkdev_get_by_path(device->name->str, flags, holder); 678 ret = btrfs_get_bdev_and_sb(device->name->str, flags, holder, 1,
641 if (IS_ERR(bdev)) { 679 &bdev, &bh);
642 printk(KERN_INFO "btrfs: open %s failed\n", device->name->str); 680 if (ret)
643 goto error; 681 continue;
644 }
645 filemap_write_and_wait(bdev->bd_inode->i_mapping);
646 invalidate_bdev(bdev);
647 set_blocksize(bdev, 4096);
648
649 bh = btrfs_read_dev_super(bdev);
650 if (!bh)
651 goto error_close;
652 682
653 disk_super = (struct btrfs_super_block *)bh->b_data; 683 disk_super = (struct btrfs_super_block *)bh->b_data;
654 devid = btrfs_stack_device_id(&disk_super->dev_item); 684 devid = btrfs_stack_device_id(&disk_super->dev_item);
@@ -697,9 +727,7 @@ static int __btrfs_open_devices(struct btrfs_fs_devices *fs_devices,
697 727
698error_brelse: 728error_brelse:
699 brelse(bh); 729 brelse(bh);
700error_close:
701 blkdev_put(bdev, flags); 730 blkdev_put(bdev, flags);
702error:
703 continue; 731 continue;
704 } 732 }
705 if (fs_devices->open_devices == 0) { 733 if (fs_devices->open_devices == 0) {
@@ -744,22 +772,10 @@ int btrfs_scan_one_device(const char *path, fmode_t flags, void *holder,
744 u64 total_devices; 772 u64 total_devices;
745 773
746 flags |= FMODE_EXCL; 774 flags |= FMODE_EXCL;
747 bdev = blkdev_get_by_path(path, flags, holder);
748
749 if (IS_ERR(bdev)) {
750 ret = PTR_ERR(bdev);
751 goto error;
752 }
753
754 mutex_lock(&uuid_mutex); 775 mutex_lock(&uuid_mutex);
755 ret = set_blocksize(bdev, 4096); 776 ret = btrfs_get_bdev_and_sb(path, flags, holder, 0, &bdev, &bh);
756 if (ret) 777 if (ret)
757 goto error_close; 778 goto error;
758 bh = btrfs_read_dev_super(bdev);
759 if (!bh) {
760 ret = -EINVAL;
761 goto error_close;
762 }
763 disk_super = (struct btrfs_super_block *)bh->b_data; 779 disk_super = (struct btrfs_super_block *)bh->b_data;
764 devid = btrfs_stack_device_id(&disk_super->dev_item); 780 devid = btrfs_stack_device_id(&disk_super->dev_item);
765 transid = btrfs_super_generation(disk_super); 781 transid = btrfs_super_generation(disk_super);
@@ -777,10 +793,9 @@ int btrfs_scan_one_device(const char *path, fmode_t flags, void *holder,
777 if (!ret && fs_devices_ret) 793 if (!ret && fs_devices_ret)
778 (*fs_devices_ret)->total_devices = total_devices; 794 (*fs_devices_ret)->total_devices = total_devices;
779 brelse(bh); 795 brelse(bh);
780error_close:
781 mutex_unlock(&uuid_mutex);
782 blkdev_put(bdev, flags); 796 blkdev_put(bdev, flags);
783error: 797error:
798 mutex_unlock(&uuid_mutex);
784 return ret; 799 return ret;
785} 800}
786 801
@@ -1374,20 +1389,12 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path)
1374 goto out; 1389 goto out;
1375 } 1390 }
1376 } else { 1391 } else {
1377 bdev = blkdev_get_by_path(device_path, FMODE_READ | FMODE_EXCL, 1392 ret = btrfs_get_bdev_and_sb(device_path,
1378 root->fs_info->bdev_holder); 1393 FMODE_READ | FMODE_EXCL,
1379 if (IS_ERR(bdev)) { 1394 root->fs_info->bdev_holder, 0,
1380 ret = PTR_ERR(bdev); 1395 &bdev, &bh);
1396 if (ret)
1381 goto out; 1397 goto out;
1382 }
1383
1384 set_blocksize(bdev, 4096);
1385 invalidate_bdev(bdev);
1386 bh = btrfs_read_dev_super(bdev);
1387 if (!bh) {
1388 ret = -EINVAL;
1389 goto error_close;
1390 }
1391 disk_super = (struct btrfs_super_block *)bh->b_data; 1398 disk_super = (struct btrfs_super_block *)bh->b_data;
1392 devid = btrfs_stack_device_id(&disk_super->dev_item); 1399 devid = btrfs_stack_device_id(&disk_super->dev_item);
1393 dev_uuid = disk_super->dev_item.uuid; 1400 dev_uuid = disk_super->dev_item.uuid;