Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d4d77629 authored by Tejun Heo's avatar Tejun Heo
Browse files

block: clean up blkdev_get() wrappers and their users



After recent blkdev_get() modifications, open_by_devnum() and
open_bdev_exclusive() are simple wrappers around blkdev_get().
Replace them with blkdev_get_by_dev() and blkdev_get_by_path().

blkdev_get_by_dev() is identical to open_by_devnum().
blkdev_get_by_path() is slightly different in that it doesn't
automatically add %FMODE_EXCL to @mode.

All users are converted.  Most conversions are mechanical and don't
introduce any behavior difference.  There are several exceptions.

* btrfs now sets FMODE_EXCL in btrfs_device->mode, so there's no
  reason to OR it explicitly on blkdev_put().

* gfs2, nilfs2 and the generic mount_bdev() now set FMODE_EXCL in
  sb->s_mode.

* With the above changes, sb->s_mode now always should contain
  FMODE_EXCL.  WARN_ON_ONCE() added to kill_block_super() to detect
  errors.

The new blkdev_get_*() functions are with proper docbook comments.
While at it, add function description to blkdev_get() too.

Signed-off-by: default avatarTejun Heo <tj@kernel.org>
Cc: Philipp Reisner <philipp.reisner@linbit.com>
Cc: Neil Brown <neilb@suse.de>
Cc: Mike Snitzer <snitzer@redhat.com>
Cc: Joern Engel <joern@lazybastard.org>
Cc: Chris Mason <chris.mason@oracle.com>
Cc: Jan Kara <jack@suse.cz>
Cc: "Theodore Ts'o" <tytso@mit.edu>
Cc: KONISHI Ryusuke <konishi.ryusuke@lab.ntt.co.jp>
Cc: reiserfs-devel@vger.kernel.org
Cc: xfs-masters@oss.sgi.com
Cc: Alexander Viro <viro@zeniv.linux.org.uk>
parent 75f1dc0d
Loading
Loading
Loading
Loading
+6 −6
Original line number Original line Diff line number Diff line
@@ -902,8 +902,8 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp
		}
		}
	}
	}


	bdev = open_bdev_exclusive(nbc->dc.backing_dev,
	bdev = blkdev_get_by_path(nbc->dc.backing_dev,
				   FMODE_READ | FMODE_WRITE, mdev);
				  FMODE_READ | FMODE_WRITE | FMODE_EXCL, mdev);
	if (IS_ERR(bdev)) {
	if (IS_ERR(bdev)) {
		dev_err(DEV, "open(\"%s\") failed with %ld\n", nbc->dc.backing_dev,
		dev_err(DEV, "open(\"%s\") failed with %ld\n", nbc->dc.backing_dev,
			PTR_ERR(bdev));
			PTR_ERR(bdev));
@@ -920,8 +920,8 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp
	 * should check it for you already; but if you don't, or
	 * should check it for you already; but if you don't, or
	 * someone fooled it, we need to double check here)
	 * someone fooled it, we need to double check here)
	 */
	 */
	bdev = open_bdev_exclusive(nbc->dc.meta_dev,
	bdev = blkdev_get_by_path(nbc->dc.meta_dev,
				   FMODE_READ | FMODE_WRITE,
				  FMODE_READ | FMODE_WRITE | FMODE_EXCL,
				  (nbc->dc.meta_dev_idx < 0) ?
				  (nbc->dc.meta_dev_idx < 0) ?
				  (void *)mdev : (void *)drbd_m_holder);
				  (void *)mdev : (void *)drbd_m_holder);
	if (IS_ERR(bdev)) {
	if (IS_ERR(bdev)) {
+1 −1
Original line number Original line Diff line number Diff line
@@ -325,7 +325,7 @@ static int open_dev(struct dm_dev_internal *d, dev_t dev,


	BUG_ON(d->dm_dev.bdev);
	BUG_ON(d->dm_dev.bdev);


	bdev = open_by_devnum(dev, d->dm_dev.mode | FMODE_EXCL, _claim_ptr);
	bdev = blkdev_get_by_dev(dev, d->dm_dev.mode | FMODE_EXCL, _claim_ptr);
	if (IS_ERR(bdev))
	if (IS_ERR(bdev))
		return PTR_ERR(bdev);
		return PTR_ERR(bdev);


+2 −2
Original line number Original line Diff line number Diff line
@@ -1934,7 +1934,7 @@ static int lock_rdev(mdk_rdev_t *rdev, dev_t dev, int shared)
	struct block_device *bdev;
	struct block_device *bdev;
	char b[BDEVNAME_SIZE];
	char b[BDEVNAME_SIZE];


	bdev = open_by_devnum(dev, FMODE_READ|FMODE_WRITE|FMODE_EXCL,
	bdev = blkdev_get_by_dev(dev, FMODE_READ|FMODE_WRITE|FMODE_EXCL,
				 shared ? (mdk_rdev_t *)lock_rdev : rdev);
				 shared ? (mdk_rdev_t *)lock_rdev : rdev);
	if (IS_ERR(bdev)) {
	if (IS_ERR(bdev)) {
		printk(KERN_ERR "md: could not open %s.\n",
		printk(KERN_ERR "md: could not open %s.\n",
+2 −2
Original line number Original line Diff line number Diff line
@@ -247,7 +247,7 @@ static struct block2mtd_dev *add_device(char *devname, int erase_size)
		return NULL;
		return NULL;


	/* Get a handle on the device */
	/* Get a handle on the device */
	bdev = open_bdev_exclusive(devname, mode, dev);
	bdev = blkdev_get_by_path(devname, mode, dev);
#ifndef MODULE
#ifndef MODULE
	if (IS_ERR(bdev)) {
	if (IS_ERR(bdev)) {


@@ -256,7 +256,7 @@ static struct block2mtd_dev *add_device(char *devname, int erase_size)


		dev_t devt = name_to_dev_t(devname);
		dev_t devt = name_to_dev_t(devname);
		if (devt)
		if (devt)
			bdev = open_by_devnum(devt, mode, dev);
			bdev = blkdev_get_by_dev(devt, mode, dev);
	}
	}
#endif
#endif


+93 −46
Original line number Original line Diff line number Diff line
@@ -854,24 +854,6 @@ static inline void bd_unlink_disk_holder(struct block_device *bdev)
{ }
{ }
#endif
#endif


/*
 * Tries to open block device by device number.  Use it ONLY if you
 * really do not have anything better - i.e. when you are behind a
 * truly sucky interface and all you are given is a device number.  _Never_
 * to be used for internal purposes.  If you ever need it - reconsider
 * your API.
 */
struct block_device *open_by_devnum(dev_t dev, fmode_t mode, void *holder)
{
	struct block_device *bdev = bdget(dev);
	int err = -ENOMEM;
	if (bdev)
		err = blkdev_get(bdev, mode, holder);
	return err ? ERR_PTR(err) : bdev;
}

EXPORT_SYMBOL(open_by_devnum);

/**
/**
 * flush_disk - invalidates all buffer-cache entries on a disk
 * flush_disk - invalidates all buffer-cache entries on a disk
 *
 *
@@ -1132,6 +1114,25 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part)
	return ret;
	return ret;
}
}


/**
 * blkdev_get - open a block device
 * @bdev: block_device to open
 * @mode: FMODE_* mask
 * @holder: exclusive holder identifier
 *
 * Open @bdev with @mode.  If @mode includes %FMODE_EXCL, @bdev is
 * open with exclusive access.  Specifying %FMODE_EXCL with %NULL
 * @holder is invalid.  Exclusive opens may nest for the same @holder.
 *
 * On success, the reference count of @bdev is unchanged.  On failure,
 * @bdev is put.
 *
 * CONTEXT:
 * Might sleep.
 *
 * RETURNS:
 * 0 on success, -errno on failure.
 */
int blkdev_get(struct block_device *bdev, fmode_t mode, void *holder)
int blkdev_get(struct block_device *bdev, fmode_t mode, void *holder)
{
{
	struct block_device *whole = NULL;
	struct block_device *whole = NULL;
@@ -1186,6 +1187,80 @@ int blkdev_get(struct block_device *bdev, fmode_t mode, void *holder)
}
}
EXPORT_SYMBOL(blkdev_get);
EXPORT_SYMBOL(blkdev_get);


/**
 * blkdev_get_by_path - open a block device by name
 * @path: path to the block device to open
 * @mode: FMODE_* mask
 * @holder: exclusive holder identifier
 *
 * Open the blockdevice described by the device file at @path.  @mode
 * and @holder are identical to blkdev_get().
 *
 * On success, the returned block_device has reference count of one.
 *
 * CONTEXT:
 * Might sleep.
 *
 * RETURNS:
 * Pointer to block_device on success, ERR_PTR(-errno) on failure.
 */
struct block_device *blkdev_get_by_path(const char *path, fmode_t mode,
					void *holder)
{
	struct block_device *bdev;
	int err;

	bdev = lookup_bdev(path);
	if (IS_ERR(bdev))
		return bdev;

	err = blkdev_get(bdev, mode, holder);
	if (err)
		return ERR_PTR(err);

	return bdev;
}
EXPORT_SYMBOL(blkdev_get_by_path);

/**
 * blkdev_get_by_dev - open a block device by device number
 * @dev: device number of block device to open
 * @mode: FMODE_* mask
 * @holder: exclusive holder identifier
 *
 * Open the blockdevice described by device number @dev.  @mode and
 * @holder are identical to blkdev_get().
 *
 * Use it ONLY if you really do not have anything better - i.e. when
 * you are behind a truly sucky interface and all you are given is a
 * device number.  _Never_ to be used for internal purposes.  If you
 * ever need it - reconsider your API.
 *
 * On success, the returned block_device has reference count of one.
 *
 * CONTEXT:
 * Might sleep.
 *
 * RETURNS:
 * Pointer to block_device on success, ERR_PTR(-errno) on failure.
 */
struct block_device *blkdev_get_by_dev(dev_t dev, fmode_t mode, void *holder)
{
	struct block_device *bdev;
	int err;

	bdev = bdget(dev);
	if (!bdev)
		return ERR_PTR(-ENOMEM);

	err = blkdev_get(bdev, mode, holder);
	if (err)
		return ERR_PTR(err);

	return bdev;
}
EXPORT_SYMBOL(blkdev_get_by_dev);

static int blkdev_open(struct inode * inode, struct file * filp)
static int blkdev_open(struct inode * inode, struct file * filp)
{
{
	struct block_device *bdev;
	struct block_device *bdev;
@@ -1436,34 +1511,6 @@ struct block_device *lookup_bdev(const char *pathname)
}
}
EXPORT_SYMBOL(lookup_bdev);
EXPORT_SYMBOL(lookup_bdev);


/**
 * open_bdev_exclusive  -  open a block device by name and set it up for use
 *
 * @path:	special file representing the block device
 * @mode:	FMODE_... combination to pass be used
 * @holder:	owner for exclusion
 *
 * Open the blockdevice described by the special file at @path, claim it
 * for the @holder.
 */
struct block_device *open_bdev_exclusive(const char *path, fmode_t mode, void *holder)
{
	struct block_device *bdev;
	int error;

	bdev = lookup_bdev(path);
	if (IS_ERR(bdev))
		return bdev;

	error = blkdev_get(bdev, mode | FMODE_EXCL, holder);
	if (error)
		return ERR_PTR(error);

	return bdev;
}

EXPORT_SYMBOL(open_bdev_exclusive);

int __invalidate_device(struct block_device *bdev)
int __invalidate_device(struct block_device *bdev)
{
{
	struct super_block *sb = get_super(bdev);
	struct super_block *sb = get_super(bdev);
Loading