Skip to content

Commit 1423881

Browse files
asjmasoncl
authored andcommitted
btrfs: do not background blkdev_put()
At the end of unmount/dev-delete, if the device exclusive open is not actually closed, then there might be a race with another program in the userland who is trying to open the device in exclusive mode and it may fail for eg: unmount /btrfs; fsck /dev/x btrfs dev del /dev/x /btrfs; fsck /dev/x so here background blkdev_put() is not a choice Signed-off-by: Anand Jain <[email protected]> Reviewed-by: David Sterba <[email protected]> Signed-off-by: David Sterba <[email protected]> Signed-off-by: Chris Mason <[email protected]>
1 parent 28b737f commit 1423881

File tree

1 file changed

+19
-8
lines changed

1 file changed

+19
-8
lines changed

fs/btrfs/volumes.c

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -834,10 +834,6 @@ static void __free_device(struct work_struct *work)
834834
struct btrfs_device *device;
835835

836836
device = container_of(work, struct btrfs_device, rcu_work);
837-
838-
if (device->bdev)
839-
blkdev_put(device->bdev, device->mode);
840-
841837
rcu_string_free(device->name);
842838
kfree(device);
843839
}
@@ -852,6 +848,17 @@ static void free_device(struct rcu_head *head)
852848
schedule_work(&device->rcu_work);
853849
}
854850

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+
855862
static void btrfs_close_one_device(struct btrfs_device *device)
856863
{
857864
struct btrfs_fs_devices *fs_devices = device->fs_devices;
@@ -870,10 +877,7 @@ static void btrfs_close_one_device(struct btrfs_device *device)
870877
if (device->missing)
871878
fs_devices->missing_devices--;
872879

873-
if (device->bdev && device->writeable) {
874-
sync_blockdev(device->bdev);
875-
invalidate_bdev(device->bdev);
876-
}
880+
btrfs_close_bdev(device);
877881

878882
new_device = btrfs_alloc_device(NULL, &device->devid,
879883
device->uuid);
@@ -1932,6 +1936,8 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path, u64 devid)
19321936
btrfs_sysfs_rm_device_link(root->fs_info->fs_devices, device);
19331937
}
19341938

1939+
btrfs_close_bdev(device);
1940+
19351941
call_rcu(&device->rcu, free_device);
19361942

19371943
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,
20252031
/* zero out the old super if it is writable */
20262032
btrfs_scratch_superblocks(srcdev->bdev, srcdev->name->str);
20272033
}
2034+
2035+
btrfs_close_bdev(srcdev);
2036+
20282037
call_rcu(&srcdev->rcu, free_device);
20292038

20302039
/*
@@ -2080,6 +2089,8 @@ void btrfs_destroy_dev_replace_tgtdev(struct btrfs_fs_info *fs_info,
20802089
* the device_list_mutex lock.
20812090
*/
20822091
btrfs_scratch_superblocks(tgtdev->bdev, tgtdev->name->str);
2092+
2093+
btrfs_close_bdev(tgtdev);
20832094
call_rcu(&tgtdev->rcu, free_device);
20842095
}
20852096

0 commit comments

Comments
 (0)