Commit e525fd89d380c4a94c0d63913a1dd1a593ed25e7

Authored by Tejun Heo
1 parent e09b457bdb

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>

Showing 26 changed files with 162 additions and 318 deletions Side-by-side Diff

... ... @@ -294,11 +294,12 @@
294 294 return -EINVAL;
295 295 if (get_user(n, (int __user *) arg))
296 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 299 return -EBUSY;
299 300 ret = set_blocksize(bdev, n);
300 301 if (!(mode & FMODE_EXCL))
301   - bd_release(bdev);
  302 + blkdev_put(bdev, mode | FMODE_EXCL);
302 303 return ret;
303 304 case BLKPG:
304 305 ret = blkpg_ioctl(bdev, (struct blkpg_ioctl_arg __user *) arg);
drivers/block/drbd/drbd_int.h
... ... @@ -923,8 +923,6 @@
923 923 struct drbd_backing_dev {
924 924 struct block_device *backing_bdev;
925 925 struct block_device *md_bdev;
926   - struct file *lo_file;
927   - struct file *md_file;
928 926 struct drbd_md md;
929 927 struct disk_conf dc; /* The user provided config... */
930 928 sector_t known_size; /* last known size of that backing device */
drivers/block/drbd/drbd_main.c
... ... @@ -3361,11 +3361,8 @@
3361 3361 if (ldev == NULL)
3362 3362 return;
3363 3363  
3364   - bd_release(ldev->backing_bdev);
3365   - bd_release(ldev->md_bdev);
3366   -
3367   - fput(ldev->lo_file);
3368   - fput(ldev->md_file);
  3364 + blkdev_put(ldev->backing_bdev, FMODE_READ | FMODE_WRITE | FMODE_EXCL);
  3365 + blkdev_put(ldev->md_bdev, FMODE_READ | FMODE_WRITE | FMODE_EXCL);
3369 3366  
3370 3367 kfree(ldev);
3371 3368 }
drivers/block/drbd/drbd_nl.c
... ... @@ -855,7 +855,7 @@
855 855 sector_t max_possible_sectors;
856 856 sector_t min_md_device_sectors;
857 857 struct drbd_backing_dev *nbc = NULL; /* new_backing_conf */
858   - struct inode *inode, *inode2;
  858 + struct block_device *bdev;
859 859 struct lru_cache *resync_lru = NULL;
860 860 union drbd_state ns, os;
861 861 unsigned int max_seg_s;
862 862  
863 863  
864 864  
865 865  
866 866  
867 867  
868 868  
869 869  
870 870  
... ... @@ -902,78 +902,51 @@
902 902 }
903 903 }
904 904  
905   - nbc->lo_file = filp_open(nbc->dc.backing_dev, O_RDWR, 0);
906   - if (IS_ERR(nbc->lo_file)) {
  905 + bdev = open_bdev_exclusive(nbc->dc.backing_dev,
  906 + FMODE_READ | FMODE_WRITE, mdev);
  907 + if (IS_ERR(bdev)) {
907 908 dev_err(DEV, "open(\"%s\") failed with %ld\n", nbc->dc.backing_dev,
908   - PTR_ERR(nbc->lo_file));
909   - nbc->lo_file = NULL;
  909 + PTR_ERR(bdev));
910 910 retcode = ERR_OPEN_DISK;
911 911 goto fail;
912 912 }
  913 + nbc->backing_bdev = bdev;
913 914  
914   - inode = nbc->lo_file->f_dentry->d_inode;
915   -
916   - if (!S_ISBLK(inode->i_mode)) {
917   - retcode = ERR_DISK_NOT_BDEV;
918   - goto fail;
919   - }
920   -
921   - nbc->md_file = filp_open(nbc->dc.meta_dev, O_RDWR, 0);
922   - if (IS_ERR(nbc->md_file)) {
  915 + /*
  916 + * meta_dev_idx >= 0: external fixed size, possibly multiple
  917 + * drbd sharing one meta device. TODO in that case, paranoia
  918 + * check that [md_bdev, meta_dev_idx] is not yet used by some
  919 + * other drbd minor! (if you use drbd.conf + drbdadm, that
  920 + * should check it for you already; but if you don't, or
  921 + * someone fooled it, we need to double check here)
  922 + */
  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 928 dev_err(DEV, "open(\"%s\") failed with %ld\n", nbc->dc.meta_dev,
924   - PTR_ERR(nbc->md_file));
925   - nbc->md_file = NULL;
  929 + PTR_ERR(bdev));
926 930 retcode = ERR_OPEN_MD_DISK;
927 931 goto fail;
928 932 }
  933 + nbc->md_bdev = bdev;
929 934  
930   - inode2 = nbc->md_file->f_dentry->d_inode;
931   -
932   - if (!S_ISBLK(inode2->i_mode)) {
933   - retcode = ERR_MD_NOT_BDEV;
  935 + if ((nbc->backing_bdev == nbc->md_bdev) !=
  936 + (nbc->dc.meta_dev_idx == DRBD_MD_INDEX_INTERNAL ||
  937 + nbc->dc.meta_dev_idx == DRBD_MD_INDEX_FLEX_INT)) {
  938 + retcode = ERR_MD_IDX_INVALID;
934 939 goto fail;
935 940 }
936 941  
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;
946   - }
947   -
948 942 resync_lru = lc_create("resync", drbd_bm_ext_cache,
949 943 61, sizeof(struct bm_extent),
950 944 offsetof(struct bm_extent, lce));
951 945 if (!resync_lru) {
952 946 retcode = ERR_NOMEM;
953   - goto release_bdev_fail;
  947 + goto fail;
954 948 }
955 949  
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   - }
976   -
977 950 /* RT - for drbd_get_max_capacity() DRBD_MD_INDEX_FLEX_INT */
978 951 drbd_md_set_sector_offsets(mdev, nbc);
979 952  
... ... @@ -982,7 +955,7 @@
982 955 (unsigned long long) drbd_get_max_capacity(nbc),
983 956 (unsigned long long) nbc->dc.disk_size);
984 957 retcode = ERR_DISK_TO_SMALL;
985   - goto release_bdev2_fail;
  958 + goto fail;
986 959 }
987 960  
988 961 if (nbc->dc.meta_dev_idx < 0) {
... ... @@ -999,7 +972,7 @@
999 972 dev_warn(DEV, "refusing attach: md-device too small, "
1000 973 "at least %llu sectors needed for this meta-disk type\n",
1001 974 (unsigned long long) min_md_device_sectors);
1002   - goto release_bdev2_fail;
  975 + goto fail;
1003 976 }
1004 977  
1005 978 /* Make sure the new disk is big enough
... ... @@ -1007,7 +980,7 @@
1007 980 if (drbd_get_max_capacity(nbc) <
1008 981 drbd_get_capacity(mdev->this_bdev)) {
1009 982 retcode = ERR_DISK_TO_SMALL;
1010   - goto release_bdev2_fail;
  983 + goto fail;
1011 984 }
1012 985  
1013 986 nbc->known_size = drbd_get_capacity(nbc->backing_bdev);
... ... @@ -1030,7 +1003,7 @@
1030 1003 retcode = _drbd_request_state(mdev, NS(disk, D_ATTACHING), CS_VERBOSE);
1031 1004 drbd_resume_io(mdev);
1032 1005 if (retcode < SS_SUCCESS)
1033   - goto release_bdev2_fail;
  1006 + goto fail;
1034 1007  
1035 1008 if (!get_ldev_if_state(mdev, D_ATTACHING))
1036 1009 goto force_diskless;
1037 1010  
... ... @@ -1264,18 +1237,14 @@
1264 1237 force_diskless:
1265 1238 drbd_force_state(mdev, NS(disk, D_DISKLESS));
1266 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 1240 fail:
1274 1241 if (nbc) {
1275   - if (nbc->lo_file)
1276   - fput(nbc->lo_file);
1277   - if (nbc->md_file)
1278   - fput(nbc->md_file);
  1242 + if (nbc->backing_bdev)
  1243 + blkdev_put(nbc->backing_bdev,
  1244 + FMODE_READ | FMODE_WRITE | FMODE_EXCL);
  1245 + if (nbc->md_bdev)
  1246 + blkdev_put(nbc->md_bdev,
  1247 + FMODE_READ | FMODE_WRITE | FMODE_EXCL);
1279 1248 kfree(nbc);
1280 1249 }
1281 1250 lc_destroy(resync_lru);
drivers/block/pktcdvd.c
... ... @@ -2296,15 +2296,12 @@
2296 2296 * so bdget() can't fail.
2297 2297 */
2298 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 2300 goto out;
2301 2301  
2302   - if ((ret = bd_claim(pd->bdev, pd)))
2303   - goto out_putdev;
2304   -
2305 2302 if ((ret = pkt_get_last_written(pd, &lba))) {
2306 2303 printk(DRIVER_NAME": pkt_get_last_written failed\n");
2307   - goto out_unclaim;
  2304 + goto out_putdev;
2308 2305 }
2309 2306  
2310 2307 set_capacity(pd->disk, lba << 2);
... ... @@ -2314,7 +2311,7 @@
2314 2311 q = bdev_get_queue(pd->bdev);
2315 2312 if (write) {
2316 2313 if ((ret = pkt_open_write(pd)))
2317   - goto out_unclaim;
  2314 + goto out_putdev;
2318 2315 /*
2319 2316 * Some CDRW drives can not handle writes larger than one packet,
2320 2317 * even if the size is a multiple of the packet size.
2321 2318  
2322 2319  
2323 2320  
... ... @@ -2329,23 +2326,21 @@
2329 2326 }
2330 2327  
2331 2328 if ((ret = pkt_set_segment_merging(pd, q)))
2332   - goto out_unclaim;
  2329 + goto out_putdev;
2333 2330  
2334 2331 if (write) {
2335 2332 if (!pkt_grow_pktlist(pd, CONFIG_CDROM_PKTCDVD_BUFFERS)) {
2336 2333 printk(DRIVER_NAME": not enough memory for buffers\n");
2337 2334 ret = -ENOMEM;
2338   - goto out_unclaim;
  2335 + goto out_putdev;
2339 2336 }
2340 2337 printk(DRIVER_NAME": %lukB available on disc\n", lba << 1);
2341 2338 }
2342 2339  
2343 2340 return 0;
2344 2341  
2345   -out_unclaim:
2346   - bd_release(pd->bdev);
2347 2342 out_putdev:
2348   - blkdev_put(pd->bdev, FMODE_READ);
  2343 + blkdev_put(pd->bdev, FMODE_READ | FMODE_EXCL);
2349 2344 out:
2350 2345 return ret;
2351 2346 }
... ... @@ -2362,8 +2357,7 @@
2362 2357 pkt_lock_door(pd, 0);
2363 2358  
2364 2359 pkt_set_speed(pd, MAX_SPEED, MAX_SPEED);
2365   - bd_release(pd->bdev);
2366   - blkdev_put(pd->bdev, FMODE_READ);
  2360 + blkdev_put(pd->bdev, FMODE_READ | FMODE_EXCL);
2367 2361  
2368 2362 pkt_shrink_pktlist(pd);
2369 2363 }
... ... @@ -2733,7 +2727,7 @@
2733 2727 bdev = bdget(dev);
2734 2728 if (!bdev)
2735 2729 return -ENOMEM;
2736   - ret = blkdev_get(bdev, FMODE_READ | FMODE_NDELAY);
  2730 + ret = blkdev_get(bdev, FMODE_READ | FMODE_NDELAY, NULL);
2737 2731 if (ret)
2738 2732 return ret;
2739 2733  
... ... @@ -65,15 +65,12 @@
65 65 if (!bdev)
66 66 goto out;
67 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 69 if (err)
70 70 goto out;
71   - err = bd_claim(bdev, raw_open);
72   - if (err)
73   - goto out1;
74 71 err = set_blocksize(bdev, bdev_logical_block_size(bdev));
75 72 if (err)
76   - goto out2;
  73 + goto out1;
77 74 filp->f_flags |= O_DIRECT;
78 75 filp->f_mapping = bdev->bd_inode->i_mapping;
79 76 if (++raw_devices[minor].inuse == 1)
80 77  
... ... @@ -83,10 +80,8 @@
83 80 mutex_unlock(&raw_mutex);
84 81 return 0;
85 82  
86   -out2:
87   - bd_release(bdev);
88 83 out1:
89   - blkdev_put(bdev, filp->f_mode);
  84 + blkdev_put(bdev, filp->f_mode | FMODE_EXCL);
90 85 out:
91 86 mutex_unlock(&raw_mutex);
92 87 return err;
... ... @@ -110,8 +105,7 @@
110 105 }
111 106 mutex_unlock(&raw_mutex);
112 107  
113   - bd_release(bdev);
114   - blkdev_put(bdev, filp->f_mode);
  108 + blkdev_put(bdev, filp->f_mode | FMODE_EXCL);
115 109 return 0;
116 110 }
117 111  
drivers/md/dm-table.c
... ... @@ -325,20 +325,13 @@
325 325  
326 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 329 if (IS_ERR(bdev))
330 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 332 r = bd_link_disk_holder(bdev, dm_disk(md));
339 333 if (r) {
340   - bd_release(bdev);
341   - blkdev_put(bdev, d->dm_dev.mode);
  334 + blkdev_put(bdev, d->dm_dev.mode | FMODE_EXCL);
342 335 return r;
343 336 }
344 337  
... ... @@ -354,9 +347,7 @@
354 347 if (!d->dm_dev.bdev)
355 348 return;
356 349  
357   - bd_unlink_disk_holder(d->dm_dev.bdev);
358   - bd_release(d->dm_dev.bdev);
359   - blkdev_put(d->dm_dev.bdev, d->dm_dev.mode);
  350 + blkdev_put(d->dm_dev.bdev, d->dm_dev.mode | FMODE_EXCL);
360 351 d->dm_dev.bdev = NULL;
361 352 }
362 353  
... ... @@ -1907,7 +1907,6 @@
1907 1907 MD_BUG();
1908 1908 return;
1909 1909 }
1910   - bd_unlink_disk_holder(rdev->bdev);
1911 1910 list_del_rcu(&rdev->same_set);
1912 1911 printk(KERN_INFO "md: unbind<%s>\n", bdevname(rdev->bdev,b));
1913 1912 rdev->mddev = NULL;
1914 1913  
... ... @@ -1935,19 +1934,13 @@
1935 1934 struct block_device *bdev;
1936 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 1939 if (IS_ERR(bdev)) {
1940 1940 printk(KERN_ERR "md: could not open %s.\n",
1941 1941 __bdevname(dev, b));
1942 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 1944 if (!shared)
1952 1945 set_bit(AllReserved, &rdev->flags);
1953 1946 rdev->bdev = bdev;
... ... @@ -1960,8 +1953,7 @@
1960 1953 rdev->bdev = NULL;
1961 1954 if (!bdev)
1962 1955 MD_BUG();
1963   - bd_release(bdev);
1964   - blkdev_put(bdev, FMODE_READ|FMODE_WRITE);
  1956 + blkdev_put(bdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL);
1965 1957 }
1966 1958  
1967 1959 void md_autodetect_dev(dev_t dev);
drivers/mtd/devices/block2mtd.c
... ... @@ -224,7 +224,7 @@
224 224 if (dev->blkdev) {
225 225 invalidate_mapping_pages(dev->blkdev->bd_inode->i_mapping,
226 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 230 kfree(dev);
... ... @@ -234,7 +234,7 @@
234 234 /* FIXME: ensure that mtd->size % erase_size == 0 */
235 235 static 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 238 struct block_device *bdev;
239 239 struct block2mtd_dev *dev;
240 240 char *name;
... ... @@ -255,17 +255,8 @@
255 255 to resolve the device name by other means. */
256 256  
257 257 dev_t devt = name_to_dev_t(devname);
258   - if (devt) {
259   - bdev = open_by_devnum(devt, mode);
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   - }
  258 + if (devt)
  259 + bdev = open_by_devnum(devt, mode, dev);
269 260 }
270 261 #endif
271 262  
drivers/s390/block/dasd_genhd.c
... ... @@ -103,7 +103,7 @@
103 103 struct block_device *bdev;
104 104  
105 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 107 return -ENODEV;
108 108 /*
109 109 * See fs/partition/check.c:register_disk,rescan_partitions
... ... @@ -660,7 +660,7 @@
660 660 else if (bdev->bd_contains == bdev)
661 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 664 return true; /* is a partition of a device that is being partitioned */
665 665 else if (whole->bd_holder != NULL)
666 666 return false; /* is a partition of a held device */
667 667  
... ... @@ -807,10 +807,10 @@
807 807 {
808 808 /* note that for a whole device bd_holders
809 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 812 whole->bd_holders++;
813   - whole->bd_holder = bd_claim;
  813 + whole->bd_holder = bd_may_claim;
814 814 bdev->bd_holders++;
815 815 bdev->bd_holder = holder;
816 816 }
817 817  
818 818  
... ... @@ -835,39 +835,9 @@
835 835 __bd_abort_claiming(whole, holder); /* not actually an abort */
836 836 }
837 837  
838   -/**
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   - */
851   -int bd_claim(struct block_device *bdev, void *holder)
  838 +static void bd_release(struct block_device *bdev)
852 839 {
853   - struct block_device *whole = bdev->bd_contains;
854   - int res;
855   -
856   - might_sleep();
857   -
858 840 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   -}
866   -EXPORT_SYMBOL(bd_claim);
867   -
868   -void bd_release(struct block_device *bdev)
869   -{
870   - spin_lock(&bdev_lock);
871 841 if (!--bdev->bd_contains->bd_holders)
872 842 bdev->bd_contains->bd_holder = NULL;
873 843 if (!--bdev->bd_holders)
... ... @@ -875,8 +845,6 @@
875 845 spin_unlock(&bdev_lock);
876 846 }
877 847  
878   -EXPORT_SYMBOL(bd_release);
879   -
880 848 #ifdef CONFIG_SYSFS
881 849 static int add_symlink(struct kobject *from, struct kobject *to)
882 850 {
... ... @@ -943,7 +911,7 @@
943 911 }
944 912 EXPORT_SYMBOL_GPL(bd_link_disk_holder);
945 913  
946   -void bd_unlink_disk_holder(struct block_device *bdev)
  914 +static void bd_unlink_disk_holder(struct block_device *bdev)
947 915 {
948 916 struct gendisk *disk = bdev->bd_holder_disk;
949 917  
... ... @@ -954,7 +922,9 @@
954 922 del_symlink(disk->slave_dir, &part_to_dev(bdev->bd_part)->kobj);
955 923 del_symlink(bdev->bd_part->holder_dir, &disk_to_dev(disk)->kobj);
956 924 }
957   -EXPORT_SYMBOL_GPL(bd_unlink_disk_holder);
  925 +#else
  926 +static inline void bd_unlink_disk_holder(struct block_device *bdev)
  927 +{ }
958 928 #endif
959 929  
960 930 /*
961 931  
... ... @@ -964,12 +934,12 @@
964 934 * to be used for internal purposes. If you ever need it - reconsider
965 935 * your API.
966 936 */
967   -struct block_device *open_by_devnum(dev_t dev, fmode_t mode)
  937 +struct block_device *open_by_devnum(dev_t dev, fmode_t mode, void *holder)
968 938 {
969 939 struct block_device *bdev = bdget(dev);
970 940 int err = -ENOMEM;
971 941 if (bdev)
972   - err = blkdev_get(bdev, mode);
  942 + err = blkdev_get(bdev, mode, holder);
973 943 return err ? ERR_PTR(err) : bdev;
974 944 }
975 945  
976 946  
977 947  
978 948  
... ... @@ -1235,17 +1205,37 @@
1235 1205 return ret;
1236 1206 }
1237 1207  
1238   -int blkdev_get(struct block_device *bdev, fmode_t mode)
  1208 +int 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 }
1242 1234 EXPORT_SYMBOL(blkdev_get);
1243 1235  
1244 1236 static int blkdev_open(struct inode * inode, struct file * filp)
1245 1237 {
1246   - struct block_device *whole = NULL;
1247 1238 struct block_device *bdev;
1248   - int res;
1249 1239  
1250 1240 /*
1251 1241 * Preserve backwards compatibility and allow large file access
1252 1242  
... ... @@ -1266,26 +1256,9 @@
1266 1256 if (bdev == NULL)
1267 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 1259 filp->f_mapping = bdev->bd_inode->i_mapping;
1278 1260  
1279   - res = blkdev_get(bdev, filp->f_mode);
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;
  1261 + return blkdev_get(bdev, filp->f_mode, filp);
1289 1262 }
1290 1263  
1291 1264 static int __blkdev_put(struct block_device *bdev, fmode_t mode, int for_part)
... ... @@ -1329,6 +1302,13 @@
1329 1302  
1330 1303 int 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 1312 return __blkdev_put(bdev, mode, 0);
1333 1313 }
1334 1314 EXPORT_SYMBOL(blkdev_put);
... ... @@ -1336,8 +1316,7 @@
1336 1316 static int blkdev_close(struct inode * inode, struct file * filp)
1337 1317 {
1338 1318 struct block_device *bdev = I_BDEV(filp->f_mapping->host);
1339   - if (bdev->bd_holder == filp)
1340   - bd_release(bdev);
  1319 +
1341 1320 return blkdev_put(bdev, filp->f_mode);
1342 1321 }
1343 1322  
1344 1323  
1345 1324  
1346 1325  
1347 1326  
1348 1327  
1349 1328  
... ... @@ -1494,54 +1473,26 @@
1494 1473 */
1495 1474 struct 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 1477 int error;
1499 1478  
1500 1479 bdev = lookup_bdev(path);
1501 1480 if (IS_ERR(bdev))
1502 1481 return bdev;
1503 1482  
1504   - whole = bd_start_claiming(bdev, holder);
1505   - if (IS_ERR(whole)) {
1506   - bdput(bdev);
1507   - return whole;
1508   - }
1509   -
1510   - error = blkdev_get(bdev, mode);
  1483 + error = blkdev_get(bdev, mode | FMODE_EXCL, holder);
1511 1484 if (error)
1512   - goto out_abort_claiming;
  1485 + return ERR_PTR(error);
1513 1486  
1514   - error = -EACCES;
1515   - if ((mode & FMODE_WRITE) && bdev_read_only(bdev))
1516   - goto out_blkdev_put;
  1487 + if ((mode & FMODE_WRITE) && bdev_read_only(bdev)) {
  1488 + blkdev_put(bdev, mode);
  1489 + return ERR_PTR(-EACCES);
  1490 + }
1517 1491  
1518   - bd_finish_claiming(bdev, whole, holder);
1519 1492 return bdev;
1520   -
1521   -out_blkdev_put:
1522   - blkdev_put(bdev, mode);
1523   -out_abort_claiming:
1524   - bd_abort_claiming(whole, holder);
1525   - return ERR_PTR(error);
1526 1493 }
1527 1494  
1528 1495 EXPORT_SYMBOL(open_bdev_exclusive);
1529   -
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   - */
1538   -void close_bdev_exclusive(struct block_device *bdev, fmode_t mode)
1539   -{
1540   - bd_release(bdev);
1541   - blkdev_put(bdev, mode);
1542   -}
1543   -
1544   -EXPORT_SYMBOL(close_bdev_exclusive);
1545 1496  
1546 1497 int __invalidate_device(struct block_device *bdev)
1547 1498 {
... ... @@ -489,7 +489,7 @@
489 489 continue;
490 490  
491 491 if (device->bdev) {
492   - close_bdev_exclusive(device->bdev, device->mode);
  492 + blkdev_put(device->bdev, device->mode | FMODE_EXCL);
493 493 device->bdev = NULL;
494 494 fs_devices->open_devices--;
495 495 }
... ... @@ -523,7 +523,7 @@
523 523  
524 524 list_for_each_entry(device, &fs_devices->devices, dev_list) {
525 525 if (device->bdev) {
526   - close_bdev_exclusive(device->bdev, device->mode);
  526 + blkdev_put(device->bdev, device->mode | FMODE_EXCL);
527 527 fs_devices->open_devices--;
528 528 }
529 529 if (device->writeable) {
... ... @@ -638,7 +638,7 @@
638 638 error_brelse:
639 639 brelse(bh);
640 640 error_close:
641   - close_bdev_exclusive(bdev, flags);
  641 + blkdev_put(bdev, flags | FMODE_EXCL);
642 642 error:
643 643 continue;
644 644 }
... ... @@ -716,7 +716,7 @@
716 716  
717 717 brelse(bh);
718 718 error_close:
719   - close_bdev_exclusive(bdev, flags);
  719 + blkdev_put(bdev, flags | FMODE_EXCL);
720 720 error:
721 721 mutex_unlock(&uuid_mutex);
722 722 return ret;
... ... @@ -1244,7 +1244,7 @@
1244 1244 root->fs_info->fs_devices->latest_bdev = next_device->bdev;
1245 1245  
1246 1246 if (device->bdev) {
1247   - close_bdev_exclusive(device->bdev, device->mode);
  1247 + blkdev_put(device->bdev, device->mode | FMODE_EXCL);
1248 1248 device->bdev = NULL;
1249 1249 device->fs_devices->open_devices--;
1250 1250 }
... ... @@ -1287,7 +1287,7 @@
1287 1287 brelse(bh);
1288 1288 error_close:
1289 1289 if (bdev)
1290   - close_bdev_exclusive(bdev, FMODE_READ);
  1290 + blkdev_put(bdev, FMODE_READ | FMODE_EXCL);
1291 1291 out:
1292 1292 mutex_unlock(&root->fs_info->volume_mutex);
1293 1293 mutex_unlock(&uuid_mutex);
... ... @@ -1565,7 +1565,7 @@
1565 1565 mutex_unlock(&root->fs_info->volume_mutex);
1566 1566 return ret;
1567 1567 error:
1568   - close_bdev_exclusive(bdev, 0);
  1568 + blkdev_put(bdev, FMODE_EXCL);
1569 1569 if (seeding_dev) {
1570 1570 mutex_unlock(&uuid_mutex);
1571 1571 up_write(&sb->s_umount);
... ... @@ -347,7 +347,7 @@
347 347 struct block_device *bdev;
348 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 351 if (IS_ERR(bdev))
352 352 goto fail;
353 353 return bdev;
... ... @@ -364,8 +364,7 @@
364 364 */
365 365 static int ext3_blkdev_put(struct block_device *bdev)
366 366 {
367   - bd_release(bdev);
368   - return blkdev_put(bdev, FMODE_READ|FMODE_WRITE);
  367 + return blkdev_put(bdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL);
369 368 }
370 369  
371 370 static int ext3_blkdev_remove(struct ext3_sb_info *sbi)
... ... @@ -2135,13 +2134,6 @@
2135 2134 bdev = ext3_blkdev_get(j_dev, sb);
2136 2135 if (bdev == NULL)
2137 2136 return NULL;
2138   -
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 2137  
2146 2138 blocksize = sb->s_blocksize;
2147 2139 hblock = bdev_logical_block_size(bdev);
... ... @@ -647,7 +647,7 @@
647 647 struct block_device *bdev;
648 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 651 if (IS_ERR(bdev))
652 652 goto fail;
653 653 return bdev;
... ... @@ -663,8 +663,7 @@
663 663 */
664 664 static int ext4_blkdev_put(struct block_device *bdev)
665 665 {
666   - bd_release(bdev);
667   - return blkdev_put(bdev, FMODE_READ|FMODE_WRITE);
  666 + return blkdev_put(bdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL);
668 667 }
669 668  
670 669 static int ext4_blkdev_remove(struct ext4_sb_info *sbi)
... ... @@ -3757,13 +3756,6 @@
3757 3756 bdev = ext4_blkdev_get(j_dev, sb);
3758 3757 if (bdev == NULL)
3759 3758 return NULL;
3760   -
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 3759  
3768 3760 blocksize = sb->s_blocksize;
3769 3761 hblock = bdev_logical_block_size(bdev);
fs/gfs2/ops_fstype.c
... ... @@ -1298,7 +1298,7 @@
1298 1298 goto error_bdev;
1299 1299  
1300 1300 if (s->s_root)
1301   - close_bdev_exclusive(bdev, mode);
  1301 + blkdev_put(bdev, mode | FMODE_EXCL);
1302 1302  
1303 1303 memset(&args, 0, sizeof(args));
1304 1304 args.ar_quota = GFS2_QUOTA_DEFAULT;
... ... @@ -1342,7 +1342,7 @@
1342 1342 deactivate_locked_super(s);
1343 1343 return ERR_PTR(error);
1344 1344 error_bdev:
1345   - close_bdev_exclusive(bdev, mode);
  1345 + blkdev_put(bdev, mode | FMODE_EXCL);
1346 1346 return ERR_PTR(error);
1347 1347 }
1348 1348  
... ... @@ -1120,16 +1120,13 @@
1120 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 1125 if (IS_ERR(bdev)) {
1125 1126 rc = -PTR_ERR(bdev);
1126 1127 goto free;
1127 1128 }
1128 1129  
1129   - if ((rc = bd_claim(bdev, log))) {
1130   - goto close;
1131   - }
1132   -
1133 1130 log->bdev = bdev;
1134 1131 memcpy(log->uuid, sbi->loguuid, sizeof(log->uuid));
1135 1132  
... ... @@ -1137,7 +1134,7 @@
1137 1134 * initialize log:
1138 1135 */
1139 1136 if ((rc = lmLogInit(log)))
1140   - goto unclaim;
  1137 + goto close;
1141 1138  
1142 1139 list_add(&log->journal_list, &jfs_external_logs);
1143 1140  
1144 1141  
... ... @@ -1163,11 +1160,8 @@
1163 1160 list_del(&log->journal_list);
1164 1161 lbmLogShutdown(log);
1165 1162  
1166   - unclaim:
1167   - bd_release(bdev);
1168   -
1169 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 1166 free: /* free log descriptor */
1173 1167 mutex_unlock(&jfs_log_mutex);
... ... @@ -1512,8 +1506,7 @@
1512 1506 bdev = log->bdev;
1513 1507 rc = lmLogShutdown(log);
1514 1508  
1515   - bd_release(bdev);
1516   - blkdev_put(bdev, FMODE_READ|FMODE_WRITE);
  1509 + blkdev_put(bdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL);
1517 1510  
1518 1511 kfree(log);
1519 1512  
... ... @@ -300,7 +300,7 @@
300 300  
301 301 static 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  
306 306 static int bdev_can_write_buf(struct super_block *sb, u64 ofs)
... ... @@ -331,7 +331,7 @@
331 331  
332 332 if (MAJOR(bdev->bd_dev) == MTD_BLOCK_MAJOR) {
333 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 335 return logfs_get_sb_mtd(p, mtdnr);
336 336 }
337 337  
... ... @@ -1233,7 +1233,7 @@
1233 1233 }
1234 1234  
1235 1235 if (!s_new)
1236   - close_bdev_exclusive(sd.bdev, mode);
  1236 + blkdev_put(sd.bdev, mode | FMODE_EXCL);
1237 1237  
1238 1238 return root_dentry;
1239 1239  
... ... @@ -1242,7 +1242,7 @@
1242 1242  
1243 1243 failed:
1244 1244 if (!s_new)
1245   - close_bdev_exclusive(sd.bdev, mode);
  1245 + blkdev_put(sd.bdev, mode | FMODE_EXCL);
1246 1246 return ERR_PTR(err);
1247 1247 }
1248 1248  
fs/ocfs2/cluster/heartbeat.c
... ... @@ -1674,7 +1674,7 @@
1674 1674 goto out;
1675 1675  
1676 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 1678 if (ret) {
1679 1679 reg->hr_bdev = NULL;
1680 1680 goto out;
fs/partitions/check.c
... ... @@ -549,7 +549,7 @@
549 549 goto exit;
550 550  
551 551 bdev->bd_invalidated = 1;
552   - err = blkdev_get(bdev, FMODE_READ);
  552 + err = blkdev_get(bdev, FMODE_READ, NULL);
553 553 if (err < 0)
554 554 goto exit;
555 555 blkdev_put(bdev, FMODE_READ);
fs/reiserfs/journal.c
... ... @@ -2552,8 +2552,6 @@
2552 2552 result = 0;
2553 2553  
2554 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 2555 result = blkdev_put(journal->j_dev_bd, journal->j_dev_mode);
2558 2556 journal->j_dev_bd = NULL;
2559 2557 }
... ... @@ -2571,7 +2569,7 @@
2571 2569 {
2572 2570 int result;
2573 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 2573 char b[BDEVNAME_SIZE];
2576 2574  
2577 2575 result = 0;
... ... @@ -2585,7 +2583,9 @@
2585 2583  
2586 2584 /* there is no "jdev" option and journal is on separate device */
2587 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 2589 journal->j_dev_mode = blkdev_mode;
2590 2590 if (IS_ERR(journal->j_dev_bd)) {
2591 2591 result = PTR_ERR(journal->j_dev_bd);
2592 2592  
... ... @@ -2594,15 +2594,8 @@
2594 2594 "cannot init journal device '%s': %i",
2595 2595 __bdevname(jdev, b), result);
2596 2596 return result;
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   -
  2597 + } else if (jdev != super->s_dev)
2604 2598 set_blocksize(journal->j_dev_bd, super->s_blocksize);
2605   - }
2606 2599  
2607 2600 return 0;
2608 2601 }
... ... @@ -801,13 +801,13 @@
801 801  
802 802 /*
803 803 * s_umount nests inside bd_mutex during
804   - * __invalidate_device(). close_bdev_exclusive()
805   - * acquires bd_mutex and can't be called under
806   - * s_umount. Drop s_umount temporarily. This is safe
807   - * as we're holding an active reference.
  804 + * __invalidate_device(). blkdev_put() acquires
  805 + * bd_mutex and can't be called under s_umount. Drop
  806 + * s_umount temporarily. This is safe as we're
  807 + * holding an active reference.
808 808 */
809 809 up_write(&s->s_umount);
810   - close_bdev_exclusive(bdev, mode);
  810 + blkdev_put(bdev, mode | FMODE_EXCL);
811 811 down_write(&s->s_umount);
812 812 } else {
813 813 char b[BDEVNAME_SIZE];
... ... @@ -831,7 +831,7 @@
831 831 error_s:
832 832 error = PTR_ERR(s);
833 833 error_bdev:
834   - close_bdev_exclusive(bdev, mode);
  834 + blkdev_put(bdev, mode | FMODE_EXCL);
835 835 error:
836 836 return ERR_PTR(error);
837 837 }
... ... @@ -862,7 +862,7 @@
862 862 bdev->bd_super = NULL;
863 863 generic_shutdown_super(sb);
864 864 sync_blockdev(bdev);
865   - close_bdev_exclusive(bdev, mode);
  865 + blkdev_put(bdev, mode | FMODE_EXCL);
866 866 }
867 867  
868 868 EXPORT_SYMBOL(kill_block_super);
fs/xfs/linux-2.6/xfs_super.c
... ... @@ -623,7 +623,7 @@
623 623 struct block_device *bdev)
624 624 {
625 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 /*
... ... @@ -2006,7 +2006,8 @@
2006 2006 extern void bd_set_size(struct block_device *, loff_t size);
2007 2007 extern void bd_forget(struct inode *inode);
2008 2008 extern void bdput(struct block_device *);
2009   -extern struct block_device *open_by_devnum(dev_t, fmode_t);
  2009 +extern struct block_device *open_by_devnum(dev_t dev, fmode_t mode,
  2010 + void *holder);
2010 2011 extern void invalidate_bdev(struct block_device *);
2011 2012 extern int sync_blockdev(struct block_device *bdev);
2012 2013 extern struct super_block *freeze_bdev(struct block_device *);
2013 2014  
2014 2015  
... ... @@ -2037,22 +2038,16 @@
2037 2038 extern int ioctl_by_bdev(struct block_device *, unsigned, unsigned long);
2038 2039 extern int blkdev_ioctl(struct block_device *, fmode_t, unsigned, unsigned long);
2039 2040 extern long compat_blkdev_ioctl(struct file *, unsigned, unsigned long);
2040   -extern int blkdev_get(struct block_device *, fmode_t);
2041   -extern int blkdev_put(struct block_device *, fmode_t);
2042   -extern int bd_claim(struct block_device *, void *);
2043   -extern void bd_release(struct block_device *);
  2041 +extern int blkdev_get(struct block_device *bdev, fmode_t mode, void *holder);
  2042 +extern int blkdev_put(struct block_device *bdev, fmode_t mode);
2044 2043 #ifdef CONFIG_SYSFS
2045 2044 extern int bd_link_disk_holder(struct block_device *bdev, struct gendisk *disk);
2046   -extern void bd_unlink_disk_holder(struct block_device *bdev);
2047 2045 #else
2048 2046 static inline int bd_link_disk_holder(struct block_device *bdev,
2049 2047 struct gendisk *disk)
2050 2048 {
2051 2049 return 0;
2052 2050 }
2053   -static inline void bd_unlink_disk_holder(struct block_device *bdev)
2054   -{
2055   -}
2056 2051 #endif
2057 2052 #endif
2058 2053  
... ... @@ -2089,7 +2084,6 @@
2089 2084 extern const char *bdevname(struct block_device *bdev, char *buffer);
2090 2085 extern struct block_device *lookup_bdev(const char *);
2091 2086 extern struct block_device *open_bdev_exclusive(const char *, fmode_t, void *);
2092   -extern void close_bdev_exclusive(struct block_device *, fmode_t);
2093 2087 extern void blkdev_show(struct seq_file *,off_t);
2094 2088  
2095 2089 #else
... ... @@ -223,7 +223,7 @@
223 223 return res;
224 224  
225 225 root_swap = res;
226   - res = blkdev_get(hib_resume_bdev, FMODE_WRITE);
  226 + res = blkdev_get(hib_resume_bdev, FMODE_WRITE, NULL);
227 227 if (res)
228 228 return res;
229 229  
... ... @@ -907,7 +907,8 @@
907 907 {
908 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 912 if (!IS_ERR(hib_resume_bdev)) {
912 913 set_blocksize(hib_resume_bdev, PAGE_SIZE);
913 914 clear_page(swsusp_header);
... ... @@ -1677,7 +1677,7 @@
1677 1677 if (S_ISBLK(inode->i_mode)) {
1678 1678 struct block_device *bdev = I_BDEV(inode);
1679 1679 set_blocksize(bdev, p->old_block_size);
1680   - bd_release(bdev);
  1680 + blkdev_put(bdev, FMODE_READ | FMODE_WRITE | FMODE_EXCL);
1681 1681 } else {
1682 1682 mutex_lock(&inode->i_mutex);
1683 1683 inode->i_flags &= ~S_SWAPFILE;
... ... @@ -1939,7 +1939,8 @@
1939 1939 error = -EINVAL;
1940 1940 if (S_ISBLK(inode->i_mode)) {
1941 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 1944 if (error < 0) {
1944 1945 bdev = NULL;
1945 1946 error = -EINVAL;
... ... @@ -2136,7 +2137,7 @@
2136 2137 bad_swap:
2137 2138 if (bdev) {
2138 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 2142 destroy_swap_extents(p);
2142 2143 swap_cgroup_swapoff(type);