[PATCH 01/32] block: Provide blkdev_get_handle_* functions

Jan Kara <[email protected]>
Newsgroups gmane.comp.file-systems.btrfs,gmane.linux.block,gmane.linux.file-systems,gmane.linux.kernel.device-mapper.devel,gmane.linux.kernel.drbd.devel,gmane.linux.kernel.bcache.devel,gmane.comp.file-systems.ext4,gmane.linux.file-systems.f2fs,gmane.linux.kernel.mm,gmane.linux.drivers.mtd,gmane.linux.nfs,gmane.comp.file-systems.nilfs.user,gmane.linux.power-management.general,gmane.linux.raid,gmane.linux.scsi,gmane.comp.file-systems.ocfs2.devel,gmane.comp.file-systems.reiserfs.general,gmane.linux.scsi.target.devel,gmane.comp.emulators.xen.devel
Message-ID <[email protected]>
Create struct bdev_handle that contains all parameters that need to be
passed to blkdev_put() and provide blkdev_get_handle_* functions that
return this structure instead of plain bdev pointer. This will
eventually allow us to pass one more argument to blkdev_put() without
too much hassle.

CC: Alasdair Kergon <[email protected]>
CC: Andrew Morton <[email protected]>
CC: Anna Schumaker <[email protected]>
CC: Chao Yu <[email protected]>
CC: Christian Borntraeger <[email protected]>
CC: Coly Li <[email protected]
CC: "Darrick J. Wong" <[email protected]>
CC: Dave Kleikamp <[email protected]>
CC: David Sterba <[email protected]>
CC: [email protected]
CC: [email protected]
CC: Gao Xiang <[email protected]>
CC: Jack Wang <[email protected]>
CC: Jaegeuk Kim <[email protected]>
CC: [email protected]
CC: Joern Engel <[email protected]>
CC: Joseph Qi <[email protected]>
CC: Kent Overstreet <[email protected]>
CC: [email protected]
CC: [email protected]
CC: [email protected]
CC: <[email protected]>
CC: [email protected]
CC: [email protected]
CC: [email protected]
CC: [email protected]
CC: [email protected]
CC: [email protected]
CC: [email protected]
CC: [email protected]
CC: [email protected]
CC: [email protected]
CC: [email protected]
CC: "Md. Haris Iqbal" <[email protected]>
CC: Mike Snitzer <[email protected]>
CC: Minchan Kim <[email protected]>
CC: [email protected]
CC: [email protected]
CC: Sergey Senozhatsky <[email protected]>
CC: Song Liu <[email protected]>
CC: Sven Schnelle <[email protected]>
CC: [email protected]
CC: Ted Tso <[email protected]>
CC: Trond Myklebust <[email protected]>
CC: [email protected]
Signed-off-by: Jan Kara <[email protected]>
---
 block/bdev.c           | 47 ++++++++++++++++++++++++++++++++++++++++++
 include/linux/blkdev.h | 10 +++++++++
 2 files changed, 57 insertions(+)

diff --git a/block/bdev.c b/block/bdev.c
index 979e28a46b98..c75de5cac2bc 100644
--- a/block/bdev.c
+++ b/block/bdev.c
@@ -846,6 +846,24 @@ struct block_device *blkdev_get_by_dev(dev_t dev, blk_mode_t mode, void *holder,
 }
 EXPORT_SYMBOL(blkdev_get_by_dev);
 
+struct bdev_handle *blkdev_get_handle_by_dev(dev_t dev, blk_mode_t mode,
+		void *holder, const struct blk_holder_ops *hops)
+{
+	struct bdev_handle *handle = kmalloc(sizeof(struct bdev_handle),
+					     GFP_KERNEL);
+	struct block_device *bdev;
+
+	if (!handle)
+		return ERR_PTR(-ENOMEM);
+	bdev = blkdev_get_by_dev(dev, mode, holder, hops);
+	if (IS_ERR(bdev))
+		return ERR_CAST(bdev);
+	handle->bdev = bdev;
+	handle->holder = holder;
+	return handle;
+}
+EXPORT_SYMBOL(blkdev_get_handle_by_dev);
+
 /**
  * blkdev_get_by_path - open a block device by name
  * @path: path to the block device to open
@@ -884,6 +902,28 @@ struct block_device *blkdev_get_by_path(const char *path, blk_mode_t mode,
 }
 EXPORT_SYMBOL(blkdev_get_by_path);
 
+struct bdev_handle *blkdev_get_handle_by_path(const char *path, blk_mode_t mode,
+		void *holder, const struct blk_holder_ops *hops)
+{
+	struct bdev_handle *handle;
+	dev_t dev;
+	int error;
+
+	error = lookup_bdev(path, &dev);
+	if (error)
+		return ERR_PTR(error);
+
+	handle = blkdev_get_handle_by_dev(dev, mode, holder, hops);
+	if (!IS_ERR(handle) && (mode & BLK_OPEN_WRITE) &&
+	    bdev_read_only(handle->bdev)) {
+		blkdev_handle_put(handle);
+		return ERR_PTR(-EACCES);
+	}
+
+	return handle;
+}
+EXPORT_SYMBOL(blkdev_get_handle_by_path);
+
 void blkdev_put(struct block_device *bdev, void *holder)
 {
 	struct gendisk *disk = bdev->bd_disk;
@@ -920,6 +960,13 @@ void blkdev_put(struct block_device *bdev, void *holder)
 }
 EXPORT_SYMBOL(blkdev_put);
 
+void blkdev_handle_put(struct bdev_handle *handle)
+{
+	blkdev_put(handle->bdev, handle->holder);
+	kfree(handle);
+}
+EXPORT_SYMBOL(blkdev_handle_put);
+
 /**
  * lookup_bdev() - Look up a struct block_device by name.
  * @pathname: Name of the block device in the filesystem.
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index ed44a997f629..a910e9997ddd 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -1471,14 +1471,24 @@ struct blk_holder_ops {
 #define sb_open_mode(flags) \
 	(BLK_OPEN_READ | (((flags) & SB_RDONLY) ? 0 : BLK_OPEN_WRITE))
 
+struct bdev_handle {
+	struct block_device *bdev;
+	void *holder;
+};
+
 struct block_device *blkdev_get_by_dev(dev_t dev, blk_mode_t mode, void *holder,
 		const struct blk_holder_ops *hops);
 struct block_device *blkdev_get_by_path(const char *path, blk_mode_t mode,
 		void *holder, const struct blk_holder_ops *hops);
+struct bdev_handle *blkdev_get_handle_by_dev(dev_t dev, blk_mode_t mode,
+		void *holder, const struct blk_holder_ops *hops);
+struct bdev_handle *blkdev_get_handle_by_path(const char *path, blk_mode_t mode,
+		void *holder, const struct blk_holder_ops *hops);
 int bd_prepare_to_claim(struct block_device *bdev, void *holder,
 		const struct blk_holder_ops *hops);
 void bd_abort_claiming(struct block_device *bdev, void *holder);
 void blkdev_put(struct block_device *bdev, void *holder);
+void blkdev_handle_put(struct bdev_handle *handle);
 
 /* just for blk-cgroup, don't use elsewhere */
 struct block_device *blkdev_get_no_open(dev_t dev);
-- 
2.35.3
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.