aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeff Mahoney <jeffm@suse.com>2016-09-20 08:50:21 -0400
committerDavid Sterba <dsterba@suse.com>2016-09-26 12:08:44 -0400
commitcea67ab92d3d4da9f2b4141d87cb8664757daca0 (patch)
tree75f6575c0d9aecef3d981ff0083222b2c4932be9
parent02794222c4132ac003e7281fb71f4ec1645ffc87 (diff)
btrfs: clean the old superblocks before freeing the device
btrfs_rm_device frees the block device but then re-opens it using the saved device name. A race exists between the close and the re-open that allows the block size to be changed. The result is getting stuck forever in the reclaim loop in __getblk_slow. This patch moves the superblock cleanup before closing the block device, which is also consistent with other callers. We also don't need a private copy of dev_name as the whole routine operates under the uuid_mutex. Signed-off-by: Jeff Mahoney <jeffm@suse.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
-rw-r--r--fs/btrfs/volumes.c38
1 files changed, 11 insertions, 27 deletions
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index c356ce332229..be2c8b35c3ae 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -1846,7 +1846,6 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path, u64 devid)
1846 u64 num_devices; 1846 u64 num_devices;
1847 int ret = 0; 1847 int ret = 0;
1848 bool clear_super = false; 1848 bool clear_super = false;
1849 char *dev_name = NULL;
1850 1849
1851 mutex_lock(&uuid_mutex); 1850 mutex_lock(&uuid_mutex);
1852 1851
@@ -1882,11 +1881,6 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path, u64 devid)
1882 list_del_init(&device->dev_alloc_list); 1881 list_del_init(&device->dev_alloc_list);
1883 device->fs_devices->rw_devices--; 1882 device->fs_devices->rw_devices--;
1884 unlock_chunks(root); 1883 unlock_chunks(root);
1885 dev_name = kstrdup(device->name->str, GFP_KERNEL);
1886 if (!dev_name) {
1887 ret = -ENOMEM;
1888 goto error_undo;
1889 }
1890 clear_super = true; 1884 clear_super = true;
1891 } 1885 }
1892 1886
@@ -1936,14 +1930,21 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path, u64 devid)
1936 btrfs_sysfs_rm_device_link(root->fs_info->fs_devices, device); 1930 btrfs_sysfs_rm_device_link(root->fs_info->fs_devices, device);
1937 } 1931 }
1938 1932
1939 btrfs_close_bdev(device);
1940
1941 call_rcu(&device->rcu, free_device);
1942
1943 num_devices = btrfs_super_num_devices(root->fs_info->super_copy) - 1; 1933 num_devices = btrfs_super_num_devices(root->fs_info->super_copy) - 1;
1944 btrfs_set_super_num_devices(root->fs_info->super_copy, num_devices); 1934 btrfs_set_super_num_devices(root->fs_info->super_copy, num_devices);
1945 mutex_unlock(&root->fs_info->fs_devices->device_list_mutex); 1935 mutex_unlock(&root->fs_info->fs_devices->device_list_mutex);
1946 1936
1937 /*
1938 * at this point, the device is zero sized and detached from
1939 * the devices list. All that's left is to zero out the old
1940 * supers and free the device.
1941 */
1942 if (device->writeable)
1943 btrfs_scratch_superblocks(device->bdev, device->name->str);
1944
1945 btrfs_close_bdev(device);
1946 call_rcu(&device->rcu, free_device);
1947
1947 if (cur_devices->open_devices == 0) { 1948 if (cur_devices->open_devices == 0) {
1948 struct btrfs_fs_devices *fs_devices; 1949 struct btrfs_fs_devices *fs_devices;
1949 fs_devices = root->fs_info->fs_devices; 1950 fs_devices = root->fs_info->fs_devices;
@@ -1962,24 +1963,7 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path, u64 devid)
1962 root->fs_info->num_tolerated_disk_barrier_failures = 1963 root->fs_info->num_tolerated_disk_barrier_failures =
1963 btrfs_calc_num_tolerated_disk_barrier_failures(root->fs_info); 1964 btrfs_calc_num_tolerated_disk_barrier_failures(root->fs_info);
1964 1965
1965 /*
1966 * at this point, the device is zero sized. We want to
1967 * remove it from the devices list and zero out the old super
1968 */
1969 if (clear_super) {
1970 struct block_device *bdev;
1971
1972 bdev = blkdev_get_by_path(dev_name, FMODE_READ | FMODE_EXCL,
1973 root->fs_info->bdev_holder);
1974 if (!IS_ERR(bdev)) {
1975 btrfs_scratch_superblocks(bdev, dev_name);
1976 blkdev_put(bdev, FMODE_READ | FMODE_EXCL);
1977 }
1978 }
1979
1980out: 1966out:
1981 kfree(dev_name);
1982
1983 mutex_unlock(&uuid_mutex); 1967 mutex_unlock(&uuid_mutex);
1984 return ret; 1968 return ret;
1985 1969