aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/block_dev.c149
-rw-r--r--fs/btrfs/volumes.c14
-rw-r--r--fs/ext3/super.c12
-rw-r--r--fs/ext4/super.c12
-rw-r--r--fs/gfs2/ops_fstype.c4
-rw-r--r--fs/jfs/jfs_logmgr.c17
-rw-r--r--fs/logfs/dev_bdev.c4
-rw-r--r--fs/nilfs2/super.c4
-rw-r--r--fs/ocfs2/cluster/heartbeat.c2
-rw-r--r--fs/partitions/check.c2
-rw-r--r--fs/reiserfs/journal.c17
-rw-r--r--fs/super.c14
-rw-r--r--fs/xfs/linux-2.6/xfs_super.c2
13 files changed, 87 insertions, 166 deletions
diff --git a/fs/block_dev.c b/fs/block_dev.c
index 9329068684d2..fc48912354d1 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -660,7 +660,7 @@ static bool bd_may_claim(struct block_device *bdev, struct block_device *whole,
660 else if (bdev->bd_contains == bdev) 660 else if (bdev->bd_contains == bdev)
661 return true; /* is a whole device which isn't held */ 661 return true; /* is a whole device which isn't held */
662 662
663 else if (whole->bd_holder == bd_claim) 663 else if (whole->bd_holder == bd_may_claim)
664 return true; /* is a partition of a device that is being partitioned */ 664 return true; /* is a partition of a device that is being partitioned */
665 else if (whole->bd_holder != NULL) 665 else if (whole->bd_holder != NULL)
666 return false; /* is a partition of a held device */ 666 return false; /* is a partition of a held device */
@@ -807,10 +807,10 @@ static void __bd_claim(struct block_device *bdev, struct block_device *whole,
807{ 807{
808 /* note that for a whole device bd_holders 808 /* note that for a whole device bd_holders
809 * will be incremented twice, and bd_holder will 809 * will be incremented twice, and bd_holder will
810 * be set to bd_claim before being set to holder 810 * be set to bd_may_claim before being set to holder
811 */ 811 */
812 whole->bd_holders++; 812 whole->bd_holders++;
813 whole->bd_holder = bd_claim; 813 whole->bd_holder = bd_may_claim;
814 bdev->bd_holders++; 814 bdev->bd_holders++;
815 bdev->bd_holder = holder; 815 bdev->bd_holder = holder;
816} 816}
@@ -835,37 +835,7 @@ static void bd_finish_claiming(struct block_device *bdev,
835 __bd_abort_claiming(whole, holder); /* not actually an abort */ 835 __bd_abort_claiming(whole, holder); /* not actually an abort */
836} 836}
837 837
838/** 838static void bd_release(struct block_device *bdev)
839 * bd_claim - claim a block device
840 * @bdev: block device to claim
841 * @holder: holder trying to claim @bdev
842 *
843 * Try to claim @bdev which must have been opened successfully.
844 *
845 * CONTEXT:
846 * Might sleep.
847 *
848 * RETURNS:
849 * 0 if successful, -EBUSY if @bdev is already claimed.
850 */
851int bd_claim(struct block_device *bdev, void *holder)
852{
853 struct block_device *whole = bdev->bd_contains;
854 int res;
855
856 might_sleep();
857
858 spin_lock(&bdev_lock);
859 res = bd_prepare_to_claim(bdev, whole, holder);
860 if (res == 0)
861 __bd_claim(bdev, whole, holder);
862 spin_unlock(&bdev_lock);
863
864 return res;
865}
866EXPORT_SYMBOL(bd_claim);
867
868void bd_release(struct block_device *bdev)
869{ 839{
870 spin_lock(&bdev_lock); 840 spin_lock(&bdev_lock);
871 if (!--bdev->bd_contains->bd_holders) 841 if (!--bdev->bd_contains->bd_holders)
@@ -875,8 +845,6 @@ void bd_release(struct block_device *bdev)
875 spin_unlock(&bdev_lock); 845 spin_unlock(&bdev_lock);
876} 846}
877 847
878EXPORT_SYMBOL(bd_release);
879
880#ifdef CONFIG_SYSFS 848#ifdef CONFIG_SYSFS
881static int add_symlink(struct kobject *from, struct kobject *to) 849static int add_symlink(struct kobject *from, struct kobject *to)
882{ 850{
@@ -943,7 +911,7 @@ out_unlock:
943} 911}
944EXPORT_SYMBOL_GPL(bd_link_disk_holder); 912EXPORT_SYMBOL_GPL(bd_link_disk_holder);
945 913
946void bd_unlink_disk_holder(struct block_device *bdev) 914static void bd_unlink_disk_holder(struct block_device *bdev)
947{ 915{
948 struct gendisk *disk = bdev->bd_holder_disk; 916 struct gendisk *disk = bdev->bd_holder_disk;
949 917
@@ -954,7 +922,9 @@ void bd_unlink_disk_holder(struct block_device *bdev)
954 del_symlink(disk->slave_dir, &part_to_dev(bdev->bd_part)->kobj); 922 del_symlink(disk->slave_dir, &part_to_dev(bdev->bd_part)->kobj);
955 del_symlink(bdev->bd_part->holder_dir, &disk_to_dev(disk)->kobj); 923 del_symlink(bdev->bd_part->holder_dir, &disk_to_dev(disk)->kobj);
956} 924}
957EXPORT_SYMBOL_GPL(bd_unlink_disk_holder); 925#else
926static inline void bd_unlink_disk_holder(struct block_device *bdev)
927{ }
958#endif 928#endif
959 929
960/* 930/*
@@ -964,12 +934,12 @@ EXPORT_SYMBOL_GPL(bd_unlink_disk_holder);
964 * to be used for internal purposes. If you ever need it - reconsider 934 * to be used for internal purposes. If you ever need it - reconsider
965 * your API. 935 * your API.
966 */ 936 */
967struct block_device *open_by_devnum(dev_t dev, fmode_t mode) 937struct block_device *open_by_devnum(dev_t dev, fmode_t mode, void *holder)
968{ 938{
969 struct block_device *bdev = bdget(dev); 939 struct block_device *bdev = bdget(dev);
970 int err = -ENOMEM; 940 int err = -ENOMEM;
971 if (bdev) 941 if (bdev)
972 err = blkdev_get(bdev, mode); 942 err = blkdev_get(bdev, mode, holder);
973 return err ? ERR_PTR(err) : bdev; 943 return err ? ERR_PTR(err) : bdev;
974} 944}
975 945
@@ -1235,17 +1205,37 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part)
1235 return ret; 1205 return ret;
1236} 1206}
1237 1207
1238int blkdev_get(struct block_device *bdev, fmode_t mode) 1208int blkdev_get(struct block_device *bdev, fmode_t mode, void *holder)
1239{ 1209{
1240 return __blkdev_get(bdev, mode, 0); 1210 struct block_device *whole = NULL;
1211 int res;
1212
1213 WARN_ON_ONCE((mode & FMODE_EXCL) && !holder);
1214
1215 if ((mode & FMODE_EXCL) && holder) {
1216 whole = bd_start_claiming(bdev, holder);
1217 if (IS_ERR(whole)) {
1218 bdput(bdev);
1219 return PTR_ERR(whole);
1220 }
1221 }
1222
1223 res = __blkdev_get(bdev, mode, 0);
1224
1225 if (whole) {
1226 if (res == 0)
1227 bd_finish_claiming(bdev, whole, holder);
1228 else
1229 bd_abort_claiming(whole, holder);
1230 }
1231
1232 return res;
1241} 1233}
1242EXPORT_SYMBOL(blkdev_get); 1234EXPORT_SYMBOL(blkdev_get);
1243 1235
1244static int blkdev_open(struct inode * inode, struct file * filp) 1236static int blkdev_open(struct inode * inode, struct file * filp)
1245{ 1237{
1246 struct block_device *whole = NULL;
1247 struct block_device *bdev; 1238 struct block_device *bdev;
1248 int res;
1249 1239
1250 /* 1240 /*
1251 * Preserve backwards compatibility and allow large file access 1241 * Preserve backwards compatibility and allow large file access
@@ -1266,26 +1256,9 @@ static int blkdev_open(struct inode * inode, struct file * filp)
1266 if (bdev == NULL) 1256 if (bdev == NULL)
1267 return -ENOMEM; 1257 return -ENOMEM;
1268 1258
1269 if (filp->f_mode & FMODE_EXCL) {
1270 whole = bd_start_claiming(bdev, filp);
1271 if (IS_ERR(whole)) {
1272 bdput(bdev);
1273 return PTR_ERR(whole);
1274 }
1275 }
1276
1277 filp->f_mapping = bdev->bd_inode->i_mapping; 1259 filp->f_mapping = bdev->bd_inode->i_mapping;
1278 1260
1279 res = blkdev_get(bdev, filp->f_mode); 1261 return blkdev_get(bdev, filp->f_mode, filp);
1280
1281 if (whole) {
1282 if (res == 0)
1283 bd_finish_claiming(bdev, whole, filp);
1284 else
1285 bd_abort_claiming(whole, filp);
1286 }
1287
1288 return res;
1289} 1262}
1290 1263
1291static int __blkdev_put(struct block_device *bdev, fmode_t mode, int for_part) 1264static int __blkdev_put(struct block_device *bdev, fmode_t mode, int for_part)
@@ -1329,6 +1302,13 @@ static int __blkdev_put(struct block_device *bdev, fmode_t mode, int for_part)
1329 1302
1330int blkdev_put(struct block_device *bdev, fmode_t mode) 1303int blkdev_put(struct block_device *bdev, fmode_t mode)
1331{ 1304{
1305 if (mode & FMODE_EXCL) {
1306 mutex_lock(&bdev->bd_mutex);
1307 bd_release(bdev);
1308 if (!bdev->bd_holders)
1309 bd_unlink_disk_holder(bdev);
1310 mutex_unlock(&bdev->bd_mutex);
1311 }
1332 return __blkdev_put(bdev, mode, 0); 1312 return __blkdev_put(bdev, mode, 0);
1333} 1313}
1334EXPORT_SYMBOL(blkdev_put); 1314EXPORT_SYMBOL(blkdev_put);
@@ -1336,8 +1316,7 @@ EXPORT_SYMBOL(blkdev_put);
1336static int blkdev_close(struct inode * inode, struct file * filp) 1316static int blkdev_close(struct inode * inode, struct file * filp)
1337{ 1317{
1338 struct block_device *bdev = I_BDEV(filp->f_mapping->host); 1318 struct block_device *bdev = I_BDEV(filp->f_mapping->host);
1339 if (bdev->bd_holder == filp) 1319
1340 bd_release(bdev);
1341 return blkdev_put(bdev, filp->f_mode); 1320 return blkdev_put(bdev, filp->f_mode);
1342} 1321}
1343 1322
@@ -1494,55 +1473,27 @@ EXPORT_SYMBOL(lookup_bdev);
1494 */ 1473 */
1495struct block_device *open_bdev_exclusive(const char *path, fmode_t mode, void *holder) 1474struct block_device *open_bdev_exclusive(const char *path, fmode_t mode, void *holder)
1496{ 1475{
1497 struct block_device *bdev, *whole; 1476 struct block_device *bdev;
1498 int error; 1477 int error;
1499 1478
1500 bdev = lookup_bdev(path); 1479 bdev = lookup_bdev(path);
1501 if (IS_ERR(bdev)) 1480 if (IS_ERR(bdev))
1502 return bdev; 1481 return bdev;
1503 1482
1504 whole = bd_start_claiming(bdev, holder); 1483 error = blkdev_get(bdev, mode | FMODE_EXCL, holder);
1505 if (IS_ERR(whole)) {
1506 bdput(bdev);
1507 return whole;
1508 }
1509
1510 error = blkdev_get(bdev, mode);
1511 if (error) 1484 if (error)
1512 goto out_abort_claiming; 1485 return ERR_PTR(error);
1513 1486
1514 error = -EACCES; 1487 if ((mode & FMODE_WRITE) && bdev_read_only(bdev)) {
1515 if ((mode & FMODE_WRITE) && bdev_read_only(bdev)) 1488 blkdev_put(bdev, mode);
1516 goto out_blkdev_put; 1489 return ERR_PTR(-EACCES);
1490 }
1517 1491
1518 bd_finish_claiming(bdev, whole, holder);
1519 return bdev; 1492 return bdev;
1520
1521out_blkdev_put:
1522 blkdev_put(bdev, mode);
1523out_abort_claiming:
1524 bd_abort_claiming(whole, holder);
1525 return ERR_PTR(error);
1526} 1493}
1527 1494
1528EXPORT_SYMBOL(open_bdev_exclusive); 1495EXPORT_SYMBOL(open_bdev_exclusive);
1529 1496
1530/**
1531 * close_bdev_exclusive - close a blockdevice opened by open_bdev_exclusive()
1532 *
1533 * @bdev: blockdevice to close
1534 * @mode: mode, must match that used to open.
1535 *
1536 * This is the counterpart to open_bdev_exclusive().
1537 */
1538void close_bdev_exclusive(struct block_device *bdev, fmode_t mode)
1539{
1540 bd_release(bdev);
1541 blkdev_put(bdev, mode);
1542}
1543
1544EXPORT_SYMBOL(close_bdev_exclusive);
1545
1546int __invalidate_device(struct block_device *bdev) 1497int __invalidate_device(struct block_device *bdev)
1547{ 1498{
1548 struct super_block *sb = get_super(bdev); 1499 struct super_block *sb = get_super(bdev);
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index d39596224d21..f1b729d3b883 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -489,7 +489,7 @@ again:
489 continue; 489 continue;
490 490
491 if (device->bdev) { 491 if (device->bdev) {
492 close_bdev_exclusive(device->bdev, device->mode); 492 blkdev_put(device->bdev, device->mode | FMODE_EXCL);
493 device->bdev = NULL; 493 device->bdev = NULL;
494 fs_devices->open_devices--; 494 fs_devices->open_devices--;
495 } 495 }
@@ -523,7 +523,7 @@ static int __btrfs_close_devices(struct btrfs_fs_devices *fs_devices)
523 523
524 list_for_each_entry(device, &fs_devices->devices, dev_list) { 524 list_for_each_entry(device, &fs_devices->devices, dev_list) {
525 if (device->bdev) { 525 if (device->bdev) {
526 close_bdev_exclusive(device->bdev, device->mode); 526 blkdev_put(device->bdev, device->mode | FMODE_EXCL);
527 fs_devices->open_devices--; 527 fs_devices->open_devices--;
528 } 528 }
529 if (device->writeable) { 529 if (device->writeable) {
@@ -638,7 +638,7 @@ static int __btrfs_open_devices(struct btrfs_fs_devices *fs_devices,
638error_brelse: 638error_brelse:
639 brelse(bh); 639 brelse(bh);
640error_close: 640error_close:
641 close_bdev_exclusive(bdev, flags); 641 blkdev_put(bdev, flags | FMODE_EXCL);
642error: 642error:
643 continue; 643 continue;
644 } 644 }
@@ -716,7 +716,7 @@ int btrfs_scan_one_device(const char *path, fmode_t flags, void *holder,
716 716
717 brelse(bh); 717 brelse(bh);
718error_close: 718error_close:
719 close_bdev_exclusive(bdev, flags); 719 blkdev_put(bdev, flags | FMODE_EXCL);
720error: 720error:
721 mutex_unlock(&uuid_mutex); 721 mutex_unlock(&uuid_mutex);
722 return ret; 722 return ret;
@@ -1244,7 +1244,7 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path)
1244 root->fs_info->fs_devices->latest_bdev = next_device->bdev; 1244 root->fs_info->fs_devices->latest_bdev = next_device->bdev;
1245 1245
1246 if (device->bdev) { 1246 if (device->bdev) {
1247 close_bdev_exclusive(device->bdev, device->mode); 1247 blkdev_put(device->bdev, device->mode | FMODE_EXCL);
1248 device->bdev = NULL; 1248 device->bdev = NULL;
1249 device->fs_devices->open_devices--; 1249 device->fs_devices->open_devices--;
1250 } 1250 }
@@ -1287,7 +1287,7 @@ error_brelse:
1287 brelse(bh); 1287 brelse(bh);
1288error_close: 1288error_close:
1289 if (bdev) 1289 if (bdev)
1290 close_bdev_exclusive(bdev, FMODE_READ); 1290 blkdev_put(bdev, FMODE_READ | FMODE_EXCL);
1291out: 1291out:
1292 mutex_unlock(&root->fs_info->volume_mutex); 1292 mutex_unlock(&root->fs_info->volume_mutex);
1293 mutex_unlock(&uuid_mutex); 1293 mutex_unlock(&uuid_mutex);
@@ -1565,7 +1565,7 @@ out:
1565 mutex_unlock(&root->fs_info->volume_mutex); 1565 mutex_unlock(&root->fs_info->volume_mutex);
1566 return ret; 1566 return ret;
1567error: 1567error:
1568 close_bdev_exclusive(bdev, 0); 1568 blkdev_put(bdev, FMODE_EXCL);
1569 if (seeding_dev) { 1569 if (seeding_dev) {
1570 mutex_unlock(&uuid_mutex); 1570 mutex_unlock(&uuid_mutex);
1571 up_write(&sb->s_umount); 1571 up_write(&sb->s_umount);
diff --git a/fs/ext3/super.c b/fs/ext3/super.c
index 2fedaf8b5012..23e7513dba9c 100644
--- a/fs/ext3/super.c
+++ b/fs/ext3/super.c
@@ -347,7 +347,7 @@ static struct block_device *ext3_blkdev_get(dev_t dev, struct super_block *sb)
347 struct block_device *bdev; 347 struct block_device *bdev;
348 char b[BDEVNAME_SIZE]; 348 char b[BDEVNAME_SIZE];
349 349
350 bdev = open_by_devnum(dev, FMODE_READ|FMODE_WRITE); 350 bdev = open_by_devnum(dev, FMODE_READ|FMODE_WRITE|FMODE_EXCL, sb);
351 if (IS_ERR(bdev)) 351 if (IS_ERR(bdev))
352 goto fail; 352 goto fail;
353 return bdev; 353 return bdev;
@@ -364,8 +364,7 @@ fail:
364 */ 364 */
365static int ext3_blkdev_put(struct block_device *bdev) 365static int ext3_blkdev_put(struct block_device *bdev)
366{ 366{
367 bd_release(bdev); 367 return blkdev_put(bdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL);
368 return blkdev_put(bdev, FMODE_READ|FMODE_WRITE);
369} 368}
370 369
371static int ext3_blkdev_remove(struct ext3_sb_info *sbi) 370static int ext3_blkdev_remove(struct ext3_sb_info *sbi)
@@ -2136,13 +2135,6 @@ static journal_t *ext3_get_dev_journal(struct super_block *sb,
2136 if (bdev == NULL) 2135 if (bdev == NULL)
2137 return NULL; 2136 return NULL;
2138 2137
2139 if (bd_claim(bdev, sb)) {
2140 ext3_msg(sb, KERN_ERR,
2141 "error: failed to claim external journal device");
2142 blkdev_put(bdev, FMODE_READ|FMODE_WRITE);
2143 return NULL;
2144 }
2145
2146 blocksize = sb->s_blocksize; 2138 blocksize = sb->s_blocksize;
2147 hblock = bdev_logical_block_size(bdev); 2139 hblock = bdev_logical_block_size(bdev);
2148 if (blocksize < hblock) { 2140 if (blocksize < hblock) {
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 61182fe6254e..5dd0b3e76fa8 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -647,7 +647,7 @@ static struct block_device *ext4_blkdev_get(dev_t dev, struct super_block *sb)
647 struct block_device *bdev; 647 struct block_device *bdev;
648 char b[BDEVNAME_SIZE]; 648 char b[BDEVNAME_SIZE];
649 649
650 bdev = open_by_devnum(dev, FMODE_READ|FMODE_WRITE); 650 bdev = open_by_devnum(dev, FMODE_READ|FMODE_WRITE|FMODE_EXCL, sb);
651 if (IS_ERR(bdev)) 651 if (IS_ERR(bdev))
652 goto fail; 652 goto fail;
653 return bdev; 653 return bdev;
@@ -663,8 +663,7 @@ fail:
663 */ 663 */
664static int ext4_blkdev_put(struct block_device *bdev) 664static int ext4_blkdev_put(struct block_device *bdev)
665{ 665{
666 bd_release(bdev); 666 return blkdev_put(bdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL);
667 return blkdev_put(bdev, FMODE_READ|FMODE_WRITE);
668} 667}
669 668
670static int ext4_blkdev_remove(struct ext4_sb_info *sbi) 669static int ext4_blkdev_remove(struct ext4_sb_info *sbi)
@@ -3758,13 +3757,6 @@ static journal_t *ext4_get_dev_journal(struct super_block *sb,
3758 if (bdev == NULL) 3757 if (bdev == NULL)
3759 return NULL; 3758 return NULL;
3760 3759
3761 if (bd_claim(bdev, sb)) {
3762 ext4_msg(sb, KERN_ERR,
3763 "failed to claim external journal device");
3764 blkdev_put(bdev, FMODE_READ|FMODE_WRITE);
3765 return NULL;
3766 }
3767
3768 blocksize = sb->s_blocksize; 3760 blocksize = sb->s_blocksize;
3769 hblock = bdev_logical_block_size(bdev); 3761 hblock = bdev_logical_block_size(bdev);
3770 if (blocksize < hblock) { 3762 if (blocksize < hblock) {
diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c
index 3eb1393f7b81..c1f0763a022b 100644
--- a/fs/gfs2/ops_fstype.c
+++ b/fs/gfs2/ops_fstype.c
@@ -1298,7 +1298,7 @@ static struct dentry *gfs2_mount(struct file_system_type *fs_type, int flags,
1298 goto error_bdev; 1298 goto error_bdev;
1299 1299
1300 if (s->s_root) 1300 if (s->s_root)
1301 close_bdev_exclusive(bdev, mode); 1301 blkdev_put(bdev, mode | FMODE_EXCL);
1302 1302
1303 memset(&args, 0, sizeof(args)); 1303 memset(&args, 0, sizeof(args));
1304 args.ar_quota = GFS2_QUOTA_DEFAULT; 1304 args.ar_quota = GFS2_QUOTA_DEFAULT;
@@ -1342,7 +1342,7 @@ error_super:
1342 deactivate_locked_super(s); 1342 deactivate_locked_super(s);
1343 return ERR_PTR(error); 1343 return ERR_PTR(error);
1344error_bdev: 1344error_bdev:
1345 close_bdev_exclusive(bdev, mode); 1345 blkdev_put(bdev, mode | FMODE_EXCL);
1346 return ERR_PTR(error); 1346 return ERR_PTR(error);
1347} 1347}
1348 1348
diff --git a/fs/jfs/jfs_logmgr.c b/fs/jfs/jfs_logmgr.c
index e1b8493b9aaa..5a290f22dcc3 100644
--- a/fs/jfs/jfs_logmgr.c
+++ b/fs/jfs/jfs_logmgr.c
@@ -1120,16 +1120,13 @@ int lmLogOpen(struct super_block *sb)
1120 * file systems to log may have n-to-1 relationship; 1120 * file systems to log may have n-to-1 relationship;
1121 */ 1121 */
1122 1122
1123 bdev = open_by_devnum(sbi->logdev, FMODE_READ|FMODE_WRITE); 1123 bdev = open_by_devnum(sbi->logdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL,
1124 log);
1124 if (IS_ERR(bdev)) { 1125 if (IS_ERR(bdev)) {
1125 rc = -PTR_ERR(bdev); 1126 rc = -PTR_ERR(bdev);
1126 goto free; 1127 goto free;
1127 } 1128 }
1128 1129
1129 if ((rc = bd_claim(bdev, log))) {
1130 goto close;
1131 }
1132
1133 log->bdev = bdev; 1130 log->bdev = bdev;
1134 memcpy(log->uuid, sbi->loguuid, sizeof(log->uuid)); 1131 memcpy(log->uuid, sbi->loguuid, sizeof(log->uuid));
1135 1132
@@ -1137,7 +1134,7 @@ int lmLogOpen(struct super_block *sb)
1137 * initialize log: 1134 * initialize log:
1138 */ 1135 */
1139 if ((rc = lmLogInit(log))) 1136 if ((rc = lmLogInit(log)))
1140 goto unclaim; 1137 goto close;
1141 1138
1142 list_add(&log->journal_list, &jfs_external_logs); 1139 list_add(&log->journal_list, &jfs_external_logs);
1143 1140
@@ -1163,11 +1160,8 @@ journal_found:
1163 list_del(&log->journal_list); 1160 list_del(&log->journal_list);
1164 lbmLogShutdown(log); 1161 lbmLogShutdown(log);
1165 1162
1166 unclaim:
1167 bd_release(bdev);
1168
1169 close: /* close external log device */ 1163 close: /* close external log device */
1170 blkdev_put(bdev, FMODE_READ|FMODE_WRITE); 1164 blkdev_put(bdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL);
1171 1165
1172 free: /* free log descriptor */ 1166 free: /* free log descriptor */
1173 mutex_unlock(&jfs_log_mutex); 1167 mutex_unlock(&jfs_log_mutex);
@@ -1512,8 +1506,7 @@ int lmLogClose(struct super_block *sb)
1512 bdev = log->bdev; 1506 bdev = log->bdev;
1513 rc = lmLogShutdown(log); 1507 rc = lmLogShutdown(log);
1514 1508
1515 bd_release(bdev); 1509 blkdev_put(bdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL);
1516 blkdev_put(bdev, FMODE_READ|FMODE_WRITE);
1517 1510
1518 kfree(log); 1511 kfree(log);
1519 1512
diff --git a/fs/logfs/dev_bdev.c b/fs/logfs/dev_bdev.c
index 92ca6fbe09bd..734b9025858e 100644
--- a/fs/logfs/dev_bdev.c
+++ b/fs/logfs/dev_bdev.c
@@ -300,7 +300,7 @@ static int bdev_write_sb(struct super_block *sb, struct page *page)
300 300
301static void bdev_put_device(struct logfs_super *s) 301static void bdev_put_device(struct logfs_super *s)
302{ 302{
303 close_bdev_exclusive(s->s_bdev, FMODE_READ|FMODE_WRITE); 303 blkdev_put(s->s_bdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL);
304} 304}
305 305
306static int bdev_can_write_buf(struct super_block *sb, u64 ofs) 306static int bdev_can_write_buf(struct super_block *sb, u64 ofs)
@@ -331,7 +331,7 @@ int logfs_get_sb_bdev(struct logfs_super *p, struct file_system_type *type,
331 331
332 if (MAJOR(bdev->bd_dev) == MTD_BLOCK_MAJOR) { 332 if (MAJOR(bdev->bd_dev) == MTD_BLOCK_MAJOR) {
333 int mtdnr = MINOR(bdev->bd_dev); 333 int mtdnr = MINOR(bdev->bd_dev);
334 close_bdev_exclusive(bdev, FMODE_READ|FMODE_WRITE); 334 blkdev_put(bdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL);
335 return logfs_get_sb_mtd(p, mtdnr); 335 return logfs_get_sb_mtd(p, mtdnr);
336 } 336 }
337 337
diff --git a/fs/nilfs2/super.c b/fs/nilfs2/super.c
index f804d41ec9d3..756a6798d7c8 100644
--- a/fs/nilfs2/super.c
+++ b/fs/nilfs2/super.c
@@ -1233,7 +1233,7 @@ nilfs_mount(struct file_system_type *fs_type, int flags,
1233 } 1233 }
1234 1234
1235 if (!s_new) 1235 if (!s_new)
1236 close_bdev_exclusive(sd.bdev, mode); 1236 blkdev_put(sd.bdev, mode | FMODE_EXCL);
1237 1237
1238 return root_dentry; 1238 return root_dentry;
1239 1239
@@ -1242,7 +1242,7 @@ nilfs_mount(struct file_system_type *fs_type, int flags,
1242 1242
1243 failed: 1243 failed:
1244 if (!s_new) 1244 if (!s_new)
1245 close_bdev_exclusive(sd.bdev, mode); 1245 blkdev_put(sd.bdev, mode | FMODE_EXCL);
1246 return ERR_PTR(err); 1246 return ERR_PTR(err);
1247} 1247}
1248 1248
diff --git a/fs/ocfs2/cluster/heartbeat.c b/fs/ocfs2/cluster/heartbeat.c
index 52c7557f3e25..d0a2721eaceb 100644
--- a/fs/ocfs2/cluster/heartbeat.c
+++ b/fs/ocfs2/cluster/heartbeat.c
@@ -1674,7 +1674,7 @@ static ssize_t o2hb_region_dev_write(struct o2hb_region *reg,
1674 goto out; 1674 goto out;
1675 1675
1676 reg->hr_bdev = I_BDEV(filp->f_mapping->host); 1676 reg->hr_bdev = I_BDEV(filp->f_mapping->host);
1677 ret = blkdev_get(reg->hr_bdev, FMODE_WRITE | FMODE_READ); 1677 ret = blkdev_get(reg->hr_bdev, FMODE_WRITE | FMODE_READ, NULL);
1678 if (ret) { 1678 if (ret) {
1679 reg->hr_bdev = NULL; 1679 reg->hr_bdev = NULL;
1680 goto out; 1680 goto out;
diff --git a/fs/partitions/check.c b/fs/partitions/check.c
index 0a8b0ad0c7e2..2e6501d034ab 100644
--- a/fs/partitions/check.c
+++ b/fs/partitions/check.c
@@ -549,7 +549,7 @@ void register_disk(struct gendisk *disk)
549 goto exit; 549 goto exit;
550 550
551 bdev->bd_invalidated = 1; 551 bdev->bd_invalidated = 1;
552 err = blkdev_get(bdev, FMODE_READ); 552 err = blkdev_get(bdev, FMODE_READ, NULL);
553 if (err < 0) 553 if (err < 0)
554 goto exit; 554 goto exit;
555 blkdev_put(bdev, FMODE_READ); 555 blkdev_put(bdev, FMODE_READ);
diff --git a/fs/reiserfs/journal.c b/fs/reiserfs/journal.c
index 076c8b194682..b488136f5ace 100644
--- a/fs/reiserfs/journal.c
+++ b/fs/reiserfs/journal.c
@@ -2552,8 +2552,6 @@ static int release_journal_dev(struct super_block *super,
2552 result = 0; 2552 result = 0;
2553 2553
2554 if (journal->j_dev_bd != NULL) { 2554 if (journal->j_dev_bd != NULL) {
2555 if (journal->j_dev_bd->bd_dev != super->s_dev)
2556 bd_release(journal->j_dev_bd);
2557 result = blkdev_put(journal->j_dev_bd, journal->j_dev_mode); 2555 result = blkdev_put(journal->j_dev_bd, journal->j_dev_mode);
2558 journal->j_dev_bd = NULL; 2556 journal->j_dev_bd = NULL;
2559 } 2557 }
@@ -2571,7 +2569,7 @@ static int journal_init_dev(struct super_block *super,
2571{ 2569{
2572 int result; 2570 int result;
2573 dev_t jdev; 2571 dev_t jdev;
2574 fmode_t blkdev_mode = FMODE_READ | FMODE_WRITE; 2572 fmode_t blkdev_mode = FMODE_READ | FMODE_WRITE | FMODE_EXCL;
2575 char b[BDEVNAME_SIZE]; 2573 char b[BDEVNAME_SIZE];
2576 2574
2577 result = 0; 2575 result = 0;
@@ -2585,7 +2583,9 @@ static int journal_init_dev(struct super_block *super,
2585 2583
2586 /* there is no "jdev" option and journal is on separate device */ 2584 /* there is no "jdev" option and journal is on separate device */
2587 if ((!jdev_name || !jdev_name[0])) { 2585 if ((!jdev_name || !jdev_name[0])) {
2588 journal->j_dev_bd = open_by_devnum(jdev, blkdev_mode); 2586 if (jdev == super->s_dev)
2587 blkdev_mode &= ~FMODE_EXCL;
2588 journal->j_dev_bd = open_by_devnum(jdev, blkdev_mode, journal);
2589 journal->j_dev_mode = blkdev_mode; 2589 journal->j_dev_mode = blkdev_mode;
2590 if (IS_ERR(journal->j_dev_bd)) { 2590 if (IS_ERR(journal->j_dev_bd)) {
2591 result = PTR_ERR(journal->j_dev_bd); 2591 result = PTR_ERR(journal->j_dev_bd);
@@ -2594,15 +2594,8 @@ static int journal_init_dev(struct super_block *super,
2594 "cannot init journal device '%s': %i", 2594 "cannot init journal device '%s': %i",
2595 __bdevname(jdev, b), result); 2595 __bdevname(jdev, b), result);
2596 return result; 2596 return result;
2597 } else if (jdev != super->s_dev) { 2597 } else if (jdev != super->s_dev)
2598 result = bd_claim(journal->j_dev_bd, journal);
2599 if (result) {
2600 blkdev_put(journal->j_dev_bd, blkdev_mode);
2601 return result;
2602 }
2603
2604 set_blocksize(journal->j_dev_bd, super->s_blocksize); 2598 set_blocksize(journal->j_dev_bd, super->s_blocksize);
2605 }
2606 2599
2607 return 0; 2600 return 0;
2608 } 2601 }
diff --git a/fs/super.c b/fs/super.c
index ca696155cd9a..22374bf0ba87 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -801,13 +801,13 @@ struct dentry *mount_bdev(struct file_system_type *fs_type,
801 801
802 /* 802 /*
803 * s_umount nests inside bd_mutex during 803 * s_umount nests inside bd_mutex during
804 * __invalidate_device(). close_bdev_exclusive() 804 * __invalidate_device(). blkdev_put() acquires
805 * acquires bd_mutex and can't be called under 805 * bd_mutex and can't be called under s_umount. Drop
806 * s_umount. Drop s_umount temporarily. This is safe 806 * s_umount temporarily. This is safe as we're
807 * as we're holding an active reference. 807 * holding an active reference.
808 */ 808 */
809 up_write(&s->s_umount); 809 up_write(&s->s_umount);
810 close_bdev_exclusive(bdev, mode); 810 blkdev_put(bdev, mode | FMODE_EXCL);
811 down_write(&s->s_umount); 811 down_write(&s->s_umount);
812 } else { 812 } else {
813 char b[BDEVNAME_SIZE]; 813 char b[BDEVNAME_SIZE];
@@ -831,7 +831,7 @@ struct dentry *mount_bdev(struct file_system_type *fs_type,
831error_s: 831error_s:
832 error = PTR_ERR(s); 832 error = PTR_ERR(s);
833error_bdev: 833error_bdev:
834 close_bdev_exclusive(bdev, mode); 834 blkdev_put(bdev, mode | FMODE_EXCL);
835error: 835error:
836 return ERR_PTR(error); 836 return ERR_PTR(error);
837} 837}
@@ -862,7 +862,7 @@ void kill_block_super(struct super_block *sb)
862 bdev->bd_super = NULL; 862 bdev->bd_super = NULL;
863 generic_shutdown_super(sb); 863 generic_shutdown_super(sb);
864 sync_blockdev(bdev); 864 sync_blockdev(bdev);
865 close_bdev_exclusive(bdev, mode); 865 blkdev_put(bdev, mode | FMODE_EXCL);
866} 866}
867 867
868EXPORT_SYMBOL(kill_block_super); 868EXPORT_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 9f3a78fe6ae4..a1a6e5ceea67 100644
--- a/fs/xfs/linux-2.6/xfs_super.c
+++ b/fs/xfs/linux-2.6/xfs_super.c
@@ -623,7 +623,7 @@ xfs_blkdev_put(
623 struct block_device *bdev) 623 struct block_device *bdev)
624{ 624{
625 if (bdev) 625 if (bdev)
626 close_bdev_exclusive(bdev, FMODE_READ|FMODE_WRITE); 626 blkdev_put(bdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL);
627} 627}
628 628
629/* 629/*