aboutsummaryrefslogtreecommitdiffstats
path: root/fs
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
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')
-rw-r--r--fs/block_dev.c111
-rw-r--r--fs/ext2/xip.c1
-rw-r--r--fs/ext3/super.c4
-rw-r--r--fs/ext4/super.c4
-rw-r--r--fs/fifo.c6
-rw-r--r--fs/file_table.c4
-rw-r--r--fs/hostfs/hostfs_kern.c5
-rw-r--r--fs/jfs/jfs_logmgr.c4
-rw-r--r--fs/locks.c3
-rw-r--r--fs/ocfs2/cluster/heartbeat.c6
-rw-r--r--fs/open.c2
-rw-r--r--fs/partitions/check.c4
-rw-r--r--fs/proc/base.c4
-rw-r--r--fs/reiserfs/journal.c11
-rw-r--r--fs/super.c14
-rw-r--r--fs/xfs/linux-2.6/xfs_super.c4
16 files changed, 93 insertions, 94 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{
diff --git a/fs/ext2/xip.c b/fs/ext2/xip.c
index 4fb94c20041b..b72b85884223 100644
--- a/fs/ext2/xip.c
+++ b/fs/ext2/xip.c
@@ -11,6 +11,7 @@
11#include <linux/buffer_head.h> 11#include <linux/buffer_head.h>
12#include <linux/ext2_fs_sb.h> 12#include <linux/ext2_fs_sb.h>
13#include <linux/ext2_fs.h> 13#include <linux/ext2_fs.h>
14#include <linux/blkdev.h>
14#include "ext2.h" 15#include "ext2.h"
15#include "xip.h" 16#include "xip.h"
16 17
diff --git a/fs/ext3/super.c b/fs/ext3/super.c
index 34b6fca765d7..8147dd44cede 100644
--- a/fs/ext3/super.c
+++ b/fs/ext3/super.c
@@ -347,7 +347,7 @@ fail:
347static int ext3_blkdev_put(struct block_device *bdev) 347static int ext3_blkdev_put(struct block_device *bdev)
348{ 348{
349 bd_release(bdev); 349 bd_release(bdev);
350 return blkdev_put(bdev); 350 return blkdev_put(bdev, FMODE_READ|FMODE_WRITE);
351} 351}
352 352
353static int ext3_blkdev_remove(struct ext3_sb_info *sbi) 353static int ext3_blkdev_remove(struct ext3_sb_info *sbi)
@@ -2067,7 +2067,7 @@ static journal_t *ext3_get_dev_journal(struct super_block *sb,
2067 if (bd_claim(bdev, sb)) { 2067 if (bd_claim(bdev, sb)) {
2068 printk(KERN_ERR 2068 printk(KERN_ERR
2069 "EXT3: failed to claim external journal device.\n"); 2069 "EXT3: failed to claim external journal device.\n");
2070 blkdev_put(bdev); 2070 blkdev_put(bdev, FMODE_READ|FMODE_WRITE);
2071 return NULL; 2071 return NULL;
2072 } 2072 }
2073 2073
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index ae35f176b697..bdddea14e782 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -399,7 +399,7 @@ fail:
399static int ext4_blkdev_put(struct block_device *bdev) 399static int ext4_blkdev_put(struct block_device *bdev)
400{ 400{
401 bd_release(bdev); 401 bd_release(bdev);
402 return blkdev_put(bdev); 402 return blkdev_put(bdev, FMODE_READ|FMODE_WRITE);
403} 403}
404 404
405static int ext4_blkdev_remove(struct ext4_sb_info *sbi) 405static int ext4_blkdev_remove(struct ext4_sb_info *sbi)
@@ -2553,7 +2553,7 @@ static journal_t *ext4_get_dev_journal(struct super_block *sb,
2553 if (bd_claim(bdev, sb)) { 2553 if (bd_claim(bdev, sb)) {
2554 printk(KERN_ERR 2554 printk(KERN_ERR
2555 "EXT4: failed to claim external journal device.\n"); 2555 "EXT4: failed to claim external journal device.\n");
2556 blkdev_put(bdev); 2556 blkdev_put(bdev, FMODE_READ|FMODE_WRITE);
2557 return NULL; 2557 return NULL;
2558 } 2558 }
2559 2559
diff --git a/fs/fifo.c b/fs/fifo.c
index 987bf9411495..f8f97b8b6d44 100644
--- a/fs/fifo.c
+++ b/fs/fifo.c
@@ -51,7 +51,7 @@ static int fifo_open(struct inode *inode, struct file *filp)
51 filp->f_mode &= (FMODE_READ | FMODE_WRITE); 51 filp->f_mode &= (FMODE_READ | FMODE_WRITE);
52 52
53 switch (filp->f_mode) { 53 switch (filp->f_mode) {
54 case 1: 54 case FMODE_READ:
55 /* 55 /*
56 * O_RDONLY 56 * O_RDONLY
57 * POSIX.1 says that O_NONBLOCK means return with the FIFO 57 * POSIX.1 says that O_NONBLOCK means return with the FIFO
@@ -76,7 +76,7 @@ static int fifo_open(struct inode *inode, struct file *filp)
76 } 76 }
77 break; 77 break;
78 78
79 case 2: 79 case FMODE_WRITE:
80 /* 80 /*
81 * O_WRONLY 81 * O_WRONLY
82 * POSIX.1 says that O_NONBLOCK means return -1 with 82 * POSIX.1 says that O_NONBLOCK means return -1 with
@@ -98,7 +98,7 @@ static int fifo_open(struct inode *inode, struct file *filp)
98 } 98 }
99 break; 99 break;
100 100
101 case 3: 101 case FMODE_READ | FMODE_WRITE:
102 /* 102 /*
103 * O_RDWR 103 * O_RDWR
104 * POSIX.1 leaves this case "undefined" when O_NONBLOCK is set. 104 * POSIX.1 leaves this case "undefined" when O_NONBLOCK is set.
diff --git a/fs/file_table.c b/fs/file_table.c
index f45a4493f9e7..efc06faede6c 100644
--- a/fs/file_table.c
+++ b/fs/file_table.c
@@ -161,7 +161,7 @@ EXPORT_SYMBOL(get_empty_filp);
161 * code should be moved into this function. 161 * code should be moved into this function.
162 */ 162 */
163struct file *alloc_file(struct vfsmount *mnt, struct dentry *dentry, 163struct file *alloc_file(struct vfsmount *mnt, struct dentry *dentry,
164 mode_t mode, const struct file_operations *fop) 164 fmode_t mode, const struct file_operations *fop)
165{ 165{
166 struct file *file; 166 struct file *file;
167 struct path; 167 struct path;
@@ -193,7 +193,7 @@ EXPORT_SYMBOL(alloc_file);
193 * of this should be moving to alloc_file(). 193 * of this should be moving to alloc_file().
194 */ 194 */
195int init_file(struct file *file, struct vfsmount *mnt, struct dentry *dentry, 195int init_file(struct file *file, struct vfsmount *mnt, struct dentry *dentry,
196 mode_t mode, const struct file_operations *fop) 196 fmode_t mode, const struct file_operations *fop)
197{ 197{
198 int error = 0; 198 int error = 0;
199 file->f_path.dentry = dentry; 199 file->f_path.dentry = dentry;
diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c
index d6ecabf4d231..7f34f4385de0 100644
--- a/fs/hostfs/hostfs_kern.c
+++ b/fs/hostfs/hostfs_kern.c
@@ -20,7 +20,7 @@
20struct hostfs_inode_info { 20struct hostfs_inode_info {
21 char *host_filename; 21 char *host_filename;
22 int fd; 22 int fd;
23 int mode; 23 fmode_t mode;
24 struct inode vfs_inode; 24 struct inode vfs_inode;
25}; 25};
26 26
@@ -373,7 +373,8 @@ int hostfs_readdir(struct file *file, void *ent, filldir_t filldir)
373int hostfs_file_open(struct inode *ino, struct file *file) 373int hostfs_file_open(struct inode *ino, struct file *file)
374{ 374{
375 char *name; 375 char *name;
376 int mode = 0, r = 0, w = 0, fd; 376 fmode_t mode = 0;
377 int r = 0, w = 0, fd;
377 378
378 mode = file->f_mode & (FMODE_READ | FMODE_WRITE); 379 mode = file->f_mode & (FMODE_READ | FMODE_WRITE);
379 if ((mode & HOSTFS_I(ino)->mode) == mode) 380 if ((mode & HOSTFS_I(ino)->mode) == mode)
diff --git a/fs/jfs/jfs_logmgr.c b/fs/jfs/jfs_logmgr.c
index cd2ec2988b59..335c4de6552d 100644
--- a/fs/jfs/jfs_logmgr.c
+++ b/fs/jfs/jfs_logmgr.c
@@ -1168,7 +1168,7 @@ journal_found:
1168 bd_release(bdev); 1168 bd_release(bdev);
1169 1169
1170 close: /* close external log device */ 1170 close: /* close external log device */
1171 blkdev_put(bdev); 1171 blkdev_put(bdev, FMODE_READ|FMODE_WRITE);
1172 1172
1173 free: /* free log descriptor */ 1173 free: /* free log descriptor */
1174 mutex_unlock(&jfs_log_mutex); 1174 mutex_unlock(&jfs_log_mutex);
@@ -1514,7 +1514,7 @@ int lmLogClose(struct super_block *sb)
1514 rc = lmLogShutdown(log); 1514 rc = lmLogShutdown(log);
1515 1515
1516 bd_release(bdev); 1516 bd_release(bdev);
1517 blkdev_put(bdev); 1517 blkdev_put(bdev, FMODE_READ|FMODE_WRITE);
1518 1518
1519 kfree(log); 1519 kfree(log);
1520 1520
diff --git a/fs/locks.c b/fs/locks.c
index 5eb259e3cd38..20457486d6b2 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -1580,7 +1580,8 @@ asmlinkage long sys_flock(unsigned int fd, unsigned int cmd)
1580 cmd &= ~LOCK_NB; 1580 cmd &= ~LOCK_NB;
1581 unlock = (cmd == LOCK_UN); 1581 unlock = (cmd == LOCK_UN);
1582 1582
1583 if (!unlock && !(cmd & LOCK_MAND) && !(filp->f_mode & 3)) 1583 if (!unlock && !(cmd & LOCK_MAND) &&
1584 !(filp->f_mode & (FMODE_READ|FMODE_WRITE)))
1584 goto out_putf; 1585 goto out_putf;
1585 1586
1586 error = flock_make_lock(filp, &lock, cmd); 1587 error = flock_make_lock(filp, &lock, cmd);
diff --git a/fs/ocfs2/cluster/heartbeat.c b/fs/ocfs2/cluster/heartbeat.c
index 7dce1612553e..6ebaa58e2c03 100644
--- a/fs/ocfs2/cluster/heartbeat.c
+++ b/fs/ocfs2/cluster/heartbeat.c
@@ -976,7 +976,7 @@ static void o2hb_region_release(struct config_item *item)
976 } 976 }
977 977
978 if (reg->hr_bdev) 978 if (reg->hr_bdev)
979 blkdev_put(reg->hr_bdev); 979 blkdev_put(reg->hr_bdev, FMODE_READ|FMODE_WRITE);
980 980
981 if (reg->hr_slots) 981 if (reg->hr_slots)
982 kfree(reg->hr_slots); 982 kfree(reg->hr_slots);
@@ -1268,7 +1268,7 @@ static ssize_t o2hb_region_dev_write(struct o2hb_region *reg,
1268 goto out; 1268 goto out;
1269 1269
1270 reg->hr_bdev = I_BDEV(filp->f_mapping->host); 1270 reg->hr_bdev = I_BDEV(filp->f_mapping->host);
1271 ret = blkdev_get(reg->hr_bdev, FMODE_WRITE | FMODE_READ, 0); 1271 ret = blkdev_get(reg->hr_bdev, FMODE_WRITE | FMODE_READ);
1272 if (ret) { 1272 if (ret) {
1273 reg->hr_bdev = NULL; 1273 reg->hr_bdev = NULL;
1274 goto out; 1274 goto out;
@@ -1358,7 +1358,7 @@ out:
1358 iput(inode); 1358 iput(inode);
1359 if (ret < 0) { 1359 if (ret < 0) {
1360 if (reg->hr_bdev) { 1360 if (reg->hr_bdev) {
1361 blkdev_put(reg->hr_bdev); 1361 blkdev_put(reg->hr_bdev, FMODE_READ|FMODE_WRITE);
1362 reg->hr_bdev = NULL; 1362 reg->hr_bdev = NULL;
1363 } 1363 }
1364 } 1364 }
diff --git a/fs/open.c b/fs/open.c
index 5596049863bf..83cdb9dee0c1 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -798,7 +798,7 @@ static struct file *__dentry_open(struct dentry *dentry, struct vfsmount *mnt,
798 int error; 798 int error;
799 799
800 f->f_flags = flags; 800 f->f_flags = flags;
801 f->f_mode = ((flags+1) & O_ACCMODE) | FMODE_LSEEK | 801 f->f_mode = (__force fmode_t)((flags+1) & O_ACCMODE) | FMODE_LSEEK |
802 FMODE_PREAD | FMODE_PWRITE; 802 FMODE_PREAD | FMODE_PWRITE;
803 inode = dentry->d_inode; 803 inode = dentry->d_inode;
804 if (f->f_mode & FMODE_WRITE) { 804 if (f->f_mode & FMODE_WRITE) {
diff --git a/fs/partitions/check.c b/fs/partitions/check.c
index cfb0c80690aa..633f7a0ebb2c 100644
--- a/fs/partitions/check.c
+++ b/fs/partitions/check.c
@@ -485,10 +485,10 @@ void register_disk(struct gendisk *disk)
485 goto exit; 485 goto exit;
486 486
487 bdev->bd_invalidated = 1; 487 bdev->bd_invalidated = 1;
488 err = blkdev_get(bdev, FMODE_READ, 0); 488 err = blkdev_get(bdev, FMODE_READ);
489 if (err < 0) 489 if (err < 0)
490 goto exit; 490 goto exit;
491 blkdev_put(bdev); 491 blkdev_put(bdev, FMODE_READ);
492 492
493exit: 493exit:
494 /* announce disk after possible partitions are created */ 494 /* announce disk after possible partitions are created */
diff --git a/fs/proc/base.c b/fs/proc/base.c
index b5918ae8ca79..486cf3fe7139 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -1712,9 +1712,9 @@ static struct dentry *proc_fd_instantiate(struct inode *dir,
1712 file = fcheck_files(files, fd); 1712 file = fcheck_files(files, fd);
1713 if (!file) 1713 if (!file)
1714 goto out_unlock; 1714 goto out_unlock;
1715 if (file->f_mode & 1) 1715 if (file->f_mode & FMODE_READ)
1716 inode->i_mode |= S_IRUSR | S_IXUSR; 1716 inode->i_mode |= S_IRUSR | S_IXUSR;
1717 if (file->f_mode & 2) 1717 if (file->f_mode & FMODE_WRITE)
1718 inode->i_mode |= S_IWUSR | S_IXUSR; 1718 inode->i_mode |= S_IWUSR | S_IXUSR;
1719 spin_unlock(&files->file_lock); 1719 spin_unlock(&files->file_lock);
1720 put_files_struct(files); 1720 put_files_struct(files);
diff --git a/fs/reiserfs/journal.c b/fs/reiserfs/journal.c
index c21df71943a6..9643c3bbeb3b 100644
--- a/fs/reiserfs/journal.c
+++ b/fs/reiserfs/journal.c
@@ -2575,7 +2575,7 @@ static int release_journal_dev(struct super_block *super,
2575 if (journal->j_dev_bd != NULL) { 2575 if (journal->j_dev_bd != NULL) {
2576 if (journal->j_dev_bd->bd_dev != super->s_dev) 2576 if (journal->j_dev_bd->bd_dev != super->s_dev)
2577 bd_release(journal->j_dev_bd); 2577 bd_release(journal->j_dev_bd);
2578 result = blkdev_put(journal->j_dev_bd); 2578 result = blkdev_put(journal->j_dev_bd, journal->j_dev_mode);
2579 journal->j_dev_bd = NULL; 2579 journal->j_dev_bd = NULL;
2580 } 2580 }
2581 2581
@@ -2593,7 +2593,7 @@ static int journal_init_dev(struct super_block *super,
2593{ 2593{
2594 int result; 2594 int result;
2595 dev_t jdev; 2595 dev_t jdev;
2596 int blkdev_mode = FMODE_READ | FMODE_WRITE; 2596 fmode_t blkdev_mode = FMODE_READ | FMODE_WRITE;
2597 char b[BDEVNAME_SIZE]; 2597 char b[BDEVNAME_SIZE];
2598 2598
2599 result = 0; 2599 result = 0;
@@ -2608,6 +2608,7 @@ static int journal_init_dev(struct super_block *super,
2608 /* there is no "jdev" option and journal is on separate device */ 2608 /* there is no "jdev" option and journal is on separate device */
2609 if ((!jdev_name || !jdev_name[0])) { 2609 if ((!jdev_name || !jdev_name[0])) {
2610 journal->j_dev_bd = open_by_devnum(jdev, blkdev_mode); 2610 journal->j_dev_bd = open_by_devnum(jdev, blkdev_mode);
2611 journal->j_dev_mode = blkdev_mode;
2611 if (IS_ERR(journal->j_dev_bd)) { 2612 if (IS_ERR(journal->j_dev_bd)) {
2612 result = PTR_ERR(journal->j_dev_bd); 2613 result = PTR_ERR(journal->j_dev_bd);
2613 journal->j_dev_bd = NULL; 2614 journal->j_dev_bd = NULL;
@@ -2618,7 +2619,7 @@ static int journal_init_dev(struct super_block *super,
2618 } else if (jdev != super->s_dev) { 2619 } else if (jdev != super->s_dev) {
2619 result = bd_claim(journal->j_dev_bd, journal); 2620 result = bd_claim(journal->j_dev_bd, journal);
2620 if (result) { 2621 if (result) {
2621 blkdev_put(journal->j_dev_bd); 2622 blkdev_put(journal->j_dev_bd, blkdev_mode);
2622 return result; 2623 return result;
2623 } 2624 }
2624 2625
@@ -2628,7 +2629,9 @@ static int journal_init_dev(struct super_block *super,
2628 return 0; 2629 return 0;
2629 } 2630 }
2630 2631
2631 journal->j_dev_bd = open_bdev_excl(jdev_name, 0, journal); 2632 journal->j_dev_mode = blkdev_mode;
2633 journal->j_dev_bd = open_bdev_exclusive(jdev_name,
2634 blkdev_mode, journal);
2632 if (IS_ERR(journal->j_dev_bd)) { 2635 if (IS_ERR(journal->j_dev_bd)) {
2633 result = PTR_ERR(journal->j_dev_bd); 2636 result = PTR_ERR(journal->j_dev_bd);
2634 journal->j_dev_bd = NULL; 2637 journal->j_dev_bd = NULL;
diff --git a/fs/super.c b/fs/super.c
index f31ef824d069..400a7608f15e 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -755,9 +755,13 @@ int get_sb_bdev(struct file_system_type *fs_type,
755{ 755{
756 struct block_device *bdev; 756 struct block_device *bdev;
757 struct super_block *s; 757 struct super_block *s;
758 fmode_t mode = FMODE_READ;
758 int error = 0; 759 int error = 0;
759 760
760 bdev = open_bdev_excl(dev_name, flags, fs_type); 761 if (!(flags & MS_RDONLY))
762 mode |= FMODE_WRITE;
763
764 bdev = open_bdev_exclusive(dev_name, mode, fs_type);
761 if (IS_ERR(bdev)) 765 if (IS_ERR(bdev))
762 return PTR_ERR(bdev); 766 return PTR_ERR(bdev);
763 767
@@ -780,11 +784,12 @@ int get_sb_bdev(struct file_system_type *fs_type,
780 goto error_bdev; 784 goto error_bdev;
781 } 785 }
782 786
783 close_bdev_excl(bdev); 787 close_bdev_exclusive(bdev, mode);
784 } else { 788 } else {
785 char b[BDEVNAME_SIZE]; 789 char b[BDEVNAME_SIZE];
786 790
787 s->s_flags = flags; 791 s->s_flags = flags;
792 s->s_mode = mode;
788 strlcpy(s->s_id, bdevname(bdev, b), sizeof(s->s_id)); 793 strlcpy(s->s_id, bdevname(bdev, b), sizeof(s->s_id));
789 sb_set_blocksize(s, block_size(bdev)); 794 sb_set_blocksize(s, block_size(bdev));
790 error = fill_super(s, data, flags & MS_SILENT ? 1 : 0); 795 error = fill_super(s, data, flags & MS_SILENT ? 1 : 0);
@@ -802,7 +807,7 @@ int get_sb_bdev(struct file_system_type *fs_type,
802error_s: 807error_s:
803 error = PTR_ERR(s); 808 error = PTR_ERR(s);
804error_bdev: 809error_bdev:
805 close_bdev_excl(bdev); 810 close_bdev_exclusive(bdev, mode);
806error: 811error:
807 return error; 812 return error;
808} 813}
@@ -812,10 +817,11 @@ EXPORT_SYMBOL(get_sb_bdev);
812void kill_block_super(struct super_block *sb) 817void kill_block_super(struct super_block *sb)
813{ 818{
814 struct block_device *bdev = sb->s_bdev; 819 struct block_device *bdev = sb->s_bdev;
820 fmode_t mode = sb->s_mode;
815 821
816 generic_shutdown_super(sb); 822 generic_shutdown_super(sb);
817 sync_blockdev(bdev); 823 sync_blockdev(bdev);
818 close_bdev_excl(bdev); 824 close_bdev_exclusive(bdev, mode);
819} 825}
820 826
821EXPORT_SYMBOL(kill_block_super); 827EXPORT_SYMBOL(kill_block_super);
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c
index e39013619b26..37ebe36056eb 100644
--- a/fs/xfs/linux-2.6/xfs_super.c
+++ b/fs/xfs/linux-2.6/xfs_super.c
@@ -589,7 +589,7 @@ xfs_blkdev_get(
589{ 589{
590 int error = 0; 590 int error = 0;
591 591
592 *bdevp = open_bdev_excl(name, 0, mp); 592 *bdevp = open_bdev_exclusive(name, FMODE_READ|FMODE_WRITE, mp);
593 if (IS_ERR(*bdevp)) { 593 if (IS_ERR(*bdevp)) {
594 error = PTR_ERR(*bdevp); 594 error = PTR_ERR(*bdevp);
595 printk("XFS: Invalid device [%s], error=%d\n", name, error); 595 printk("XFS: Invalid device [%s], error=%d\n", name, error);
@@ -603,7 +603,7 @@ xfs_blkdev_put(
603 struct block_device *bdev) 603 struct block_device *bdev)
604{ 604{
605 if (bdev) 605 if (bdev)
606 close_bdev_excl(bdev); 606 close_bdev_exclusive(bdev, FMODE_READ|FMODE_WRITE);
607} 607}
608 608
609/* 609/*