diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-10-23 13:23:07 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-10-23 13:23:07 -0400 |
commit | 22484856402bfa1ff3defe47f6029ab0418240d9 (patch) | |
tree | 140c67bf59674da350a7b51765d6ff7eb101b597 /fs/block_dev.c | |
parent | 5ed487bc2c44ca4e9668ef9cb54c830e2a9fac47 (diff) | |
parent | 56b26add02b4bdea81d5e0ebda60db1fe3311ad4 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/viro/bdev
* git://git.kernel.org/pub/scm/linux/kernel/git/viro/bdev: (66 commits)
[PATCH] kill the rest of struct file propagation in block ioctls
[PATCH] get rid of struct file use in blkdev_ioctl() BLKBSZSET
[PATCH] get rid of blkdev_locked_ioctl()
[PATCH] get rid of blkdev_driver_ioctl()
[PATCH] sanitize blkdev_get() and friends
[PATCH] remember mode of reiserfs journal
[PATCH] propagate mode through swsusp_close()
[PATCH] propagate mode through open_bdev_excl/close_bdev_excl
[PATCH] pass fmode_t to blkdev_put()
[PATCH] kill the unused bsize on the send side of /dev/loop
[PATCH] trim file propagation in block/compat_ioctl.c
[PATCH] end of methods switch: remove the old ones
[PATCH] switch sr
[PATCH] switch sd
[PATCH] switch ide-scsi
[PATCH] switch tape_block
[PATCH] switch dcssblk
[PATCH] switch dasd
[PATCH] switch mtd_blkdevs
[PATCH] switch mmc
...
Diffstat (limited to 'fs/block_dev.c')
-rw-r--r-- | fs/block_dev.c | 111 |
1 files changed, 49 insertions, 62 deletions
diff --git a/fs/block_dev.c b/fs/block_dev.c index d06fe3c3dd3f..88a776fa0ef6 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c | |||
@@ -840,13 +840,12 @@ EXPORT_SYMBOL_GPL(bd_release_from_disk); | |||
840 | * to be used for internal purposes. If you ever need it - reconsider | 840 | * to be used for internal purposes. If you ever need it - reconsider |
841 | * your API. | 841 | * your API. |
842 | */ | 842 | */ |
843 | struct block_device *open_by_devnum(dev_t dev, unsigned mode) | 843 | 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,9 +974,7 @@ 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, mode_t mode, unsigned flags, | 977 | static int __blkdev_put(struct block_device *bdev, fmode_t mode, int for_part); |
979 | int for_part); | ||
980 | static int __blkdev_put(struct block_device *bdev, int for_part); | ||
981 | 978 | ||
982 | /* | 979 | /* |
983 | * bd_mutex locking: | 980 | * bd_mutex locking: |
@@ -986,7 +983,7 @@ static int __blkdev_put(struct block_device *bdev, 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". |
@@ -1008,7 +1005,6 @@ static int do_open(struct block_device *bdev, struct file *file, int for_part) | |||
1008 | } | 1005 | } |
1009 | 1006 | ||
1010 | ret = -ENXIO; | 1007 | ret = -ENXIO; |
1011 | file->f_mapping = bdev->bd_inode->i_mapping; | ||
1012 | 1008 | ||
1013 | lock_kernel(); | 1009 | lock_kernel(); |
1014 | 1010 | ||
@@ -1027,7 +1023,7 @@ static int do_open(struct block_device *bdev, struct file *file, int for_part) | |||
1027 | if (!partno) { | 1023 | if (!partno) { |
1028 | struct backing_dev_info *bdi; | 1024 | struct backing_dev_info *bdi; |
1029 | if (disk->fops->open) { | 1025 | if (disk->fops->open) { |
1030 | ret = disk->fops->open(bdev->bd_inode, file); | 1026 | ret = disk->fops->open(bdev, mode); |
1031 | if (ret) | 1027 | if (ret) |
1032 | goto out_clear; | 1028 | goto out_clear; |
1033 | } | 1029 | } |
@@ -1047,7 +1043,7 @@ static int do_open(struct block_device *bdev, struct file *file, int for_part) | |||
1047 | if (!whole) | 1043 | if (!whole) |
1048 | goto out_clear; | 1044 | goto out_clear; |
1049 | BUG_ON(for_part); | 1045 | BUG_ON(for_part); |
1050 | ret = __blkdev_get(whole, file->f_mode, file->f_flags, 1); | 1046 | ret = __blkdev_get(whole, mode, 1); |
1051 | if (ret) | 1047 | if (ret) |
1052 | goto out_clear; | 1048 | goto out_clear; |
1053 | bdev->bd_contains = whole; | 1049 | bdev->bd_contains = whole; |
@@ -1068,7 +1064,7 @@ static int do_open(struct block_device *bdev, struct file *file, int for_part) | |||
1068 | disk = NULL; | 1064 | disk = NULL; |
1069 | if (bdev->bd_contains == bdev) { | 1065 | if (bdev->bd_contains == bdev) { |
1070 | if (bdev->bd_disk->fops->open) { | 1066 | if (bdev->bd_disk->fops->open) { |
1071 | ret = bdev->bd_disk->fops->open(bdev->bd_inode, file); | 1067 | ret = bdev->bd_disk->fops->open(bdev, mode); |
1072 | if (ret) | 1068 | if (ret) |
1073 | goto out_unlock_bdev; | 1069 | goto out_unlock_bdev; |
1074 | } | 1070 | } |
@@ -1088,7 +1084,7 @@ static int do_open(struct block_device *bdev, struct file *file, int for_part) | |||
1088 | bdev->bd_part = NULL; | 1084 | bdev->bd_part = NULL; |
1089 | 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; |
1090 | if (bdev != bdev->bd_contains) | 1086 | if (bdev != bdev->bd_contains) |
1091 | __blkdev_put(bdev->bd_contains, 1); | 1087 | __blkdev_put(bdev->bd_contains, mode, 1); |
1092 | bdev->bd_contains = NULL; | 1088 | bdev->bd_contains = NULL; |
1093 | out_unlock_bdev: | 1089 | out_unlock_bdev: |
1094 | mutex_unlock(&bdev->bd_mutex); | 1090 | mutex_unlock(&bdev->bd_mutex); |
@@ -1104,28 +1100,9 @@ static int do_open(struct block_device *bdev, struct file *file, int for_part) | |||
1104 | return ret; | 1100 | return ret; |
1105 | } | 1101 | } |
1106 | 1102 | ||
1107 | static int __blkdev_get(struct block_device *bdev, mode_t mode, unsigned flags, | 1103 | int blkdev_get(struct block_device *bdev, fmode_t mode) |
1108 | int for_part) | ||
1109 | { | 1104 | { |
1110 | /* | 1105 | return __blkdev_get(bdev, mode, 0); |
1111 | * This crockload is due to bad choice of ->open() type. | ||
1112 | * It will go away. | ||
1113 | * For now, block device ->open() routine must _not_ | ||
1114 | * examine anything in 'inode' argument except ->i_rdev. | ||
1115 | */ | ||
1116 | struct file fake_file = {}; | ||
1117 | struct dentry fake_dentry = {}; | ||
1118 | fake_file.f_mode = mode; | ||
1119 | fake_file.f_flags = flags; | ||
1120 | fake_file.f_path.dentry = &fake_dentry; | ||
1121 | fake_dentry.d_inode = bdev->bd_inode; | ||
1122 | |||
1123 | return do_open(bdev, &fake_file, for_part); | ||
1124 | } | ||
1125 | |||
1126 | int blkdev_get(struct block_device *bdev, mode_t mode, unsigned flags) | ||
1127 | { | ||
1128 | return __blkdev_get(bdev, mode, flags, 0); | ||
1129 | } | 1106 | } |
1130 | EXPORT_SYMBOL(blkdev_get); | 1107 | EXPORT_SYMBOL(blkdev_get); |
1131 | 1108 | ||
@@ -1142,28 +1119,36 @@ static int blkdev_open(struct inode * inode, struct file * filp) | |||
1142 | */ | 1119 | */ |
1143 | filp->f_flags |= O_LARGEFILE; | 1120 | filp->f_flags |= O_LARGEFILE; |
1144 | 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 | |||
1145 | bdev = bd_acquire(inode); | 1129 | bdev = bd_acquire(inode); |
1146 | if (bdev == NULL) | 1130 | if (bdev == NULL) |
1147 | return -ENOMEM; | 1131 | return -ENOMEM; |
1148 | 1132 | ||
1149 | res = do_open(bdev, filp, 0); | 1133 | filp->f_mapping = bdev->bd_inode->i_mapping; |
1134 | |||
1135 | res = blkdev_get(bdev, filp->f_mode); | ||
1150 | if (res) | 1136 | if (res) |
1151 | return res; | 1137 | return res; |
1152 | 1138 | ||
1153 | if (!(filp->f_flags & O_EXCL) ) | 1139 | if (!(filp->f_mode & FMODE_EXCL)) |
1154 | return 0; | 1140 | return 0; |
1155 | 1141 | ||
1156 | if (!(res = bd_claim(bdev, filp))) | 1142 | if (!(res = bd_claim(bdev, filp))) |
1157 | return 0; | 1143 | return 0; |
1158 | 1144 | ||
1159 | blkdev_put(bdev); | 1145 | blkdev_put(bdev, filp->f_mode); |
1160 | return res; | 1146 | return res; |
1161 | } | 1147 | } |
1162 | 1148 | ||
1163 | static int __blkdev_put(struct block_device *bdev, int for_part) | 1149 | static int __blkdev_put(struct block_device *bdev, fmode_t mode, int for_part) |
1164 | { | 1150 | { |
1165 | int ret = 0; | 1151 | int ret = 0; |
1166 | struct inode *bd_inode = bdev->bd_inode; | ||
1167 | struct gendisk *disk = bdev->bd_disk; | 1152 | struct gendisk *disk = bdev->bd_disk; |
1168 | struct block_device *victim = NULL; | 1153 | struct block_device *victim = NULL; |
1169 | 1154 | ||
@@ -1178,7 +1163,7 @@ static int __blkdev_put(struct block_device *bdev, int for_part) | |||
1178 | } | 1163 | } |
1179 | if (bdev->bd_contains == bdev) { | 1164 | if (bdev->bd_contains == bdev) { |
1180 | if (disk->fops->release) | 1165 | if (disk->fops->release) |
1181 | ret = disk->fops->release(bd_inode, NULL); | 1166 | ret = disk->fops->release(disk, mode); |
1182 | } | 1167 | } |
1183 | if (!bdev->bd_openers) { | 1168 | if (!bdev->bd_openers) { |
1184 | struct module *owner = disk->fops->owner; | 1169 | struct module *owner = disk->fops->owner; |
@@ -1197,13 +1182,13 @@ static int __blkdev_put(struct block_device *bdev, int for_part) | |||
1197 | mutex_unlock(&bdev->bd_mutex); | 1182 | mutex_unlock(&bdev->bd_mutex); |
1198 | bdput(bdev); | 1183 | bdput(bdev); |
1199 | if (victim) | 1184 | if (victim) |
1200 | __blkdev_put(victim, 1); | 1185 | __blkdev_put(victim, mode, 1); |
1201 | return ret; | 1186 | return ret; |
1202 | } | 1187 | } |
1203 | 1188 | ||
1204 | int blkdev_put(struct block_device *bdev) | 1189 | int blkdev_put(struct block_device *bdev, fmode_t mode) |
1205 | { | 1190 | { |
1206 | return __blkdev_put(bdev, 0); | 1191 | return __blkdev_put(bdev, mode, 0); |
1207 | } | 1192 | } |
1208 | EXPORT_SYMBOL(blkdev_put); | 1193 | EXPORT_SYMBOL(blkdev_put); |
1209 | 1194 | ||
@@ -1212,12 +1197,16 @@ static int blkdev_close(struct inode * inode, struct file * filp) | |||
1212 | struct block_device *bdev = I_BDEV(filp->f_mapping->host); | 1197 | struct block_device *bdev = I_BDEV(filp->f_mapping->host); |
1213 | if (bdev->bd_holder == filp) | 1198 | if (bdev->bd_holder == filp) |
1214 | bd_release(bdev); | 1199 | bd_release(bdev); |
1215 | return blkdev_put(bdev); | 1200 | return blkdev_put(bdev, filp->f_mode); |
1216 | } | 1201 | } |
1217 | 1202 | ||
1218 | static long block_ioctl(struct file *file, unsigned cmd, unsigned long arg) | 1203 | static long block_ioctl(struct file *file, unsigned cmd, unsigned long arg) |
1219 | { | 1204 | { |
1220 | return blkdev_ioctl(file->f_mapping->host, file, cmd, arg); | 1205 | struct block_device *bdev = I_BDEV(file->f_mapping->host); |
1206 | fmode_t mode = file->f_mode; | ||
1207 | if (file->f_flags & O_NDELAY) | ||
1208 | mode |= FMODE_NDELAY_NOW; | ||
1209 | return blkdev_ioctl(bdev, mode, cmd, arg); | ||
1221 | } | 1210 | } |
1222 | 1211 | ||
1223 | static const struct address_space_operations def_blk_aops = { | 1212 | static const struct address_space_operations def_blk_aops = { |
@@ -1253,7 +1242,7 @@ int ioctl_by_bdev(struct block_device *bdev, unsigned cmd, unsigned long arg) | |||
1253 | int res; | 1242 | int res; |
1254 | mm_segment_t old_fs = get_fs(); | 1243 | mm_segment_t old_fs = get_fs(); |
1255 | set_fs(KERNEL_DS); | 1244 | set_fs(KERNEL_DS); |
1256 | res = blkdev_ioctl(bdev->bd_inode, NULL, cmd, arg); | 1245 | res = blkdev_ioctl(bdev, 0, cmd, arg); |
1257 | set_fs(old_fs); | 1246 | set_fs(old_fs); |
1258 | return res; | 1247 | return res; |
1259 | } | 1248 | } |
@@ -1303,32 +1292,29 @@ fail: | |||
1303 | EXPORT_SYMBOL(lookup_bdev); | 1292 | EXPORT_SYMBOL(lookup_bdev); |
1304 | 1293 | ||
1305 | /** | 1294 | /** |
1306 | * open_bdev_excl - open a block device by name and set it up for use | 1295 | * open_bdev_exclusive - open a block device by name and set it up for use |
1307 | * | 1296 | * |
1308 | * @path: special file representing the block device | 1297 | * @path: special file representing the block device |
1309 | * @flags: %MS_RDONLY for opening read-only | 1298 | * @mode: FMODE_... combination to pass be used |
1310 | * @holder: owner for exclusion | 1299 | * @holder: owner for exclusion |
1311 | * | 1300 | * |
1312 | * Open the blockdevice described by the special file at @path, claim it | 1301 | * Open the blockdevice described by the special file at @path, claim it |
1313 | * for the @holder. | 1302 | * for the @holder. |
1314 | */ | 1303 | */ |
1315 | struct block_device *open_bdev_excl(const char *path, int flags, void *holder) | 1304 | struct block_device *open_bdev_exclusive(const char *path, fmode_t mode, void *holder) |
1316 | { | 1305 | { |
1317 | struct block_device *bdev; | 1306 | struct block_device *bdev; |
1318 | mode_t mode = FMODE_READ; | ||
1319 | int error = 0; | 1307 | int error = 0; |
1320 | 1308 | ||
1321 | bdev = lookup_bdev(path); | 1309 | bdev = lookup_bdev(path); |
1322 | if (IS_ERR(bdev)) | 1310 | if (IS_ERR(bdev)) |
1323 | return bdev; | 1311 | return bdev; |
1324 | 1312 | ||
1325 | if (!(flags & MS_RDONLY)) | 1313 | error = blkdev_get(bdev, mode); |
1326 | mode |= FMODE_WRITE; | ||
1327 | error = blkdev_get(bdev, mode, 0); | ||
1328 | if (error) | 1314 | if (error) |
1329 | return ERR_PTR(error); | 1315 | return ERR_PTR(error); |
1330 | error = -EACCES; | 1316 | error = -EACCES; |
1331 | if (!(flags & MS_RDONLY) && bdev_read_only(bdev)) | 1317 | if ((mode & FMODE_WRITE) && bdev_read_only(bdev)) |
1332 | goto blkdev_put; | 1318 | goto blkdev_put; |
1333 | error = bd_claim(bdev, holder); | 1319 | error = bd_claim(bdev, holder); |
1334 | if (error) | 1320 | if (error) |
@@ -1337,26 +1323,27 @@ struct block_device *open_bdev_excl(const char *path, int flags, void *holder) | |||
1337 | return bdev; | 1323 | return bdev; |
1338 | 1324 | ||
1339 | blkdev_put: | 1325 | blkdev_put: |
1340 | blkdev_put(bdev); | 1326 | blkdev_put(bdev, mode); |
1341 | return ERR_PTR(error); | 1327 | return ERR_PTR(error); |
1342 | } | 1328 | } |
1343 | 1329 | ||
1344 | EXPORT_SYMBOL(open_bdev_excl); | 1330 | EXPORT_SYMBOL(open_bdev_exclusive); |
1345 | 1331 | ||
1346 | /** | 1332 | /** |
1347 | * close_bdev_excl - release a blockdevice openen by open_bdev_excl() | 1333 | * close_bdev_exclusive - close a blockdevice opened by open_bdev_exclusive() |
1348 | * | 1334 | * |
1349 | * @bdev: blockdevice to close | 1335 | * @bdev: blockdevice to close |
1336 | * @mode: mode, must match that used to open. | ||
1350 | * | 1337 | * |
1351 | * This is the counterpart to open_bdev_excl(). | 1338 | * This is the counterpart to open_bdev_exclusive(). |
1352 | */ | 1339 | */ |
1353 | void close_bdev_excl(struct block_device *bdev) | 1340 | void close_bdev_exclusive(struct block_device *bdev, fmode_t mode) |
1354 | { | 1341 | { |
1355 | bd_release(bdev); | 1342 | bd_release(bdev); |
1356 | blkdev_put(bdev); | 1343 | blkdev_put(bdev, mode); |
1357 | } | 1344 | } |
1358 | 1345 | ||
1359 | EXPORT_SYMBOL(close_bdev_excl); | 1346 | EXPORT_SYMBOL(close_bdev_exclusive); |
1360 | 1347 | ||
1361 | int __invalidate_device(struct block_device *bdev) | 1348 | int __invalidate_device(struct block_device *bdev) |
1362 | { | 1349 | { |