diff options
Diffstat (limited to 'fs/block_dev.c')
-rw-r--r-- | fs/block_dev.c | 139 |
1 files changed, 93 insertions, 46 deletions
diff --git a/fs/block_dev.c b/fs/block_dev.c index 606a5259f87f..c1c1b8c3fb99 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c | |||
@@ -854,24 +854,6 @@ static inline void bd_unlink_disk_holder(struct block_device *bdev) | |||
854 | { } | 854 | { } |
855 | #endif | 855 | #endif |
856 | 856 | ||
857 | /* | ||
858 | * Tries to open block device by device number. Use it ONLY if you | ||
859 | * really do not have anything better - i.e. when you are behind a | ||
860 | * truly sucky interface and all you are given is a device number. _Never_ | ||
861 | * to be used for internal purposes. If you ever need it - reconsider | ||
862 | * your API. | ||
863 | */ | ||
864 | struct block_device *open_by_devnum(dev_t dev, fmode_t mode, void *holder) | ||
865 | { | ||
866 | struct block_device *bdev = bdget(dev); | ||
867 | int err = -ENOMEM; | ||
868 | if (bdev) | ||
869 | err = blkdev_get(bdev, mode, holder); | ||
870 | return err ? ERR_PTR(err) : bdev; | ||
871 | } | ||
872 | |||
873 | EXPORT_SYMBOL(open_by_devnum); | ||
874 | |||
875 | /** | 857 | /** |
876 | * flush_disk - invalidates all buffer-cache entries on a disk | 858 | * flush_disk - invalidates all buffer-cache entries on a disk |
877 | * | 859 | * |
@@ -1132,6 +1114,25 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part) | |||
1132 | return ret; | 1114 | return ret; |
1133 | } | 1115 | } |
1134 | 1116 | ||
1117 | /** | ||
1118 | * blkdev_get - open a block device | ||
1119 | * @bdev: block_device to open | ||
1120 | * @mode: FMODE_* mask | ||
1121 | * @holder: exclusive holder identifier | ||
1122 | * | ||
1123 | * Open @bdev with @mode. If @mode includes %FMODE_EXCL, @bdev is | ||
1124 | * open with exclusive access. Specifying %FMODE_EXCL with %NULL | ||
1125 | * @holder is invalid. Exclusive opens may nest for the same @holder. | ||
1126 | * | ||
1127 | * On success, the reference count of @bdev is unchanged. On failure, | ||
1128 | * @bdev is put. | ||
1129 | * | ||
1130 | * CONTEXT: | ||
1131 | * Might sleep. | ||
1132 | * | ||
1133 | * RETURNS: | ||
1134 | * 0 on success, -errno on failure. | ||
1135 | */ | ||
1135 | int blkdev_get(struct block_device *bdev, fmode_t mode, void *holder) | 1136 | int blkdev_get(struct block_device *bdev, fmode_t mode, void *holder) |
1136 | { | 1137 | { |
1137 | struct block_device *whole = NULL; | 1138 | struct block_device *whole = NULL; |
@@ -1186,6 +1187,80 @@ int blkdev_get(struct block_device *bdev, fmode_t mode, void *holder) | |||
1186 | } | 1187 | } |
1187 | EXPORT_SYMBOL(blkdev_get); | 1188 | EXPORT_SYMBOL(blkdev_get); |
1188 | 1189 | ||
1190 | /** | ||
1191 | * blkdev_get_by_path - open a block device by name | ||
1192 | * @path: path to the block device to open | ||
1193 | * @mode: FMODE_* mask | ||
1194 | * @holder: exclusive holder identifier | ||
1195 | * | ||
1196 | * Open the blockdevice described by the device file at @path. @mode | ||
1197 | * and @holder are identical to blkdev_get(). | ||
1198 | * | ||
1199 | * On success, the returned block_device has reference count of one. | ||
1200 | * | ||
1201 | * CONTEXT: | ||
1202 | * Might sleep. | ||
1203 | * | ||
1204 | * RETURNS: | ||
1205 | * Pointer to block_device on success, ERR_PTR(-errno) on failure. | ||
1206 | */ | ||
1207 | struct block_device *blkdev_get_by_path(const char *path, fmode_t mode, | ||
1208 | void *holder) | ||
1209 | { | ||
1210 | struct block_device *bdev; | ||
1211 | int err; | ||
1212 | |||
1213 | bdev = lookup_bdev(path); | ||
1214 | if (IS_ERR(bdev)) | ||
1215 | return bdev; | ||
1216 | |||
1217 | err = blkdev_get(bdev, mode, holder); | ||
1218 | if (err) | ||
1219 | return ERR_PTR(err); | ||
1220 | |||
1221 | return bdev; | ||
1222 | } | ||
1223 | EXPORT_SYMBOL(blkdev_get_by_path); | ||
1224 | |||
1225 | /** | ||
1226 | * blkdev_get_by_dev - open a block device by device number | ||
1227 | * @dev: device number of block device to open | ||
1228 | * @mode: FMODE_* mask | ||
1229 | * @holder: exclusive holder identifier | ||
1230 | * | ||
1231 | * Open the blockdevice described by device number @dev. @mode and | ||
1232 | * @holder are identical to blkdev_get(). | ||
1233 | * | ||
1234 | * Use it ONLY if you really do not have anything better - i.e. when | ||
1235 | * you are behind a truly sucky interface and all you are given is a | ||
1236 | * device number. _Never_ to be used for internal purposes. If you | ||
1237 | * ever need it - reconsider your API. | ||
1238 | * | ||
1239 | * On success, the returned block_device has reference count of one. | ||
1240 | * | ||
1241 | * CONTEXT: | ||
1242 | * Might sleep. | ||
1243 | * | ||
1244 | * RETURNS: | ||
1245 | * Pointer to block_device on success, ERR_PTR(-errno) on failure. | ||
1246 | */ | ||
1247 | struct block_device *blkdev_get_by_dev(dev_t dev, fmode_t mode, void *holder) | ||
1248 | { | ||
1249 | struct block_device *bdev; | ||
1250 | int err; | ||
1251 | |||
1252 | bdev = bdget(dev); | ||
1253 | if (!bdev) | ||
1254 | return ERR_PTR(-ENOMEM); | ||
1255 | |||
1256 | err = blkdev_get(bdev, mode, holder); | ||
1257 | if (err) | ||
1258 | return ERR_PTR(err); | ||
1259 | |||
1260 | return bdev; | ||
1261 | } | ||
1262 | EXPORT_SYMBOL(blkdev_get_by_dev); | ||
1263 | |||
1189 | static int blkdev_open(struct inode * inode, struct file * filp) | 1264 | static int blkdev_open(struct inode * inode, struct file * filp) |
1190 | { | 1265 | { |
1191 | struct block_device *bdev; | 1266 | struct block_device *bdev; |
@@ -1436,34 +1511,6 @@ fail: | |||
1436 | } | 1511 | } |
1437 | EXPORT_SYMBOL(lookup_bdev); | 1512 | EXPORT_SYMBOL(lookup_bdev); |
1438 | 1513 | ||
1439 | /** | ||
1440 | * open_bdev_exclusive - open a block device by name and set it up for use | ||
1441 | * | ||
1442 | * @path: special file representing the block device | ||
1443 | * @mode: FMODE_... combination to pass be used | ||
1444 | * @holder: owner for exclusion | ||
1445 | * | ||
1446 | * Open the blockdevice described by the special file at @path, claim it | ||
1447 | * for the @holder. | ||
1448 | */ | ||
1449 | struct block_device *open_bdev_exclusive(const char *path, fmode_t mode, void *holder) | ||
1450 | { | ||
1451 | struct block_device *bdev; | ||
1452 | int error; | ||
1453 | |||
1454 | bdev = lookup_bdev(path); | ||
1455 | if (IS_ERR(bdev)) | ||
1456 | return bdev; | ||
1457 | |||
1458 | error = blkdev_get(bdev, mode | FMODE_EXCL, holder); | ||
1459 | if (error) | ||
1460 | return ERR_PTR(error); | ||
1461 | |||
1462 | return bdev; | ||
1463 | } | ||
1464 | |||
1465 | EXPORT_SYMBOL(open_bdev_exclusive); | ||
1466 | |||
1467 | int __invalidate_device(struct block_device *bdev) | 1514 | int __invalidate_device(struct block_device *bdev) |
1468 | { | 1515 | { |
1469 | struct super_block *sb = get_super(bdev); | 1516 | struct super_block *sb = get_super(bdev); |