Unverified Commit 46122b92 authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!3099 block: Make blkdev_get_by_*() return

Merge Pull Request from: @ci-robot 
 
PR sync from: Li Lingfeng <lilingfeng3@huawei.com>
https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/BL2N4PINLJQBMQS6EMVVECJK636CIQ7Z/ 
Create struct bdev_handle that contains all parameters that need to be
passed to blkdev_put() and provide bdev_open_* functions that return
this structure instead of plain bdev pointer.

v1->v2:
  Add new bugfix 8bd90b6ae785 ("erofs: fix NULL dereference of
  Fix the comment of cd34758c5238 ("block: Remove blkdev_get_by_()
  functions").
v2->v3:
  Fix the comment of acb083b55597 ("block: Use bdev_open_by_dev()
  in disk_scan_partitions() and blkdev_bszset()").

Jan Kara (30):
  block: Provide bdev_open_* functions
  block: Use bdev_open_by_dev() in blkdev_open()
  block: Use bdev_open_by_dev() in disk_scan_partitions() and
    blkdev_bszset()
  drdb: Convert to use bdev_open_by_path()
  pktcdvd: Convert to bdev_open_by_dev()
  rnbd-srv: Convert to use bdev_open_by_path()
  xen/blkback: Convert to bdev_open_by_dev()
  zram: Convert to use bdev_open_by_dev()
  bcache: Convert to bdev_open_by_path()
  dm: Convert to bdev_open_by_dev()
  md: Convert to bdev_open_by_dev()
  mtd: block2mtd: Convert to bdev_open_by_dev/path()
  nvmet: Convert to bdev_open_by_path()
  s390/dasd: Convert to bdev_open_by_path()
  scsi: target: Convert to bdev_open_by_path()
  PM: hibernate: Convert to bdev_open_by_dev()
  PM: hibernate: Drop unused snapshot_test argument
  mm/swap: Convert to use bdev_open_by_dev()
  fs: Convert to bdev_open_by_dev()
  btrfs: Convert to bdev_open_by_path()
  erofs: Convert to use bdev_open_by_path()
  ext4: Convert to bdev_open_by_dev()
  f2fs: Convert to bdev_open_by_dev/path()
  jfs: Convert to bdev_open_by_dev()
  nfs/blocklayout: Convert to use bdev_open_by_dev/path()
  ocfs2: Convert to use bdev_open_by_dev()
  reiserfs: Convert to bdev_open_by_dev/path()
  xfs: Convert to bdev_open_by_path()
  bcache: Fixup error handling in register_cache()
  block: Remove blkdev_get_by_*() functions

Jingbo Xu (1):


-- 
2.31.1
 
https://gitee.com/openeuler/kernel/issues/I8KPBR 
 
Link:https://gitee.com/openeuler/kernel/pulls/3099

 

Reviewed-by: default avatarzhangyi (F) <yi.zhang@huawei.com>
Signed-off-by: default avatarZheng Zengkai <zhengzengkai@huawei.com>
parents 86294596 8aac3113
Loading
Loading
Loading
Loading
+41 −24
Original line number Diff line number Diff line
@@ -729,7 +729,7 @@ void blkdev_put_no_open(struct block_device *bdev)
}
	
/**
 * blkdev_get_by_dev - open a block device by device number
 * bdev_open_by_dev - open a block device by device number
 * @dev: device number of block device to open
 * @mode: open mode (BLK_OPEN_*)
 * @holder: exclusive holder identifier
@@ -741,32 +741,40 @@ void blkdev_put_no_open(struct block_device *bdev)
 *
 * Use this interface 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.  Everything else should use blkdev_get_by_path().
 * number.  Everything else should use bdev_open_by_path().
 *
 * CONTEXT:
 * Might sleep.
 *
 * RETURNS:
 * Reference to the block_device on success, ERR_PTR(-errno) on failure.
 * Handle with a reference to the block_device on success, ERR_PTR(-errno) on
 * failure.
 */
struct block_device *blkdev_get_by_dev(dev_t dev, blk_mode_t mode, void *holder,
struct bdev_handle *bdev_open_by_dev(dev_t dev, blk_mode_t mode, void *holder,
				     const struct blk_holder_ops *hops)
{
	bool unblock_events = true;
	struct bdev_handle *handle = kmalloc(sizeof(struct bdev_handle),
					     GFP_KERNEL);
	struct block_device *bdev;
	bool unblock_events = true;
	struct gendisk *disk;
	int ret;

	if (!handle)
		return ERR_PTR(-ENOMEM);

	ret = devcgroup_check_permission(DEVCG_DEV_BLOCK,
			MAJOR(dev), MINOR(dev),
			((mode & BLK_OPEN_READ) ? DEVCG_ACC_READ : 0) |
			((mode & BLK_OPEN_WRITE) ? DEVCG_ACC_WRITE : 0));
	if (ret)
		return ERR_PTR(ret);
		goto free_handle;

	bdev = blkdev_get_no_open(dev);
	if (!bdev)
		return ERR_PTR(-ENXIO);
	if (!bdev) {
		ret = -ENXIO;
		goto free_handle;
	}
	disk = bdev->bd_disk;

	if (holder) {
@@ -815,7 +823,10 @@ struct block_device *blkdev_get_by_dev(dev_t dev, blk_mode_t mode, void *holder,

	if (unblock_events)
		disk_unblock_events(disk);
	return bdev;
	handle->bdev = bdev;
	handle->holder = holder;
	handle->mode = mode;
	return handle;
put_module:
	module_put(disk->fops->owner);
abort_claiming:
@@ -825,12 +836,14 @@ struct block_device *blkdev_get_by_dev(dev_t dev, blk_mode_t mode, void *holder,
	disk_unblock_events(disk);
put_blkdev:
	blkdev_put_no_open(bdev);
free_handle:
	kfree(handle);
	return ERR_PTR(ret);
}
EXPORT_SYMBOL(blkdev_get_by_dev);
EXPORT_SYMBOL(bdev_open_by_dev);

/**
 * blkdev_get_by_path - open a block device by name
 * bdev_open_by_path - open a block device by name
 * @path: path to the block device to open
 * @mode: open mode (BLK_OPEN_*)
 * @holder: exclusive holder identifier
@@ -844,12 +857,13 @@ EXPORT_SYMBOL(blkdev_get_by_dev);
 * Might sleep.
 *
 * RETURNS:
 * Reference to the block_device on success, ERR_PTR(-errno) on failure.
 * Handle with a reference to the block_device on success, ERR_PTR(-errno) on
 * failure.
 */
struct block_device *blkdev_get_by_path(const char *path, blk_mode_t mode,
struct bdev_handle *bdev_open_by_path(const char *path, blk_mode_t mode,
		void *holder, const struct blk_holder_ops *hops)
{
	struct block_device *bdev;
	struct bdev_handle *handle;
	dev_t dev;
	int error;

@@ -857,18 +871,20 @@ struct block_device *blkdev_get_by_path(const char *path, blk_mode_t mode,
	if (error)
		return ERR_PTR(error);

	bdev = blkdev_get_by_dev(dev, mode, holder, hops);
	if (!IS_ERR(bdev) && (mode & BLK_OPEN_WRITE) && bdev_read_only(bdev)) {
		blkdev_put(bdev, holder);
	handle = bdev_open_by_dev(dev, mode, holder, hops);
	if (!IS_ERR(handle) && (mode & BLK_OPEN_WRITE) &&
	    bdev_read_only(handle->bdev)) {
		bdev_release(handle);
		return ERR_PTR(-EACCES);
	}

	return bdev;
	return handle;
}
EXPORT_SYMBOL(blkdev_get_by_path);
EXPORT_SYMBOL(bdev_open_by_path);

void blkdev_put(struct block_device *bdev, void *holder)
void bdev_release(struct bdev_handle *handle)
{
	struct block_device *bdev = handle->bdev;
	struct gendisk *disk = bdev->bd_disk;

	/*
@@ -882,8 +898,8 @@ void blkdev_put(struct block_device *bdev, void *holder)
		sync_blockdev(bdev);

	mutex_lock(&disk->open_mutex);
	if (holder)
		bd_end_claim(bdev, holder);
	if (handle->holder)
		bd_end_claim(bdev, handle->holder);

	/*
	 * Trigger event checking and tell drivers to flush MEDIA_CHANGE
@@ -900,8 +916,9 @@ void blkdev_put(struct block_device *bdev, void *holder)

	module_put(disk->fops->owner);
	blkdev_put_no_open(bdev);
	kfree(handle);
}
EXPORT_SYMBOL(blkdev_put);
EXPORT_SYMBOL(bdev_release);

/**
 * lookup_bdev() - Look up a struct block_device by name.
+28 −16
Original line number Diff line number Diff line
@@ -542,15 +542,31 @@ static int blkdev_fsync(struct file *filp, loff_t start, loff_t end,
	return error;
}

/**
 * file_to_blk_mode - get block open flags from file flags
 * @file: file whose open flags should be converted
 *
 * Look at file open flags and generate corresponding block open flags from
 * them. The function works both for file just being open (e.g. during ->open
 * callback) and for file that is already open. This is actually non-trivial
 * (see comment in the function).
 */
blk_mode_t file_to_blk_mode(struct file *file)
{
	blk_mode_t mode = 0;
	struct bdev_handle *handle = file->private_data;

	if (file->f_mode & FMODE_READ)
		mode |= BLK_OPEN_READ;
	if (file->f_mode & FMODE_WRITE)
		mode |= BLK_OPEN_WRITE;
	if (file->private_data)
	/*
	 * do_dentry_open() clears O_EXCL from f_flags, use handle->mode to
	 * determine whether the open was exclusive for already open files.
	 */
	if (handle)
		mode |= handle->mode & BLK_OPEN_EXCL;
	else if (file->f_flags & O_EXCL)
		mode |= BLK_OPEN_EXCL;
	if (file->f_flags & O_NDELAY)
		mode |= BLK_OPEN_NDELAY;
@@ -568,7 +584,8 @@ blk_mode_t file_to_blk_mode(struct file *file)

static int blkdev_open(struct inode *inode, struct file *filp)
{
	struct block_device *bdev;
	struct bdev_handle *handle;
	blk_mode_t mode;

	/*
	 * Preserve backwards compatibility and allow large file access
@@ -579,29 +596,24 @@ static int blkdev_open(struct inode *inode, struct file *filp)
	filp->f_flags |= O_LARGEFILE;
	filp->f_mode |= FMODE_BUF_RASYNC | FMODE_CAN_ODIRECT;

	/*
	 * Use the file private data to store the holder for exclusive openes.
	 * file_to_blk_mode relies on it being present to set BLK_OPEN_EXCL.
	 */
	if (filp->f_flags & O_EXCL)
		filp->private_data = filp;

	bdev = blkdev_get_by_dev(inode->i_rdev, file_to_blk_mode(filp),
				 filp->private_data, NULL);
	if (IS_ERR(bdev))
		return PTR_ERR(bdev);
	mode = file_to_blk_mode(filp);
	handle = bdev_open_by_dev(inode->i_rdev, mode,
			mode & BLK_OPEN_EXCL ? filp : NULL, NULL);
	if (IS_ERR(handle))
		return PTR_ERR(handle);

	if (bdev_nowait(bdev))
	if (bdev_nowait(handle->bdev))
		filp->f_mode |= FMODE_NOWAIT;

	filp->f_mapping = bdev->bd_inode->i_mapping;
	filp->f_mapping = handle->bdev->bd_inode->i_mapping;
	filp->f_wb_err = filemap_sample_wb_err(filp->f_mapping);
	filp->private_data = handle;
	return 0;
}

static int blkdev_release(struct inode *inode, struct file *filp)
{
	blkdev_put(I_BDEV(filp->f_mapping->host), filp->private_data);
	bdev_release(filp->private_data);
	return 0;
}

+6 −6
Original line number Diff line number Diff line
@@ -342,7 +342,7 @@ EXPORT_SYMBOL_GPL(disk_uevent);

int disk_scan_partitions(struct gendisk *disk, blk_mode_t mode)
{
	struct block_device *bdev;
	struct bdev_handle *handle;
	int ret = 0;

	if (disk->flags & (GENHD_FL_NO_PART | GENHD_FL_HIDDEN))
@@ -366,12 +366,12 @@ int disk_scan_partitions(struct gendisk *disk, blk_mode_t mode)
	}

	set_bit(GD_NEED_PART_SCAN, &disk->state);
	bdev = blkdev_get_by_dev(disk_devt(disk), mode & ~BLK_OPEN_EXCL, NULL,
	handle = bdev_open_by_dev(disk_devt(disk), mode & ~BLK_OPEN_EXCL, NULL,
				  NULL);
	if (IS_ERR(bdev))
		ret =  PTR_ERR(bdev);
	if (IS_ERR(handle))
		ret = PTR_ERR(handle);
	else
		blkdev_put(bdev, NULL);
		bdev_release(handle);

	/*
	 * If blkdev_get_by_dev() failed early, GD_NEED_PART_SCAN is still set,
+4 −2
Original line number Diff line number Diff line
@@ -467,6 +467,7 @@ static int blkdev_bszset(struct block_device *bdev, blk_mode_t mode,
		int __user *argp)
{
	int ret, n;
	struct bdev_handle *handle;

	if (!capable(CAP_SYS_ADMIN))
		return -EACCES;
@@ -478,10 +479,11 @@ static int blkdev_bszset(struct block_device *bdev, blk_mode_t mode,
	if (mode & BLK_OPEN_EXCL)
		return set_blocksize(bdev, n);

	if (IS_ERR(blkdev_get_by_dev(bdev->bd_dev, mode, &bdev, NULL)))
	handle = bdev_open_by_dev(bdev->bd_dev, mode, &bdev, NULL);
	if (IS_ERR(handle))
		return -EBUSY;
	ret = set_blocksize(bdev, n);
	blkdev_put(bdev, &bdev);
	bdev_release(handle);

	return ret;
}
+2 −0
Original line number Diff line number Diff line
@@ -524,7 +524,9 @@ struct drbd_md {

struct drbd_backing_dev {
	struct block_device *backing_bdev;
	struct bdev_handle *backing_bdev_handle;
	struct block_device *md_bdev;
	struct bdev_handle *md_bdev_handle;
	struct drbd_md md;
	struct disk_conf *disk_conf; /* RCU, for updates: resource->conf_update */
	sector_t known_size; /* last known size of that backing device */
Loading