diff options
Diffstat (limited to 'fs/block_dev.c')
-rw-r--r-- | fs/block_dev.c | 65 |
1 files changed, 22 insertions, 43 deletions
diff --git a/fs/block_dev.c b/fs/block_dev.c index 4b595904cefd..b89c956e04f6 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c | |||
@@ -844,9 +844,8 @@ struct block_device *open_by_devnum(dev_t dev, fmode_t mode) | |||
844 | { | 844 | { |
845 | struct block_device *bdev = bdget(dev); | 845 | struct block_device *bdev = bdget(dev); |
846 | int err = -ENOMEM; | 846 | int err = -ENOMEM; |
847 | int flags = mode & FMODE_WRITE ? O_RDWR : O_RDONLY; | ||
848 | if (bdev) | 847 | if (bdev) |
849 | err = blkdev_get(bdev, mode, flags); | 848 | err = blkdev_get(bdev, mode); |
850 | return err ? ERR_PTR(err) : bdev; | 849 | return err ? ERR_PTR(err) : bdev; |
851 | } | 850 | } |
852 | 851 | ||
@@ -975,8 +974,6 @@ void bd_set_size(struct block_device *bdev, loff_t size) | |||
975 | } | 974 | } |
976 | EXPORT_SYMBOL(bd_set_size); | 975 | EXPORT_SYMBOL(bd_set_size); |
977 | 976 | ||
978 | static int __blkdev_get(struct block_device *bdev, fmode_t mode, unsigned flags, | ||
979 | int for_part); | ||
980 | static int __blkdev_put(struct block_device *bdev, fmode_t mode, int for_part); | 977 | static int __blkdev_put(struct block_device *bdev, fmode_t mode, int for_part); |
981 | 978 | ||
982 | /* | 979 | /* |
@@ -986,7 +983,7 @@ static int __blkdev_put(struct block_device *bdev, fmode_t mode, int for_part); | |||
986 | * mutex_lock_nested(whole->bd_mutex, 1) | 983 | * mutex_lock_nested(whole->bd_mutex, 1) |
987 | */ | 984 | */ |
988 | 985 | ||
989 | static int do_open(struct block_device *bdev, struct file *file, int for_part) | 986 | static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part) |
990 | { | 987 | { |
991 | struct gendisk *disk; | 988 | struct gendisk *disk; |
992 | struct hd_struct *part = NULL; | 989 | struct hd_struct *part = NULL; |
@@ -994,9 +991,9 @@ static int do_open(struct block_device *bdev, struct file *file, int for_part) | |||
994 | int partno; | 991 | int partno; |
995 | int perm = 0; | 992 | int perm = 0; |
996 | 993 | ||
997 | if (file->f_mode & FMODE_READ) | 994 | if (mode & FMODE_READ) |
998 | perm |= MAY_READ; | 995 | perm |= MAY_READ; |
999 | if (file->f_mode & FMODE_WRITE) | 996 | if (mode & FMODE_WRITE) |
1000 | perm |= MAY_WRITE; | 997 | perm |= MAY_WRITE; |
1001 | /* | 998 | /* |
1002 | * hooks: /n/, see "layering violations". | 999 | * hooks: /n/, see "layering violations". |
@@ -1007,15 +1004,7 @@ static int do_open(struct block_device *bdev, struct file *file, int for_part) | |||
1007 | return ret; | 1004 | return ret; |
1008 | } | 1005 | } |
1009 | 1006 | ||
1010 | if (file->f_flags & O_NDELAY) | ||
1011 | file->f_mode |= FMODE_NDELAY; | ||
1012 | if (file->f_flags & O_EXCL) | ||
1013 | file->f_mode |= FMODE_EXCL; | ||
1014 | if ((file->f_flags & O_ACCMODE) == 3) | ||
1015 | file->f_mode |= FMODE_WRITE_IOCTL; | ||
1016 | |||
1017 | ret = -ENXIO; | 1007 | ret = -ENXIO; |
1018 | file->f_mapping = bdev->bd_inode->i_mapping; | ||
1019 | 1008 | ||
1020 | lock_kernel(); | 1009 | lock_kernel(); |
1021 | 1010 | ||
@@ -1034,7 +1023,7 @@ static int do_open(struct block_device *bdev, struct file *file, int for_part) | |||
1034 | if (!partno) { | 1023 | if (!partno) { |
1035 | struct backing_dev_info *bdi; | 1024 | struct backing_dev_info *bdi; |
1036 | if (disk->fops->open) { | 1025 | if (disk->fops->open) { |
1037 | ret = disk->fops->open(bdev, file->f_mode); | 1026 | ret = disk->fops->open(bdev, mode); |
1038 | if (ret) | 1027 | if (ret) |
1039 | goto out_clear; | 1028 | goto out_clear; |
1040 | } | 1029 | } |
@@ -1054,7 +1043,7 @@ static int do_open(struct block_device *bdev, struct file *file, int for_part) | |||
1054 | if (!whole) | 1043 | if (!whole) |
1055 | goto out_clear; | 1044 | goto out_clear; |
1056 | BUG_ON(for_part); | 1045 | BUG_ON(for_part); |
1057 | ret = __blkdev_get(whole, file->f_mode, file->f_flags, 1); | 1046 | ret = __blkdev_get(whole, mode, 1); |
1058 | if (ret) | 1047 | if (ret) |
1059 | goto out_clear; | 1048 | goto out_clear; |
1060 | bdev->bd_contains = whole; | 1049 | bdev->bd_contains = whole; |
@@ -1075,7 +1064,7 @@ static int do_open(struct block_device *bdev, struct file *file, int for_part) | |||
1075 | disk = NULL; | 1064 | disk = NULL; |
1076 | if (bdev->bd_contains == bdev) { | 1065 | if (bdev->bd_contains == bdev) { |
1077 | if (bdev->bd_disk->fops->open) { | 1066 | if (bdev->bd_disk->fops->open) { |
1078 | ret = bdev->bd_disk->fops->open(bdev, file->f_mode); | 1067 | ret = bdev->bd_disk->fops->open(bdev, mode); |
1079 | if (ret) | 1068 | if (ret) |
1080 | goto out_unlock_bdev; | 1069 | goto out_unlock_bdev; |
1081 | } | 1070 | } |
@@ -1095,7 +1084,7 @@ static int do_open(struct block_device *bdev, struct file *file, int for_part) | |||
1095 | bdev->bd_part = NULL; | 1084 | bdev->bd_part = NULL; |
1096 | bdev->bd_inode->i_data.backing_dev_info = &default_backing_dev_info; | 1085 | bdev->bd_inode->i_data.backing_dev_info = &default_backing_dev_info; |
1097 | if (bdev != bdev->bd_contains) | 1086 | if (bdev != bdev->bd_contains) |
1098 | __blkdev_put(bdev->bd_contains, file->f_mode, 1); | 1087 | __blkdev_put(bdev->bd_contains, mode, 1); |
1099 | bdev->bd_contains = NULL; | 1088 | bdev->bd_contains = NULL; |
1100 | out_unlock_bdev: | 1089 | out_unlock_bdev: |
1101 | mutex_unlock(&bdev->bd_mutex); | 1090 | mutex_unlock(&bdev->bd_mutex); |
@@ -1111,28 +1100,9 @@ static int do_open(struct block_device *bdev, struct file *file, int for_part) | |||
1111 | return ret; | 1100 | return ret; |
1112 | } | 1101 | } |
1113 | 1102 | ||
1114 | static int __blkdev_get(struct block_device *bdev, fmode_t mode, unsigned flags, | 1103 | int blkdev_get(struct block_device *bdev, fmode_t mode) |
1115 | int for_part) | ||
1116 | { | ||
1117 | /* | ||
1118 | * This crockload is due to bad choice of ->open() type. | ||
1119 | * It will go away. | ||
1120 | * For now, block device ->open() routine must _not_ | ||
1121 | * examine anything in 'inode' argument except ->i_rdev. | ||
1122 | */ | ||
1123 | struct file fake_file = {}; | ||
1124 | struct dentry fake_dentry = {}; | ||
1125 | fake_file.f_mode = mode; | ||
1126 | fake_file.f_flags = flags; | ||
1127 | fake_file.f_path.dentry = &fake_dentry; | ||
1128 | fake_dentry.d_inode = bdev->bd_inode; | ||
1129 | |||
1130 | return do_open(bdev, &fake_file, for_part); | ||
1131 | } | ||
1132 | |||
1133 | int blkdev_get(struct block_device *bdev, fmode_t mode, unsigned flags) | ||
1134 | { | 1104 | { |
1135 | return __blkdev_get(bdev, mode, flags, 0); | 1105 | return __blkdev_get(bdev, mode, 0); |
1136 | } | 1106 | } |
1137 | EXPORT_SYMBOL(blkdev_get); | 1107 | EXPORT_SYMBOL(blkdev_get); |
1138 | 1108 | ||
@@ -1149,15 +1119,24 @@ static int blkdev_open(struct inode * inode, struct file * filp) | |||
1149 | */ | 1119 | */ |
1150 | filp->f_flags |= O_LARGEFILE; | 1120 | filp->f_flags |= O_LARGEFILE; |
1151 | 1121 | ||
1122 | if (filp->f_flags & O_NDELAY) | ||
1123 | filp->f_mode |= FMODE_NDELAY; | ||
1124 | if (filp->f_flags & O_EXCL) | ||
1125 | filp->f_mode |= FMODE_EXCL; | ||
1126 | if ((filp->f_flags & O_ACCMODE) == 3) | ||
1127 | filp->f_mode |= FMODE_WRITE_IOCTL; | ||
1128 | |||
1152 | bdev = bd_acquire(inode); | 1129 | bdev = bd_acquire(inode); |
1153 | if (bdev == NULL) | 1130 | if (bdev == NULL) |
1154 | return -ENOMEM; | 1131 | return -ENOMEM; |
1155 | 1132 | ||
1156 | res = do_open(bdev, filp, 0); | 1133 | filp->f_mapping = bdev->bd_inode->i_mapping; |
1134 | |||
1135 | res = blkdev_get(bdev, filp->f_mode); | ||
1157 | if (res) | 1136 | if (res) |
1158 | return res; | 1137 | return res; |
1159 | 1138 | ||
1160 | if (!(filp->f_flags & O_EXCL) ) | 1139 | if (!(filp->f_mode & FMODE_EXCL)) |
1161 | return 0; | 1140 | return 0; |
1162 | 1141 | ||
1163 | if (!(res = bd_claim(bdev, filp))) | 1142 | if (!(res = bd_claim(bdev, filp))) |
@@ -1327,7 +1306,7 @@ struct block_device *open_bdev_exclusive(const char *path, fmode_t mode, void *h | |||
1327 | if (IS_ERR(bdev)) | 1306 | if (IS_ERR(bdev)) |
1328 | return bdev; | 1307 | return bdev; |
1329 | 1308 | ||
1330 | error = blkdev_get(bdev, mode, 0); | 1309 | error = blkdev_get(bdev, mode); |
1331 | if (error) | 1310 | if (error) |
1332 | return ERR_PTR(error); | 1311 | return ERR_PTR(error); |
1333 | error = -EACCES; | 1312 | error = -EACCES; |