aboutsummaryrefslogtreecommitdiffstats
path: root/fs/block_dev.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-10-23 13:23:07 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-10-23 13:23:07 -0400
commit22484856402bfa1ff3defe47f6029ab0418240d9 (patch)
tree140c67bf59674da350a7b51765d6ff7eb101b597 /fs/block_dev.c
parent5ed487bc2c44ca4e9668ef9cb54c830e2a9fac47 (diff)
parent56b26add02b4bdea81d5e0ebda60db1fe3311ad4 (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.c111
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 */
843struct block_device *open_by_devnum(dev_t dev, unsigned mode) 843struct 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}
976EXPORT_SYMBOL(bd_set_size); 975EXPORT_SYMBOL(bd_set_size);
977 976
978static int __blkdev_get(struct block_device *bdev, mode_t mode, unsigned flags, 977static int __blkdev_put(struct block_device *bdev, fmode_t mode, int for_part);
979 int for_part);
980static 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
989static int do_open(struct block_device *bdev, struct file *file, int for_part) 986static 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
1107static int __blkdev_get(struct block_device *bdev, mode_t mode, unsigned flags, 1103int 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
1126int blkdev_get(struct block_device *bdev, mode_t mode, unsigned flags)
1127{
1128 return __blkdev_get(bdev, mode, flags, 0);
1129} 1106}
1130EXPORT_SYMBOL(blkdev_get); 1107EXPORT_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
1163static int __blkdev_put(struct block_device *bdev, int for_part) 1149static 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
1204int blkdev_put(struct block_device *bdev) 1189int 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}
1208EXPORT_SYMBOL(blkdev_put); 1193EXPORT_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
1218static long block_ioctl(struct file *file, unsigned cmd, unsigned long arg) 1203static 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
1223static const struct address_space_operations def_blk_aops = { 1212static 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:
1303EXPORT_SYMBOL(lookup_bdev); 1292EXPORT_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 */
1315struct block_device *open_bdev_excl(const char *path, int flags, void *holder) 1304struct 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
1339blkdev_put: 1325blkdev_put:
1340 blkdev_put(bdev); 1326 blkdev_put(bdev, mode);
1341 return ERR_PTR(error); 1327 return ERR_PTR(error);
1342} 1328}
1343 1329
1344EXPORT_SYMBOL(open_bdev_excl); 1330EXPORT_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 */
1353void close_bdev_excl(struct block_device *bdev) 1340void 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
1359EXPORT_SYMBOL(close_bdev_excl); 1346EXPORT_SYMBOL(close_bdev_exclusive);
1360 1347
1361int __invalidate_device(struct block_device *bdev) 1348int __invalidate_device(struct block_device *bdev)
1362{ 1349{