diff options
Diffstat (limited to 'fs/block_dev.c')
-rw-r--r-- | fs/block_dev.c | 14 |
1 files changed, 14 insertions, 0 deletions
diff --git a/fs/block_dev.c b/fs/block_dev.c index b957717e25ab..8ebbfdf708c2 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c | |||
@@ -1005,6 +1005,7 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part) | |||
1005 | } | 1005 | } |
1006 | 1006 | ||
1007 | lock_kernel(); | 1007 | lock_kernel(); |
1008 | restart: | ||
1008 | 1009 | ||
1009 | ret = -ENXIO; | 1010 | ret = -ENXIO; |
1010 | disk = get_gendisk(bdev->bd_dev, &partno); | 1011 | disk = get_gendisk(bdev->bd_dev, &partno); |
@@ -1025,6 +1026,19 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part) | |||
1025 | 1026 | ||
1026 | if (disk->fops->open) { | 1027 | if (disk->fops->open) { |
1027 | ret = disk->fops->open(bdev, mode); | 1028 | ret = disk->fops->open(bdev, mode); |
1029 | if (ret == -ERESTARTSYS) { | ||
1030 | /* Lost a race with 'disk' being | ||
1031 | * deleted, try again. | ||
1032 | * See md.c | ||
1033 | */ | ||
1034 | disk_put_part(bdev->bd_part); | ||
1035 | bdev->bd_part = NULL; | ||
1036 | module_put(disk->fops->owner); | ||
1037 | put_disk(disk); | ||
1038 | bdev->bd_disk = NULL; | ||
1039 | mutex_unlock(&bdev->bd_mutex); | ||
1040 | goto restart; | ||
1041 | } | ||
1028 | if (ret) | 1042 | if (ret) |
1029 | goto out_clear; | 1043 | goto out_clear; |
1030 | } | 1044 | } |