diff options
Diffstat (limited to 'fs/btrfs/volumes.c')
-rw-r--r-- | fs/btrfs/volumes.c | 27 |
1 files changed, 19 insertions, 8 deletions
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index 51f125508771..035efce603a9 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c | |||
@@ -834,10 +834,6 @@ static void __free_device(struct work_struct *work) | |||
834 | struct btrfs_device *device; | 834 | struct btrfs_device *device; |
835 | 835 | ||
836 | device = container_of(work, struct btrfs_device, rcu_work); | 836 | device = container_of(work, struct btrfs_device, rcu_work); |
837 | |||
838 | if (device->bdev) | ||
839 | blkdev_put(device->bdev, device->mode); | ||
840 | |||
841 | rcu_string_free(device->name); | 837 | rcu_string_free(device->name); |
842 | kfree(device); | 838 | kfree(device); |
843 | } | 839 | } |
@@ -852,6 +848,17 @@ static void free_device(struct rcu_head *head) | |||
852 | schedule_work(&device->rcu_work); | 848 | schedule_work(&device->rcu_work); |
853 | } | 849 | } |
854 | 850 | ||
851 | static void btrfs_close_bdev(struct btrfs_device *device) | ||
852 | { | ||
853 | if (device->bdev && device->writeable) { | ||
854 | sync_blockdev(device->bdev); | ||
855 | invalidate_bdev(device->bdev); | ||
856 | } | ||
857 | |||
858 | if (device->bdev) | ||
859 | blkdev_put(device->bdev, device->mode); | ||
860 | } | ||
861 | |||
855 | static void btrfs_close_one_device(struct btrfs_device *device) | 862 | static void btrfs_close_one_device(struct btrfs_device *device) |
856 | { | 863 | { |
857 | struct btrfs_fs_devices *fs_devices = device->fs_devices; | 864 | struct btrfs_fs_devices *fs_devices = device->fs_devices; |
@@ -870,10 +877,7 @@ static void btrfs_close_one_device(struct btrfs_device *device) | |||
870 | if (device->missing) | 877 | if (device->missing) |
871 | fs_devices->missing_devices--; | 878 | fs_devices->missing_devices--; |
872 | 879 | ||
873 | if (device->bdev && device->writeable) { | 880 | btrfs_close_bdev(device); |
874 | sync_blockdev(device->bdev); | ||
875 | invalidate_bdev(device->bdev); | ||
876 | } | ||
877 | 881 | ||
878 | new_device = btrfs_alloc_device(NULL, &device->devid, | 882 | new_device = btrfs_alloc_device(NULL, &device->devid, |
879 | device->uuid); | 883 | device->uuid); |
@@ -1932,6 +1936,8 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path, u64 devid) | |||
1932 | btrfs_sysfs_rm_device_link(root->fs_info->fs_devices, device); | 1936 | btrfs_sysfs_rm_device_link(root->fs_info->fs_devices, device); |
1933 | } | 1937 | } |
1934 | 1938 | ||
1939 | btrfs_close_bdev(device); | ||
1940 | |||
1935 | call_rcu(&device->rcu, free_device); | 1941 | call_rcu(&device->rcu, free_device); |
1936 | 1942 | ||
1937 | num_devices = btrfs_super_num_devices(root->fs_info->super_copy) - 1; | 1943 | num_devices = btrfs_super_num_devices(root->fs_info->super_copy) - 1; |
@@ -2025,6 +2031,9 @@ void btrfs_rm_dev_replace_free_srcdev(struct btrfs_fs_info *fs_info, | |||
2025 | /* zero out the old super if it is writable */ | 2031 | /* zero out the old super if it is writable */ |
2026 | btrfs_scratch_superblocks(srcdev->bdev, srcdev->name->str); | 2032 | btrfs_scratch_superblocks(srcdev->bdev, srcdev->name->str); |
2027 | } | 2033 | } |
2034 | |||
2035 | btrfs_close_bdev(srcdev); | ||
2036 | |||
2028 | call_rcu(&srcdev->rcu, free_device); | 2037 | call_rcu(&srcdev->rcu, free_device); |
2029 | 2038 | ||
2030 | /* | 2039 | /* |
@@ -2080,6 +2089,8 @@ void btrfs_destroy_dev_replace_tgtdev(struct btrfs_fs_info *fs_info, | |||
2080 | * the device_list_mutex lock. | 2089 | * the device_list_mutex lock. |
2081 | */ | 2090 | */ |
2082 | btrfs_scratch_superblocks(tgtdev->bdev, tgtdev->name->str); | 2091 | btrfs_scratch_superblocks(tgtdev->bdev, tgtdev->name->str); |
2092 | |||
2093 | btrfs_close_bdev(tgtdev); | ||
2083 | call_rcu(&tgtdev->rcu, free_device); | 2094 | call_rcu(&tgtdev->rcu, free_device); |
2084 | } | 2095 | } |
2085 | 2096 | ||