diff options
Diffstat (limited to 'fs/block_dev.c')
-rw-r--r-- | fs/block_dev.c | 67 |
1 files changed, 31 insertions, 36 deletions
diff --git a/fs/block_dev.c b/fs/block_dev.c index 57d572642854..c3fa19bd64df 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c | |||
@@ -540,14 +540,6 @@ EXPORT_SYMBOL(bd_release); | |||
540 | * /sys/block/sda/holders/dm-0 --> /sys/block/dm-0 | 540 | * /sys/block/sda/holders/dm-0 --> /sys/block/dm-0 |
541 | */ | 541 | */ |
542 | 542 | ||
543 | static struct kobject *bdev_get_kobj(struct block_device *bdev) | ||
544 | { | ||
545 | if (bdev->bd_contains != bdev) | ||
546 | return kobject_get(&part_to_dev(bdev->bd_part)->kobj); | ||
547 | else | ||
548 | return kobject_get(&disk_to_dev(bdev->bd_disk)->kobj); | ||
549 | } | ||
550 | |||
551 | static int add_symlink(struct kobject *from, struct kobject *to) | 543 | static int add_symlink(struct kobject *from, struct kobject *to) |
552 | { | 544 | { |
553 | if (!from || !to) | 545 | if (!from || !to) |
@@ -596,7 +588,7 @@ static int bd_holder_grab_dirs(struct block_device *bdev, | |||
596 | if (!bo->hdev) | 588 | if (!bo->hdev) |
597 | goto fail_put_sdir; | 589 | goto fail_put_sdir; |
598 | 590 | ||
599 | bo->sdev = bdev_get_kobj(bdev); | 591 | bo->sdev = kobject_get(&part_to_dev(bdev->bd_part)->kobj); |
600 | if (!bo->sdev) | 592 | if (!bo->sdev) |
601 | goto fail_put_hdev; | 593 | goto fail_put_hdev; |
602 | 594 | ||
@@ -919,7 +911,6 @@ static int __blkdev_put(struct block_device *bdev, int for_part); | |||
919 | 911 | ||
920 | static int do_open(struct block_device *bdev, struct file *file, int for_part) | 912 | static int do_open(struct block_device *bdev, struct file *file, int for_part) |
921 | { | 913 | { |
922 | struct module *owner = NULL; | ||
923 | struct gendisk *disk; | 914 | struct gendisk *disk; |
924 | struct hd_struct *part = NULL; | 915 | struct hd_struct *part = NULL; |
925 | int ret; | 916 | int ret; |
@@ -941,25 +932,27 @@ static int do_open(struct block_device *bdev, struct file *file, int for_part) | |||
941 | 932 | ||
942 | ret = -ENXIO; | 933 | ret = -ENXIO; |
943 | file->f_mapping = bdev->bd_inode->i_mapping; | 934 | file->f_mapping = bdev->bd_inode->i_mapping; |
935 | |||
944 | lock_kernel(); | 936 | lock_kernel(); |
937 | |||
945 | disk = get_gendisk(bdev->bd_dev, &partno); | 938 | disk = get_gendisk(bdev->bd_dev, &partno); |
946 | if (!disk) { | 939 | if (!disk) |
947 | unlock_kernel(); | 940 | goto out_unlock_kernel; |
948 | bdput(bdev); | 941 | part = disk_get_part(disk, partno); |
949 | return ret; | 942 | if (!part) |
950 | } | 943 | goto out_unlock_kernel; |
951 | owner = disk->fops->owner; | ||
952 | 944 | ||
953 | mutex_lock_nested(&bdev->bd_mutex, for_part); | 945 | mutex_lock_nested(&bdev->bd_mutex, for_part); |
954 | if (!bdev->bd_openers) { | 946 | if (!bdev->bd_openers) { |
955 | bdev->bd_disk = disk; | 947 | bdev->bd_disk = disk; |
948 | bdev->bd_part = part; | ||
956 | bdev->bd_contains = bdev; | 949 | bdev->bd_contains = bdev; |
957 | if (!partno) { | 950 | if (!partno) { |
958 | struct backing_dev_info *bdi; | 951 | struct backing_dev_info *bdi; |
959 | if (disk->fops->open) { | 952 | if (disk->fops->open) { |
960 | ret = disk->fops->open(bdev->bd_inode, file); | 953 | ret = disk->fops->open(bdev->bd_inode, file); |
961 | if (ret) | 954 | if (ret) |
962 | goto out_first; | 955 | goto out_clear; |
963 | } | 956 | } |
964 | if (!bdev->bd_openers) { | 957 | if (!bdev->bd_openers) { |
965 | bd_set_size(bdev,(loff_t)get_capacity(disk)<<9); | 958 | bd_set_size(bdev,(loff_t)get_capacity(disk)<<9); |
@@ -975,31 +968,32 @@ static int do_open(struct block_device *bdev, struct file *file, int for_part) | |||
975 | whole = bdget_disk(disk, 0); | 968 | whole = bdget_disk(disk, 0); |
976 | ret = -ENOMEM; | 969 | ret = -ENOMEM; |
977 | if (!whole) | 970 | if (!whole) |
978 | goto out_first; | 971 | goto out_clear; |
979 | BUG_ON(for_part); | 972 | BUG_ON(for_part); |
980 | ret = __blkdev_get(whole, file->f_mode, file->f_flags, 1); | 973 | ret = __blkdev_get(whole, file->f_mode, file->f_flags, 1); |
981 | if (ret) | 974 | if (ret) |
982 | goto out_first; | 975 | goto out_clear; |
983 | bdev->bd_contains = whole; | 976 | bdev->bd_contains = whole; |
984 | part = disk_get_part(disk, partno); | ||
985 | bdev->bd_inode->i_data.backing_dev_info = | 977 | bdev->bd_inode->i_data.backing_dev_info = |
986 | whole->bd_inode->i_data.backing_dev_info; | 978 | whole->bd_inode->i_data.backing_dev_info; |
987 | if (!(disk->flags & GENHD_FL_UP) || | 979 | if (!(disk->flags & GENHD_FL_UP) || |
988 | !part || !part->nr_sects) { | 980 | !part || !part->nr_sects) { |
989 | ret = -ENXIO; | 981 | ret = -ENXIO; |
990 | goto out_first; | 982 | goto out_clear; |
991 | } | 983 | } |
992 | bdev->bd_part = part; | ||
993 | bd_set_size(bdev, (loff_t)part->nr_sects << 9); | 984 | bd_set_size(bdev, (loff_t)part->nr_sects << 9); |
994 | } | 985 | } |
995 | } else { | 986 | } else { |
987 | disk_put_part(part); | ||
996 | put_disk(disk); | 988 | put_disk(disk); |
997 | module_put(owner); | 989 | module_put(disk->fops->owner); |
990 | part = NULL; | ||
991 | disk = NULL; | ||
998 | if (bdev->bd_contains == bdev) { | 992 | if (bdev->bd_contains == bdev) { |
999 | if (bdev->bd_disk->fops->open) { | 993 | if (bdev->bd_disk->fops->open) { |
1000 | ret = bdev->bd_disk->fops->open(bdev->bd_inode, file); | 994 | ret = bdev->bd_disk->fops->open(bdev->bd_inode, file); |
1001 | if (ret) | 995 | if (ret) |
1002 | goto out; | 996 | goto out_unlock_bdev; |
1003 | } | 997 | } |
1004 | if (bdev->bd_invalidated) | 998 | if (bdev->bd_invalidated) |
1005 | rescan_partitions(bdev->bd_disk, bdev); | 999 | rescan_partitions(bdev->bd_disk, bdev); |
@@ -1012,20 +1006,24 @@ static int do_open(struct block_device *bdev, struct file *file, int for_part) | |||
1012 | unlock_kernel(); | 1006 | unlock_kernel(); |
1013 | return 0; | 1007 | return 0; |
1014 | 1008 | ||
1015 | out_first: | 1009 | out_clear: |
1016 | bdev->bd_disk = NULL; | 1010 | bdev->bd_disk = NULL; |
1011 | bdev->bd_part = NULL; | ||
1017 | bdev->bd_inode->i_data.backing_dev_info = &default_backing_dev_info; | 1012 | bdev->bd_inode->i_data.backing_dev_info = &default_backing_dev_info; |
1018 | if (bdev != bdev->bd_contains) | 1013 | if (bdev != bdev->bd_contains) |
1019 | __blkdev_put(bdev->bd_contains, 1); | 1014 | __blkdev_put(bdev->bd_contains, 1); |
1020 | bdev->bd_contains = NULL; | 1015 | bdev->bd_contains = NULL; |
1021 | put_disk(disk); | 1016 | out_unlock_bdev: |
1022 | disk_put_part(part); | ||
1023 | module_put(owner); | ||
1024 | out: | ||
1025 | mutex_unlock(&bdev->bd_mutex); | 1017 | mutex_unlock(&bdev->bd_mutex); |
1018 | out_unlock_kernel: | ||
1026 | unlock_kernel(); | 1019 | unlock_kernel(); |
1027 | if (ret) | 1020 | |
1028 | bdput(bdev); | 1021 | disk_put_part(part); |
1022 | if (disk) | ||
1023 | module_put(disk->fops->owner); | ||
1024 | put_disk(disk); | ||
1025 | bdput(bdev); | ||
1026 | |||
1029 | return ret; | 1027 | return ret; |
1030 | } | 1028 | } |
1031 | 1029 | ||
@@ -1110,11 +1108,8 @@ static int __blkdev_put(struct block_device *bdev, int for_part) | |||
1110 | 1108 | ||
1111 | put_disk(disk); | 1109 | put_disk(disk); |
1112 | module_put(owner); | 1110 | module_put(owner); |
1113 | 1111 | disk_put_part(bdev->bd_part); | |
1114 | if (bdev->bd_contains != bdev) { | 1112 | bdev->bd_part = NULL; |
1115 | disk_put_part(bdev->bd_part); | ||
1116 | bdev->bd_part = NULL; | ||
1117 | } | ||
1118 | bdev->bd_disk = NULL; | 1113 | bdev->bd_disk = NULL; |
1119 | bdev->bd_inode->i_data.backing_dev_info = &default_backing_dev_info; | 1114 | bdev->bd_inode->i_data.backing_dev_info = &default_backing_dev_info; |
1120 | if (bdev != bdev->bd_contains) | 1115 | if (bdev != bdev->bd_contains) |