aboutsummaryrefslogtreecommitdiffstats
path: root/fs/block_dev.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/block_dev.c')
-rw-r--r--fs/block_dev.c65
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}
976EXPORT_SYMBOL(bd_set_size); 975EXPORT_SYMBOL(bd_set_size);
977 976
978static int __blkdev_get(struct block_device *bdev, fmode_t mode, unsigned flags,
979 int for_part);
980static int __blkdev_put(struct block_device *bdev, fmode_t mode, int for_part); 977static 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
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".
@@ -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
1114static int __blkdev_get(struct block_device *bdev, fmode_t mode, unsigned flags, 1103int 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
1133int 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}
1137EXPORT_SYMBOL(blkdev_get); 1107EXPORT_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;