* [PATCH] btrfs: clean the old superblocks before freeing the device
@ 2016-09-20 12:50 jeffm
2016-09-21 14:13 ` David Sterba
0 siblings, 1 reply; 2+ messages in thread
From: jeffm @ 2016-09-20 12:50 UTC (permalink / raw)
To: linux-btrfs
From: Jeff Mahoney <jeffm@suse.com>
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>
---
fs/btrfs/volumes.c | 38 +++++++++++---------------------------
1 file changed, 11 insertions(+), 27 deletions(-)
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index c41f8c1..3adf5ce 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)
u64 num_devices;
int ret = 0;
bool clear_super = false;
- char *dev_name = NULL;
mutex_lock(&uuid_mutex);
@@ -1882,11 +1881,6 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path, u64 devid)
list_del_init(&device->dev_alloc_list);
device->fs_devices->rw_devices--;
unlock_chunks(root);
- dev_name = kstrdup(device->name->str, GFP_KERNEL);
- if (!dev_name) {
- ret = -ENOMEM;
- goto error_undo;
- }
clear_super = true;
}
@@ -1936,14 +1930,21 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path, u64 devid)
btrfs_sysfs_rm_device_link(root->fs_info->fs_devices, device);
}
- btrfs_close_bdev(device);
-
- call_rcu(&device->rcu, free_device);
-
num_devices = btrfs_super_num_devices(root->fs_info->super_copy) - 1;
btrfs_set_super_num_devices(root->fs_info->super_copy, num_devices);
mutex_unlock(&root->fs_info->fs_devices->device_list_mutex);
+ /*
+ * at this point, the device is zero sized and detached from
+ * the devices list. All that's left is to zero out the old
+ * supers and free the device.
+ */
+ if (device->writeable)
+ btrfs_scratch_superblocks(device->bdev, device->name->str);
+
+ btrfs_close_bdev(device);
+ call_rcu(&device->rcu, free_device);
+
if (cur_devices->open_devices == 0) {
struct btrfs_fs_devices *fs_devices;
fs_devices = root->fs_info->fs_devices;
@@ -1962,24 +1963,7 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path, u64 devid)
root->fs_info->num_tolerated_disk_barrier_failures =
btrfs_calc_num_tolerated_disk_barrier_failures(root->fs_info);
- /*
- * at this point, the device is zero sized. We want to
- * remove it from the devices list and zero out the old super
- */
- if (clear_super) {
- struct block_device *bdev;
-
- bdev = blkdev_get_by_path(dev_name, FMODE_READ | FMODE_EXCL,
- root->fs_info->bdev_holder);
- if (!IS_ERR(bdev)) {
- btrfs_scratch_superblocks(bdev, dev_name);
- blkdev_put(bdev, FMODE_READ | FMODE_EXCL);
- }
- }
-
out:
- kfree(dev_name);
-
mutex_unlock(&uuid_mutex);
return ret;
--
2.7.1
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH] btrfs: clean the old superblocks before freeing the device
2016-09-20 12:50 [PATCH] btrfs: clean the old superblocks before freeing the device jeffm
@ 2016-09-21 14:13 ` David Sterba
0 siblings, 0 replies; 2+ messages in thread
From: David Sterba @ 2016-09-21 14:13 UTC (permalink / raw)
To: jeffm; +Cc: linux-btrfs
On Tue, Sep 20, 2016 at 08:50:21AM -0400, jeffm@suse.com wrote:
> From: Jeff Mahoney <jeffm@suse.com>
>
> 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>
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2016-09-21 14:15 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-09-20 12:50 [PATCH] btrfs: clean the old superblocks before freeing the device jeffm
2016-09-21 14:13 ` David Sterba
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.