aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2010-11-13 05:55:17 -0500
committerTejun Heo <tj@kernel.org>2010-11-13 05:55:17 -0500
commite525fd89d380c4a94c0d63913a1dd1a593ed25e7 (patch)
treed226ef40d3f99e42fcf272ad432585cbd641ebec
parente09b457bdb7e8d23fc54dcef0930ac697d8de895 (diff)
block: make blkdev_get/put() handle exclusive access
Over time, block layer has accumulated a set of APIs dealing with bdev open, close, claim and release. * blkdev_get/put() are the primary open and close functions. * bd_claim/release() deal with exclusive open. * open/close_bdev_exclusive() are combination of open and claim and the other way around, respectively. * bd_link/unlink_disk_holder() to create and remove holder/slave symlinks. * open_by_devnum() wraps bdget() + blkdev_get(). The interface is a bit confusing and the decoupling of open and claim makes it impossible to properly guarantee exclusive access as in-kernel open + claim sequence can disturb the existing exclusive open even before the block layer knows the current open if for another exclusive access. Reorganize the interface such that, * blkdev_get() is extended to include exclusive access management. @holder argument is added and, if is @FMODE_EXCL specified, it will gain exclusive access atomically w.r.t. other exclusive accesses. * blkdev_put() is similarly extended. It now takes @mode argument and if @FMODE_EXCL is set, it releases an exclusive access. Also, when the last exclusive claim is released, the holder/slave symlinks are removed automatically. * bd_claim/release() and close_bdev_exclusive() are no longer necessary and either made static or removed. * bd_link_disk_holder() remains the same but bd_unlink_disk_holder() is no longer necessary and removed. * open_bdev_exclusive() becomes a simple wrapper around lookup_bdev() and blkdev_get(). It also has an unexpected extra bdev_read_only() test which probably should be moved into blkdev_get(). * open_by_devnum() is modified to take @holder argument and pass it to blkdev_get(). Most of bdev open/close operations are unified into blkdev_get/put() and most exclusive accesses are tested atomically at the open time (as it should). This cleans up code and removes some, both valid and invalid, but unnecessary all the same, corner cases. open_bdev_exclusive() and open_by_devnum() can use further cleanup - rename to blkdev_get_by_path() and blkdev_get_by_devt() and drop special features. Well, let's leave them for another day. Most conversions are straight-forward. drbd conversion is a bit more involved as there was some reordering, but the logic should stay the same. Signed-off-by: Tejun Heo <tj@kernel.org> Acked-by: Neil Brown <neilb@suse.de> Acked-by: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp> Acked-by: Mike Snitzer <snitzer@redhat.com> Acked-by: Philipp Reisner <philipp.reisner@linbit.com> Cc: Peter Osterlund <petero2@telia.com> Cc: Martin Schwidefsky <schwidefsky@de.ibm.com> Cc: Heiko Carstens <heiko.carstens@de.ibm.com> Cc: Jan Kara <jack@suse.cz> Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Andreas Dilger <adilger.kernel@dilger.ca> Cc: "Theodore Ts'o" <tytso@mit.edu> Cc: Mark Fasheh <mfasheh@suse.com> Cc: Joel Becker <joel.becker@oracle.com> Cc: Alex Elder <aelder@sgi.com> Cc: Christoph Hellwig <hch@infradead.org> Cc: dm-devel@redhat.com Cc: drbd-dev@lists.linbit.com Cc: Leo Chen <leochen@broadcom.com> Cc: Scott Branden <sbranden@broadcom.com> Cc: Chris Mason <chris.mason@oracle.com> Cc: Steven Whitehouse <swhiteho@redhat.com> Cc: Dave Kleikamp <shaggy@linux.vnet.ibm.com> Cc: Joern Engel <joern@logfs.org> Cc: reiserfs-devel@vger.kernel.org Cc: Alexander Viro <viro@zeniv.linux.org.uk>
-rw-r--r--block/ioctl.c5
-rw-r--r--drivers/block/drbd/drbd_int.h2
-rw-r--r--drivers/block/drbd/drbd_main.c7
-rw-r--r--drivers/block/drbd/drbd_nl.c103
-rw-r--r--drivers/block/pktcdvd.c22
-rw-r--r--drivers/char/raw.c14
-rw-r--r--drivers/md/dm-table.c15
-rw-r--r--drivers/md/md.c14
-rw-r--r--drivers/mtd/devices/block2mtd.c17
-rw-r--r--drivers/s390/block/dasd_genhd.c2
-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
-rw-r--r--include/linux/fs.h14
-rw-r--r--kernel/power/swap.c5
-rw-r--r--mm/swapfile.c7
26 files changed, 162 insertions, 318 deletions
diff --git a/block/ioctl.c b/block/ioctl.c
index d724ceb1d465..cc46d499fd27 100644
--- a/block/ioctl.c
+++ b/block/ioctl.c
@@ -294,11 +294,12 @@ int blkdev_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd,
294 return -EINVAL; 294 return -EINVAL;
295 if (get_user(n, (int __user *) arg)) 295 if (get_user(n, (int __user *) arg))
296 return -EFAULT; 296 return -EFAULT;
297 if (!(mode & FMODE_EXCL) && bd_claim(bdev, &bdev) < 0) 297 if (!(mode & FMODE_EXCL) &&
298 blkdev_get(bdev, mode | FMODE_EXCL, &bdev) < 0)
298 return -EBUSY; 299 return -EBUSY;
299 ret = set_blocksize(bdev, n); 300 ret = set_blocksize(bdev, n);
300 if (!(mode & FMODE_EXCL)) 301 if (!(mode & FMODE_EXCL))
301 bd_release(bdev); 302 blkdev_put(bdev, mode | FMODE_EXCL);
302 return ret; 303 return ret;
303 case BLKPG: 304 case BLKPG:
304 ret = blkpg_ioctl(bdev, (struct blkpg_ioctl_arg __user *) arg); 305 ret = blkpg_ioctl(bdev, (struct blkpg_ioctl_arg __user *) arg);
diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index 9bdcf4393c0a..0590b9f67ec6 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -923,8 +923,6 @@ struct drbd_md {
923struct drbd_backing_dev { 923struct drbd_backing_dev {
924 struct block_device *backing_bdev; 924 struct block_device *backing_bdev;
925 struct block_device *md_bdev; 925 struct block_device *md_bdev;
926 struct file *lo_file;
927 struct file *md_file;
928 struct drbd_md md; 926 struct drbd_md md;
929 struct disk_conf dc; /* The user provided config... */ 927 struct disk_conf dc; /* The user provided config... */
930 sector_t known_size; /* last known size of that backing device */ 928 sector_t known_size; /* last known size of that backing device */
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index 25c7a73c5062..7ec1a82064a9 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -3361,11 +3361,8 @@ void drbd_free_bc(struct drbd_backing_dev *ldev)
3361 if (ldev == NULL) 3361 if (ldev == NULL)
3362 return; 3362 return;
3363 3363
3364 bd_release(ldev->backing_bdev); 3364 blkdev_put(ldev->backing_bdev, FMODE_READ | FMODE_WRITE | FMODE_EXCL);
3365 bd_release(ldev->md_bdev); 3365 blkdev_put(ldev->md_bdev, FMODE_READ | FMODE_WRITE | FMODE_EXCL);
3366
3367 fput(ldev->lo_file);
3368 fput(ldev->md_file);
3369 3366
3370 kfree(ldev); 3367 kfree(ldev);
3371} 3368}
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c
index 87925e97e613..fd0346090289 100644
--- a/drivers/block/drbd/drbd_nl.c
+++ b/drivers/block/drbd/drbd_nl.c
@@ -855,7 +855,7 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp
855 sector_t max_possible_sectors; 855 sector_t max_possible_sectors;
856 sector_t min_md_device_sectors; 856 sector_t min_md_device_sectors;
857 struct drbd_backing_dev *nbc = NULL; /* new_backing_conf */ 857 struct drbd_backing_dev *nbc = NULL; /* new_backing_conf */
858 struct inode *inode, *inode2; 858 struct block_device *bdev;
859 struct lru_cache *resync_lru = NULL; 859 struct lru_cache *resync_lru = NULL;
860 union drbd_state ns, os; 860 union drbd_state ns, os;
861 unsigned int max_seg_s; 861 unsigned int max_seg_s;
@@ -902,46 +902,40 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp
902 } 902 }
903 } 903 }
904 904
905 nbc->lo_file = filp_open(nbc->dc.backing_dev, O_RDWR, 0); 905 bdev = open_bdev_exclusive(nbc->dc.backing_dev,
906 if (IS_ERR(nbc->lo_file)) { 906 FMODE_READ | FMODE_WRITE, mdev);
907 if (IS_ERR(bdev)) {
907 dev_err(DEV, "open(\"%s\") failed with %ld\n", nbc->dc.backing_dev, 908 dev_err(DEV, "open(\"%s\") failed with %ld\n", nbc->dc.backing_dev,
908 PTR_ERR(nbc->lo_file)); 909 PTR_ERR(bdev));
909 nbc->lo_file = NULL;
910 retcode = ERR_OPEN_DISK; 910 retcode = ERR_OPEN_DISK;
911 goto fail; 911 goto fail;
912 } 912 }
913 nbc->backing_bdev = bdev;
913 914
914 inode = nbc->lo_file->f_dentry->d_inode; 915 /*
915 916 * meta_dev_idx >= 0: external fixed size, possibly multiple
916 if (!S_ISBLK(inode->i_mode)) { 917 * drbd sharing one meta device. TODO in that case, paranoia
917 retcode = ERR_DISK_NOT_BDEV; 918 * check that [md_bdev, meta_dev_idx] is not yet used by some
918 goto fail; 919 * other drbd minor! (if you use drbd.conf + drbdadm, that
919 } 920 * should check it for you already; but if you don't, or
920 921 * someone fooled it, we need to double check here)
921 nbc->md_file = filp_open(nbc->dc.meta_dev, O_RDWR, 0); 922 */
922 if (IS_ERR(nbc->md_file)) { 923 bdev = open_bdev_exclusive(nbc->dc.meta_dev,
924 FMODE_READ | FMODE_WRITE,
925 (nbc->dc.meta_dev_idx < 0) ?
926 (void *)mdev : (void *)drbd_m_holder);
927 if (IS_ERR(bdev)) {
923 dev_err(DEV, "open(\"%s\") failed with %ld\n", nbc->dc.meta_dev, 928 dev_err(DEV, "open(\"%s\") failed with %ld\n", nbc->dc.meta_dev,
924 PTR_ERR(nbc->md_file)); 929 PTR_ERR(bdev));
925 nbc->md_file = NULL;
926 retcode = ERR_OPEN_MD_DISK; 930 retcode = ERR_OPEN_MD_DISK;
927 goto fail; 931 goto fail;
928 } 932 }
933 nbc->md_bdev = bdev;
929 934
930 inode2 = nbc->md_file->f_dentry->d_inode; 935 if ((nbc->backing_bdev == nbc->md_bdev) !=
931 936 (nbc->dc.meta_dev_idx == DRBD_MD_INDEX_INTERNAL ||
932 if (!S_ISBLK(inode2->i_mode)) { 937 nbc->dc.meta_dev_idx == DRBD_MD_INDEX_FLEX_INT)) {
933 retcode = ERR_MD_NOT_BDEV; 938 retcode = ERR_MD_IDX_INVALID;
934 goto fail;
935 }
936
937 nbc->backing_bdev = inode->i_bdev;
938 if (bd_claim(nbc->backing_bdev, mdev)) {
939 printk(KERN_ERR "drbd: bd_claim(%p,%p); failed [%p;%p;%u]\n",
940 nbc->backing_bdev, mdev,
941 nbc->backing_bdev->bd_holder,
942 nbc->backing_bdev->bd_contains->bd_holder,
943 nbc->backing_bdev->bd_holders);
944 retcode = ERR_BDCLAIM_DISK;
945 goto fail; 939 goto fail;
946 } 940 }
947 941
@@ -950,28 +944,7 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp
950 offsetof(struct bm_extent, lce)); 944 offsetof(struct bm_extent, lce));
951 if (!resync_lru) { 945 if (!resync_lru) {
952 retcode = ERR_NOMEM; 946 retcode = ERR_NOMEM;
953 goto release_bdev_fail; 947 goto fail;
954 }
955
956 /* meta_dev_idx >= 0: external fixed size,
957 * possibly multiple drbd sharing one meta device.
958 * TODO in that case, paranoia check that [md_bdev, meta_dev_idx] is
959 * not yet used by some other drbd minor!
960 * (if you use drbd.conf + drbdadm,
961 * that should check it for you already; but if you don't, or someone
962 * fooled it, we need to double check here) */
963 nbc->md_bdev = inode2->i_bdev;
964 if (bd_claim(nbc->md_bdev, (nbc->dc.meta_dev_idx < 0) ? (void *)mdev
965 : (void *) drbd_m_holder)) {
966 retcode = ERR_BDCLAIM_MD_DISK;
967 goto release_bdev_fail;
968 }
969
970 if ((nbc->backing_bdev == nbc->md_bdev) !=
971 (nbc->dc.meta_dev_idx == DRBD_MD_INDEX_INTERNAL ||
972 nbc->dc.meta_dev_idx == DRBD_MD_INDEX_FLEX_INT)) {
973 retcode = ERR_MD_IDX_INVALID;
974 goto release_bdev2_fail;
975 } 948 }
976 949
977 /* RT - for drbd_get_max_capacity() DRBD_MD_INDEX_FLEX_INT */ 950 /* RT - for drbd_get_max_capacity() DRBD_MD_INDEX_FLEX_INT */
@@ -982,7 +955,7 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp
982 (unsigned long long) drbd_get_max_capacity(nbc), 955 (unsigned long long) drbd_get_max_capacity(nbc),
983 (unsigned long long) nbc->dc.disk_size); 956 (unsigned long long) nbc->dc.disk_size);
984 retcode = ERR_DISK_TO_SMALL; 957 retcode = ERR_DISK_TO_SMALL;
985 goto release_bdev2_fail; 958 goto fail;
986 } 959 }
987 960
988 if (nbc->dc.meta_dev_idx < 0) { 961 if (nbc->dc.meta_dev_idx < 0) {
@@ -999,7 +972,7 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp
999 dev_warn(DEV, "refusing attach: md-device too small, " 972 dev_warn(DEV, "refusing attach: md-device too small, "
1000 "at least %llu sectors needed for this meta-disk type\n", 973 "at least %llu sectors needed for this meta-disk type\n",
1001 (unsigned long long) min_md_device_sectors); 974 (unsigned long long) min_md_device_sectors);
1002 goto release_bdev2_fail; 975 goto fail;
1003 } 976 }
1004 977
1005 /* Make sure the new disk is big enough 978 /* Make sure the new disk is big enough
@@ -1007,7 +980,7 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp
1007 if (drbd_get_max_capacity(nbc) < 980 if (drbd_get_max_capacity(nbc) <
1008 drbd_get_capacity(mdev->this_bdev)) { 981 drbd_get_capacity(mdev->this_bdev)) {
1009 retcode = ERR_DISK_TO_SMALL; 982 retcode = ERR_DISK_TO_SMALL;
1010 goto release_bdev2_fail; 983 goto fail;
1011 } 984 }
1012 985
1013 nbc->known_size = drbd_get_capacity(nbc->backing_bdev); 986 nbc->known_size = drbd_get_capacity(nbc->backing_bdev);
@@ -1030,7 +1003,7 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp
1030 retcode = _drbd_request_state(mdev, NS(disk, D_ATTACHING), CS_VERBOSE); 1003 retcode = _drbd_request_state(mdev, NS(disk, D_ATTACHING), CS_VERBOSE);
1031 drbd_resume_io(mdev); 1004 drbd_resume_io(mdev);
1032 if (retcode < SS_SUCCESS) 1005 if (retcode < SS_SUCCESS)
1033 goto release_bdev2_fail; 1006 goto fail;
1034 1007
1035 if (!get_ldev_if_state(mdev, D_ATTACHING)) 1008 if (!get_ldev_if_state(mdev, D_ATTACHING))
1036 goto force_diskless; 1009 goto force_diskless;
@@ -1264,18 +1237,14 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp
1264 force_diskless: 1237 force_diskless:
1265 drbd_force_state(mdev, NS(disk, D_DISKLESS)); 1238 drbd_force_state(mdev, NS(disk, D_DISKLESS));
1266 drbd_md_sync(mdev); 1239 drbd_md_sync(mdev);
1267 release_bdev2_fail:
1268 if (nbc)
1269 bd_release(nbc->md_bdev);
1270 release_bdev_fail:
1271 if (nbc)
1272 bd_release(nbc->backing_bdev);
1273 fail: 1240 fail:
1274 if (nbc) { 1241 if (nbc) {
1275 if (nbc->lo_file) 1242 if (nbc->backing_bdev)
1276 fput(nbc->lo_file); 1243 blkdev_put(nbc->backing_bdev,
1277 if (nbc->md_file) 1244 FMODE_READ | FMODE_WRITE | FMODE_EXCL);
1278 fput(nbc->md_file); 1245 if (nbc->md_bdev)
1246 blkdev_put(nbc->md_bdev,
1247 FMODE_READ | FMODE_WRITE | FMODE_EXCL);
1279 kfree(nbc); 1248 kfree(nbc);
1280 } 1249 }
1281 lc_destroy(resync_lru); 1250 lc_destroy(resync_lru);
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c
index 19b3568e9326..77d70eebb6b2 100644
--- a/drivers/block/pktcdvd.c
+++ b/drivers/block/pktcdvd.c
@@ -2296,15 +2296,12 @@ static int pkt_open_dev(struct pktcdvd_device *pd, fmode_t write)
2296 * so bdget() can't fail. 2296 * so bdget() can't fail.
2297 */ 2297 */
2298 bdget(pd->bdev->bd_dev); 2298 bdget(pd->bdev->bd_dev);
2299 if ((ret = blkdev_get(pd->bdev, FMODE_READ))) 2299 if ((ret = blkdev_get(pd->bdev, FMODE_READ | FMODE_EXCL, pd)))
2300 goto out; 2300 goto out;
2301 2301
2302 if ((ret = bd_claim(pd->bdev, pd)))
2303 goto out_putdev;
2304
2305 if ((ret = pkt_get_last_written(pd, &lba))) { 2302 if ((ret = pkt_get_last_written(pd, &lba))) {
2306 printk(DRIVER_NAME": pkt_get_last_written failed\n"); 2303 printk(DRIVER_NAME": pkt_get_last_written failed\n");
2307 goto out_unclaim; 2304 goto out_putdev;
2308 } 2305 }
2309 2306
2310 set_capacity(pd->disk, lba << 2); 2307 set_capacity(pd->disk, lba << 2);
@@ -2314,7 +2311,7 @@ static int pkt_open_dev(struct pktcdvd_device *pd, fmode_t write)
2314 q = bdev_get_queue(pd->bdev); 2311 q = bdev_get_queue(pd->bdev);
2315 if (write) { 2312 if (write) {
2316 if ((ret = pkt_open_write(pd))) 2313 if ((ret = pkt_open_write(pd)))
2317 goto out_unclaim; 2314 goto out_putdev;
2318 /* 2315 /*
2319 * Some CDRW drives can not handle writes larger than one packet, 2316 * Some CDRW drives can not handle writes larger than one packet,
2320 * even if the size is a multiple of the packet size. 2317 * even if the size is a multiple of the packet size.
@@ -2329,23 +2326,21 @@ static int pkt_open_dev(struct pktcdvd_device *pd, fmode_t write)
2329 } 2326 }
2330 2327
2331 if ((ret = pkt_set_segment_merging(pd, q))) 2328 if ((ret = pkt_set_segment_merging(pd, q)))
2332 goto out_unclaim; 2329 goto out_putdev;
2333 2330
2334 if (write) { 2331 if (write) {
2335 if (!pkt_grow_pktlist(pd, CONFIG_CDROM_PKTCDVD_BUFFERS)) { 2332 if (!pkt_grow_pktlist(pd, CONFIG_CDROM_PKTCDVD_BUFFERS)) {
2336 printk(DRIVER_NAME": not enough memory for buffers\n"); 2333 printk(DRIVER_NAME": not enough memory for buffers\n");
2337 ret = -ENOMEM; 2334 ret = -ENOMEM;
2338 goto out_unclaim; 2335 goto out_putdev;
2339 } 2336 }
2340 printk(DRIVER_NAME": %lukB available on disc\n", lba << 1); 2337 printk(DRIVER_NAME": %lukB available on disc\n", lba << 1);
2341 } 2338 }
2342 2339
2343 return 0; 2340 return 0;
2344 2341
2345out_unclaim:
2346 bd_release(pd->bdev);
2347out_putdev: 2342out_putdev:
2348 blkdev_put(pd->bdev, FMODE_READ); 2343 blkdev_put(pd->bdev, FMODE_READ | FMODE_EXCL);
2349out: 2344out:
2350 return ret; 2345 return ret;
2351} 2346}
@@ -2362,8 +2357,7 @@ static void pkt_release_dev(struct pktcdvd_device *pd, int flush)
2362 pkt_lock_door(pd, 0); 2357 pkt_lock_door(pd, 0);
2363 2358
2364 pkt_set_speed(pd, MAX_SPEED, MAX_SPEED); 2359 pkt_set_speed(pd, MAX_SPEED, MAX_SPEED);
2365 bd_release(pd->bdev); 2360 blkdev_put(pd->bdev, FMODE_READ | FMODE_EXCL);
2366 blkdev_put(pd->bdev, FMODE_READ);
2367 2361
2368 pkt_shrink_pktlist(pd); 2362 pkt_shrink_pktlist(pd);
2369} 2363}
@@ -2733,7 +2727,7 @@ static int pkt_new_dev(struct pktcdvd_device *pd, dev_t dev)
2733 bdev = bdget(dev); 2727 bdev = bdget(dev);
2734 if (!bdev) 2728 if (!bdev)
2735 return -ENOMEM; 2729 return -ENOMEM;
2736 ret = blkdev_get(bdev, FMODE_READ | FMODE_NDELAY); 2730 ret = blkdev_get(bdev, FMODE_READ | FMODE_NDELAY, NULL);
2737 if (ret) 2731 if (ret)
2738 return ret; 2732 return ret;
2739 2733
diff --git a/drivers/char/raw.c b/drivers/char/raw.c
index bfe25ea9766b..b4b9d5a47885 100644
--- a/drivers/char/raw.c
+++ b/drivers/char/raw.c
@@ -65,15 +65,12 @@ static int raw_open(struct inode *inode, struct file *filp)
65 if (!bdev) 65 if (!bdev)
66 goto out; 66 goto out;
67 igrab(bdev->bd_inode); 67 igrab(bdev->bd_inode);
68 err = blkdev_get(bdev, filp->f_mode); 68 err = blkdev_get(bdev, filp->f_mode | FMODE_EXCL, raw_open);
69 if (err) 69 if (err)
70 goto out; 70 goto out;
71 err = bd_claim(bdev, raw_open);
72 if (err)
73 goto out1;
74 err = set_blocksize(bdev, bdev_logical_block_size(bdev)); 71 err = set_blocksize(bdev, bdev_logical_block_size(bdev));
75 if (err) 72 if (err)
76 goto out2; 73 goto out1;
77 filp->f_flags |= O_DIRECT; 74 filp->f_flags |= O_DIRECT;
78 filp->f_mapping = bdev->bd_inode->i_mapping; 75 filp->f_mapping = bdev->bd_inode->i_mapping;
79 if (++raw_devices[minor].inuse == 1) 76 if (++raw_devices[minor].inuse == 1)
@@ -83,10 +80,8 @@ static int raw_open(struct inode *inode, struct file *filp)
83 mutex_unlock(&raw_mutex); 80 mutex_unlock(&raw_mutex);
84 return 0; 81 return 0;
85 82
86out2:
87 bd_release(bdev);
88out1: 83out1:
89 blkdev_put(bdev, filp->f_mode); 84 blkdev_put(bdev, filp->f_mode | FMODE_EXCL);
90out: 85out:
91 mutex_unlock(&raw_mutex); 86 mutex_unlock(&raw_mutex);
92 return err; 87 return err;
@@ -110,8 +105,7 @@ static int raw_release(struct inode *inode, struct file *filp)
110 } 105 }
111 mutex_unlock(&raw_mutex); 106 mutex_unlock(&raw_mutex);
112 107
113 bd_release(bdev); 108 blkdev_put(bdev, filp->f_mode | FMODE_EXCL);
114 blkdev_put(bdev, filp->f_mode);
115 return 0; 109 return 0;
116} 110}
117 111
diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c
index 2c876ffc63df..9e88ca0c55e9 100644
--- a/drivers/md/dm-table.c
+++ b/drivers/md/dm-table.c
@@ -325,20 +325,13 @@ static int open_dev(struct dm_dev_internal *d, dev_t dev,
325 325
326 BUG_ON(d->dm_dev.bdev); 326 BUG_ON(d->dm_dev.bdev);
327 327
328 bdev = open_by_devnum(dev, d->dm_dev.mode); 328 bdev = open_by_devnum(dev, d->dm_dev.mode | FMODE_EXCL, _claim_ptr);
329 if (IS_ERR(bdev)) 329 if (IS_ERR(bdev))
330 return PTR_ERR(bdev); 330 return PTR_ERR(bdev);
331 331
332 r = bd_claim(bdev, _claim_ptr);
333 if (r) {
334 blkdev_put(bdev, d->dm_dev.mode);
335 return r;
336 }
337
338 r = bd_link_disk_holder(bdev, dm_disk(md)); 332 r = bd_link_disk_holder(bdev, dm_disk(md));
339 if (r) { 333 if (r) {
340 bd_release(bdev); 334 blkdev_put(bdev, d->dm_dev.mode | FMODE_EXCL);
341 blkdev_put(bdev, d->dm_dev.mode);
342 return r; 335 return r;
343 } 336 }
344 337
@@ -354,9 +347,7 @@ static void close_dev(struct dm_dev_internal *d, struct mapped_device *md)
354 if (!d->dm_dev.bdev) 347 if (!d->dm_dev.bdev)
355 return; 348 return;
356 349
357 bd_unlink_disk_holder(d->dm_dev.bdev); 350 blkdev_put(d->dm_dev.bdev, d->dm_dev.mode | FMODE_EXCL);
358 bd_release(d->dm_dev.bdev);
359 blkdev_put(d->dm_dev.bdev, d->dm_dev.mode);
360 d->dm_dev.bdev = NULL; 351 d->dm_dev.bdev = NULL;
361} 352}
362 353
diff --git a/drivers/md/md.c b/drivers/md/md.c
index c47644fca1a1..6af951ffe0bb 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -1907,7 +1907,6 @@ static void unbind_rdev_from_array(mdk_rdev_t * rdev)
1907 MD_BUG(); 1907 MD_BUG();
1908 return; 1908 return;
1909 } 1909 }
1910 bd_unlink_disk_holder(rdev->bdev);
1911 list_del_rcu(&rdev->same_set); 1910 list_del_rcu(&rdev->same_set);
1912 printk(KERN_INFO "md: unbind<%s>\n", bdevname(rdev->bdev,b)); 1911 printk(KERN_INFO "md: unbind<%s>\n", bdevname(rdev->bdev,b));
1913 rdev->mddev = NULL; 1912 rdev->mddev = NULL;
@@ -1935,19 +1934,13 @@ static int lock_rdev(mdk_rdev_t *rdev, dev_t dev, int shared)
1935 struct block_device *bdev; 1934 struct block_device *bdev;
1936 char b[BDEVNAME_SIZE]; 1935 char b[BDEVNAME_SIZE];
1937 1936
1938 bdev = open_by_devnum(dev, FMODE_READ|FMODE_WRITE); 1937 bdev = open_by_devnum(dev, FMODE_READ|FMODE_WRITE|FMODE_EXCL,
1938 shared ? (mdk_rdev_t *)lock_rdev : rdev);
1939 if (IS_ERR(bdev)) { 1939 if (IS_ERR(bdev)) {
1940 printk(KERN_ERR "md: could not open %s.\n", 1940 printk(KERN_ERR "md: could not open %s.\n",
1941 __bdevname(dev, b)); 1941 __bdevname(dev, b));
1942 return PTR_ERR(bdev); 1942 return PTR_ERR(bdev);
1943 } 1943 }
1944 err = bd_claim(bdev, shared ? (mdk_rdev_t *)lock_rdev : rdev);
1945 if (err) {
1946 printk(KERN_ERR "md: could not bd_claim %s.\n",
1947 bdevname(bdev, b));
1948 blkdev_put(bdev, FMODE_READ|FMODE_WRITE);
1949 return err;
1950 }
1951 if (!shared) 1944 if (!shared)
1952 set_bit(AllReserved, &rdev->flags); 1945 set_bit(AllReserved, &rdev->flags);
1953 rdev->bdev = bdev; 1946 rdev->bdev = bdev;
@@ -1960,8 +1953,7 @@ static void unlock_rdev(mdk_rdev_t *rdev)
1960 rdev->bdev = NULL; 1953 rdev->bdev = NULL;
1961 if (!bdev) 1954 if (!bdev)
1962 MD_BUG(); 1955 MD_BUG();
1963 bd_release(bdev); 1956 blkdev_put(bdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL);
1964 blkdev_put(bdev, FMODE_READ|FMODE_WRITE);
1965} 1957}
1966 1958
1967void md_autodetect_dev(dev_t dev); 1959void md_autodetect_dev(dev_t dev);
diff --git a/drivers/mtd/devices/block2mtd.c b/drivers/mtd/devices/block2mtd.c
index a9e2d3b38aeb..aa557beb8f51 100644
--- a/drivers/mtd/devices/block2mtd.c
+++ b/drivers/mtd/devices/block2mtd.c
@@ -224,7 +224,7 @@ static void block2mtd_free_device(struct block2mtd_dev *dev)
224 if (dev->blkdev) { 224 if (dev->blkdev) {
225 invalidate_mapping_pages(dev->blkdev->bd_inode->i_mapping, 225 invalidate_mapping_pages(dev->blkdev->bd_inode->i_mapping,
226 0, -1); 226 0, -1);
227 close_bdev_exclusive(dev->blkdev, FMODE_READ|FMODE_WRITE); 227 blkdev_put(dev->blkdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL);
228 } 228 }
229 229
230 kfree(dev); 230 kfree(dev);
@@ -234,7 +234,7 @@ static void block2mtd_free_device(struct block2mtd_dev *dev)
234/* FIXME: ensure that mtd->size % erase_size == 0 */ 234/* FIXME: ensure that mtd->size % erase_size == 0 */
235static struct block2mtd_dev *add_device(char *devname, int erase_size) 235static struct block2mtd_dev *add_device(char *devname, int erase_size)
236{ 236{
237 const fmode_t mode = FMODE_READ | FMODE_WRITE; 237 const fmode_t mode = FMODE_READ | FMODE_WRITE | FMODE_EXCL;
238 struct block_device *bdev; 238 struct block_device *bdev;
239 struct block2mtd_dev *dev; 239 struct block2mtd_dev *dev;
240 char *name; 240 char *name;
@@ -255,17 +255,8 @@ static struct block2mtd_dev *add_device(char *devname, int erase_size)
255 to resolve the device name by other means. */ 255 to resolve the device name by other means. */
256 256
257 dev_t devt = name_to_dev_t(devname); 257 dev_t devt = name_to_dev_t(devname);
258 if (devt) { 258 if (devt)
259 bdev = open_by_devnum(devt, mode); 259 bdev = open_by_devnum(devt, mode, dev);
260 if (!IS_ERR(bdev)) {
261 int ret;
262 ret = bd_claim(bdev, dev);
263 if (ret) {
264 blkdev_put(bdev, mode);
265 bdev = ERR_PTR(ret);
266 }
267 }
268 }
269 } 260 }
270#endif 261#endif
271 262
diff --git a/drivers/s390/block/dasd_genhd.c b/drivers/s390/block/dasd_genhd.c
index 30a1ca3d08b7..5505bc07e1e7 100644
--- a/drivers/s390/block/dasd_genhd.c
+++ b/drivers/s390/block/dasd_genhd.c
@@ -103,7 +103,7 @@ int dasd_scan_partitions(struct dasd_block *block)
103 struct block_device *bdev; 103 struct block_device *bdev;
104 104
105 bdev = bdget_disk(block->gdp, 0); 105 bdev = bdget_disk(block->gdp, 0);
106 if (!bdev || blkdev_get(bdev, FMODE_READ) < 0) 106 if (!bdev || blkdev_get(bdev, FMODE_READ, NULL) < 0)
107 return -ENODEV; 107 return -ENODEV;
108 /* 108 /*
109 * See fs/partition/check.c:register_disk,rescan_partitions 109 * See fs/partition/check.c:register_disk,rescan_partitions
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/*
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 66b7f2c5d7e9..1a033e8ebe4c 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -2006,7 +2006,8 @@ extern struct block_device *bdgrab(struct block_device *bdev);
2006extern void bd_set_size(struct block_device *, loff_t size); 2006extern void bd_set_size(struct block_device *, loff_t size);
2007extern void bd_forget(struct inode *inode); 2007extern void bd_forget(struct inode *inode);
2008extern void bdput(struct block_device *); 2008extern void bdput(struct block_device *);
2009extern struct block_device *open_by_devnum(dev_t, fmode_t); 2009extern struct block_device *open_by_devnum(dev_t dev, fmode_t mode,
2010 void *holder);
2010extern void invalidate_bdev(struct block_device *); 2011extern void invalidate_bdev(struct block_device *);
2011extern int sync_blockdev(struct block_device *bdev); 2012extern int sync_blockdev(struct block_device *bdev);
2012extern struct super_block *freeze_bdev(struct block_device *); 2013extern struct super_block *freeze_bdev(struct block_device *);
@@ -2037,22 +2038,16 @@ extern const struct file_operations def_fifo_fops;
2037extern int ioctl_by_bdev(struct block_device *, unsigned, unsigned long); 2038extern int ioctl_by_bdev(struct block_device *, unsigned, unsigned long);
2038extern int blkdev_ioctl(struct block_device *, fmode_t, unsigned, unsigned long); 2039extern int blkdev_ioctl(struct block_device *, fmode_t, unsigned, unsigned long);
2039extern long compat_blkdev_ioctl(struct file *, unsigned, unsigned long); 2040extern long compat_blkdev_ioctl(struct file *, unsigned, unsigned long);
2040extern int blkdev_get(struct block_device *, fmode_t); 2041extern int blkdev_get(struct block_device *bdev, fmode_t mode, void *holder);
2041extern int blkdev_put(struct block_device *, fmode_t); 2042extern int blkdev_put(struct block_device *bdev, fmode_t mode);
2042extern int bd_claim(struct block_device *, void *);
2043extern void bd_release(struct block_device *);
2044#ifdef CONFIG_SYSFS 2043#ifdef CONFIG_SYSFS
2045extern int bd_link_disk_holder(struct block_device *bdev, struct gendisk *disk); 2044extern int bd_link_disk_holder(struct block_device *bdev, struct gendisk *disk);
2046extern void bd_unlink_disk_holder(struct block_device *bdev);
2047#else 2045#else
2048static inline int bd_link_disk_holder(struct block_device *bdev, 2046static inline int bd_link_disk_holder(struct block_device *bdev,
2049 struct gendisk *disk) 2047 struct gendisk *disk)
2050{ 2048{
2051 return 0; 2049 return 0;
2052} 2050}
2053static inline void bd_unlink_disk_holder(struct block_device *bdev)
2054{
2055}
2056#endif 2051#endif
2057#endif 2052#endif
2058 2053
@@ -2089,7 +2084,6 @@ extern const char *__bdevname(dev_t, char *buffer);
2089extern const char *bdevname(struct block_device *bdev, char *buffer); 2084extern const char *bdevname(struct block_device *bdev, char *buffer);
2090extern struct block_device *lookup_bdev(const char *); 2085extern struct block_device *lookup_bdev(const char *);
2091extern struct block_device *open_bdev_exclusive(const char *, fmode_t, void *); 2086extern struct block_device *open_bdev_exclusive(const char *, fmode_t, void *);
2092extern void close_bdev_exclusive(struct block_device *, fmode_t);
2093extern void blkdev_show(struct seq_file *,off_t); 2087extern void blkdev_show(struct seq_file *,off_t);
2094 2088
2095#else 2089#else
diff --git a/kernel/power/swap.c b/kernel/power/swap.c
index a0e4a86ccf94..513a77f1a0b3 100644
--- a/kernel/power/swap.c
+++ b/kernel/power/swap.c
@@ -223,7 +223,7 @@ static int swsusp_swap_check(void)
223 return res; 223 return res;
224 224
225 root_swap = res; 225 root_swap = res;
226 res = blkdev_get(hib_resume_bdev, FMODE_WRITE); 226 res = blkdev_get(hib_resume_bdev, FMODE_WRITE, NULL);
227 if (res) 227 if (res)
228 return res; 228 return res;
229 229
@@ -907,7 +907,8 @@ int swsusp_check(void)
907{ 907{
908 int error; 908 int error;
909 909
910 hib_resume_bdev = open_by_devnum(swsusp_resume_device, FMODE_READ); 910 hib_resume_bdev = open_by_devnum(swsusp_resume_device,
911 FMODE_READ, NULL);
911 if (!IS_ERR(hib_resume_bdev)) { 912 if (!IS_ERR(hib_resume_bdev)) {
912 set_blocksize(hib_resume_bdev, PAGE_SIZE); 913 set_blocksize(hib_resume_bdev, PAGE_SIZE);
913 clear_page(swsusp_header); 914 clear_page(swsusp_header);
diff --git a/mm/swapfile.c b/mm/swapfile.c
index 67ddaaf98c74..b6adcfbf6f48 100644
--- a/mm/swapfile.c
+++ b/mm/swapfile.c
@@ -1677,7 +1677,7 @@ SYSCALL_DEFINE1(swapoff, const char __user *, specialfile)
1677 if (S_ISBLK(inode->i_mode)) { 1677 if (S_ISBLK(inode->i_mode)) {
1678 struct block_device *bdev = I_BDEV(inode); 1678 struct block_device *bdev = I_BDEV(inode);
1679 set_blocksize(bdev, p->old_block_size); 1679 set_blocksize(bdev, p->old_block_size);
1680 bd_release(bdev); 1680 blkdev_put(bdev, FMODE_READ | FMODE_WRITE | FMODE_EXCL);
1681 } else { 1681 } else {
1682 mutex_lock(&inode->i_mutex); 1682 mutex_lock(&inode->i_mutex);
1683 inode->i_flags &= ~S_SWAPFILE; 1683 inode->i_flags &= ~S_SWAPFILE;
@@ -1939,7 +1939,8 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags)
1939 error = -EINVAL; 1939 error = -EINVAL;
1940 if (S_ISBLK(inode->i_mode)) { 1940 if (S_ISBLK(inode->i_mode)) {
1941 bdev = I_BDEV(inode); 1941 bdev = I_BDEV(inode);
1942 error = bd_claim(bdev, sys_swapon); 1942 error = blkdev_get(bdev, FMODE_READ | FMODE_WRITE | FMODE_EXCL,
1943 sys_swapon);
1943 if (error < 0) { 1944 if (error < 0) {
1944 bdev = NULL; 1945 bdev = NULL;
1945 error = -EINVAL; 1946 error = -EINVAL;
@@ -2136,7 +2137,7 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags)
2136bad_swap: 2137bad_swap:
2137 if (bdev) { 2138 if (bdev) {
2138 set_blocksize(bdev, p->old_block_size); 2139 set_blocksize(bdev, p->old_block_size);
2139 bd_release(bdev); 2140 blkdev_put(bdev, FMODE_READ | FMODE_WRITE | FMODE_EXCL);
2140 } 2141 }
2141 destroy_swap_extents(p); 2142 destroy_swap_extents(p);
2142 swap_cgroup_swapoff(type); 2143 swap_cgroup_swapoff(type);