linux-bcache.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/29] block: Make blkdev_get_by_*() return handle
@ 2023-08-11 11:04 Jan Kara
  2023-08-11 11:04 ` [PATCH 09/29] bcache: Convert to bdev_open_by_path() Jan Kara
                   ` (2 more replies)
  0 siblings, 3 replies; 16+ messages in thread
From: Jan Kara @ 2023-08-11 11:04 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: linux-block, Christoph Hellwig, Jan Kara, Alasdair Kergon,
	Andrew Morton, Anna Schumaker, Chao Yu, Christian Borntraeger,
	Darrick J. Wong, Dave Kleikamp, David Sterba, dm-devel, drbd-dev,
	Gao Xiang, Jack Wang, Jaegeuk Kim, jfs-discussion, Joern Engel,
	Joseph Qi, Kent Overstreet, linux-bcache, linux-btrfs,
	linux-erofs, linux-ext4, linux-f2fs-devel, linux-mm, linux-mtd,
	linux-nfs, linux-nilfs, linux-nvme, linux-pm, linux-raid,
	linux-s390, linux-scsi, linux-xfs, Md. Haris Iqbal, Mike Snitzer,
	Minchan Kim, ocfs2-devel, reiserfs-devel, Sergey Senozhatsky,
	Song Liu, Sven Schnelle, target-devel, Ted Tso, Trond Myklebust,
	xen-devel

Hello,

this is a v2 of the patch series which implements the idea of blkdev_get_by_*()
calls returning bdev_handle which is then passed to blkdev_put() [1]. This
makes the get and put calls for bdevs more obviously matching and allows us to
propagate context from get to put without having to modify all the users
(again!).  In particular I need to propagate used open flags to blkdev_put() to
be able count writeable opens and add support for blocking writes to mounted
block devices. I'll send that series separately.

The series is based on Christian's vfs tree as of yesterday as there is quite
some overlap. Patches have passed some reasonable testing - I've tested block
changes, md, dm, bcache, xfs, btrfs, ext4, swap. This obviously doesn't cover
everything so I'd like to ask respective maintainers to review / test their
changes. Thanks! I've pushed out the full branch to:

git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs.git bdev_handle

to ease review / testing.

Changes since v1:
* Rebased on top of current vfs tree
* Renamed final functions to bdev_open_by_*() and bdev_release()
* Fixed detection of exclusive open in blkdev_ioctl() and blkdev_fallocate()
* Fixed swap conversion to properly reinitialize swap_info->bdev_handle
* Fixed xfs conversion to not oops with rtdev without logdev
* Couple other minor fixups

								Honza

[1] https://lore.kernel.org/all/ZJGNsVDhZx0Xgs2H@infradead.org

CC: Alasdair Kergon <agk@redhat.com>
CC: Andrew Morton <akpm@linux-foundation.org>
CC: Anna Schumaker <anna@kernel.org>
CC: Chao Yu <chao@kernel.org>
CC: Christian Borntraeger <borntraeger@linux.ibm.com>
CC: Coly Li <colyli@suse.de
CC: "Darrick J. Wong" <djwong@kernel.org>
CC: Dave Kleikamp <shaggy@kernel.org>
CC: David Sterba <dsterba@suse.com>
CC: dm-devel@redhat.com
CC: drbd-dev@lists.linbit.com
CC: Gao Xiang <xiang@kernel.org>
CC: Jack Wang <jinpu.wang@ionos.com>
CC: Jaegeuk Kim <jaegeuk@kernel.org>
CC: jfs-discussion@lists.sourceforge.net
CC: Joern Engel <joern@lazybastard.org>
CC: Joseph Qi <joseph.qi@linux.alibaba.com>
CC: Kent Overstreet <kent.overstreet@gmail.com>
CC: linux-bcache@vger.kernel.org
CC: linux-btrfs@vger.kernel.org
CC: linux-erofs@lists.ozlabs.org
CC: <linux-ext4@vger.kernel.org>
CC: linux-f2fs-devel@lists.sourceforge.net
CC: linux-mm@kvack.org
CC: linux-mtd@lists.infradead.org
CC: linux-nfs@vger.kernel.org
CC: linux-nilfs@vger.kernel.org
CC: linux-nvme@lists.infradead.org
CC: linux-pm@vger.kernel.org
CC: linux-raid@vger.kernel.org
CC: linux-s390@vger.kernel.org
CC: linux-scsi@vger.kernel.org
CC: linux-xfs@vger.kernel.org
CC: "Md. Haris Iqbal" <haris.iqbal@ionos.com>
CC: Mike Snitzer <snitzer@kernel.org>
CC: Minchan Kim <minchan@kernel.org>
CC: ocfs2-devel@oss.oracle.com
CC: reiserfs-devel@vger.kernel.org
CC: Sergey Senozhatsky <senozhatsky@chromium.org>
CC: Song Liu <song@kernel.org>
CC: Sven Schnelle <svens@linux.ibm.com>
CC: target-devel@vger.kernel.org
CC: Ted Tso <tytso@mit.edu>
CC: Trond Myklebust <trond.myklebust@hammerspace.com>
CC: xen-devel@lists.xenproject.org

Previous versions:
Link: http://lore.kernel.org/r/20230629165206.383-1-jack@suse.cz # v1

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH 09/29] bcache: Convert to bdev_open_by_path()
  2023-08-11 11:04 [PATCH v2 0/29] block: Make blkdev_get_by_*() return handle Jan Kara
@ 2023-08-11 11:04 ` Jan Kara
  2023-08-21  1:06   ` Eric Wheeler
  2023-08-11 12:27 ` [PATCH v2 0/29] block: Make blkdev_get_by_*() return handle Christoph Hellwig
  2023-08-25  1:58 ` Al Viro
  2 siblings, 1 reply; 16+ messages in thread
From: Jan Kara @ 2023-08-11 11:04 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: linux-block, Christoph Hellwig, Jan Kara, linux-bcache,
	Kent Overstreet, Coly Li

Convert bcache to use bdev_open_by_path() and pass the handle around.

CC: linux-bcache@vger.kernel.org
CC: Coly Li <colyli@suse.de
CC: Kent Overstreet <kent.overstreet@gmail.com>
Acked-by: Coly Li <colyli@suse.de>
Signed-off-by: Jan Kara <jack@suse.cz>
---
 drivers/md/bcache/bcache.h |  2 +
 drivers/md/bcache/super.c  | 78 ++++++++++++++++++++------------------
 2 files changed, 43 insertions(+), 37 deletions(-)

diff --git a/drivers/md/bcache/bcache.h b/drivers/md/bcache/bcache.h
index 5a79bb3c272f..2aa3f2c1f719 100644
--- a/drivers/md/bcache/bcache.h
+++ b/drivers/md/bcache/bcache.h
@@ -299,6 +299,7 @@ struct cached_dev {
 	struct list_head	list;
 	struct bcache_device	disk;
 	struct block_device	*bdev;
+	struct bdev_handle	*bdev_handle;
 
 	struct cache_sb		sb;
 	struct cache_sb_disk	*sb_disk;
@@ -421,6 +422,7 @@ struct cache {
 
 	struct kobject		kobj;
 	struct block_device	*bdev;
+	struct bdev_handle	*bdev_handle;
 
 	struct task_struct	*alloc_thread;
 
diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c
index 0ae2b3676293..c11ac86be72b 100644
--- a/drivers/md/bcache/super.c
+++ b/drivers/md/bcache/super.c
@@ -1368,8 +1368,8 @@ static void cached_dev_free(struct closure *cl)
 	if (dc->sb_disk)
 		put_page(virt_to_page(dc->sb_disk));
 
-	if (!IS_ERR_OR_NULL(dc->bdev))
-		blkdev_put(dc->bdev, dc);
+	if (dc->bdev_handle)
+		bdev_release(dc->bdev_handle);
 
 	wake_up(&unregister_wait);
 
@@ -1444,7 +1444,7 @@ static int cached_dev_init(struct cached_dev *dc, unsigned int block_size)
 /* Cached device - bcache superblock */
 
 static int register_bdev(struct cache_sb *sb, struct cache_sb_disk *sb_disk,
-				 struct block_device *bdev,
+				 struct bdev_handle *bdev_handle,
 				 struct cached_dev *dc)
 {
 	const char *err = "cannot allocate memory";
@@ -1452,14 +1452,15 @@ static int register_bdev(struct cache_sb *sb, struct cache_sb_disk *sb_disk,
 	int ret = -ENOMEM;
 
 	memcpy(&dc->sb, sb, sizeof(struct cache_sb));
-	dc->bdev = bdev;
+	dc->bdev_handle = bdev_handle;
+	dc->bdev = bdev_handle->bdev;
 	dc->sb_disk = sb_disk;
 
 	if (cached_dev_init(dc, sb->block_size << 9))
 		goto err;
 
 	err = "error creating kobject";
-	if (kobject_add(&dc->disk.kobj, bdev_kobj(bdev), "bcache"))
+	if (kobject_add(&dc->disk.kobj, bdev_kobj(dc->bdev), "bcache"))
 		goto err;
 	if (bch_cache_accounting_add_kobjs(&dc->accounting, &dc->disk.kobj))
 		goto err;
@@ -2216,8 +2217,8 @@ void bch_cache_release(struct kobject *kobj)
 	if (ca->sb_disk)
 		put_page(virt_to_page(ca->sb_disk));
 
-	if (!IS_ERR_OR_NULL(ca->bdev))
-		blkdev_put(ca->bdev, ca);
+	if (ca->bdev_handle)
+		bdev_release(ca->bdev_handle);
 
 	kfree(ca);
 	module_put(THIS_MODULE);
@@ -2337,16 +2338,18 @@ static int cache_alloc(struct cache *ca)
 }
 
 static int register_cache(struct cache_sb *sb, struct cache_sb_disk *sb_disk,
-				struct block_device *bdev, struct cache *ca)
+				struct bdev_handle *bdev_handle,
+				struct cache *ca)
 {
 	const char *err = NULL; /* must be set for any error case */
 	int ret = 0;
 
 	memcpy(&ca->sb, sb, sizeof(struct cache_sb));
-	ca->bdev = bdev;
+	ca->bdev_handle = bdev_handle;
+	ca->bdev = bdev_handle->bdev;
 	ca->sb_disk = sb_disk;
 
-	if (bdev_max_discard_sectors((bdev)))
+	if (bdev_max_discard_sectors((bdev_handle->bdev)))
 		ca->discard = CACHE_DISCARD(&ca->sb);
 
 	ret = cache_alloc(ca);
@@ -2354,10 +2357,10 @@ static int register_cache(struct cache_sb *sb, struct cache_sb_disk *sb_disk,
 		/*
 		 * If we failed here, it means ca->kobj is not initialized yet,
 		 * kobject_put() won't be called and there is no chance to
-		 * call blkdev_put() to bdev in bch_cache_release(). So we
-		 * explicitly call blkdev_put() here.
+		 * call bdev_release() to bdev in bch_cache_release(). So
+		 * we explicitly call bdev_release() here.
 		 */
-		blkdev_put(bdev, ca);
+		bdev_release(bdev_handle);
 		if (ret == -ENOMEM)
 			err = "cache_alloc(): -ENOMEM";
 		else if (ret == -EPERM)
@@ -2367,7 +2370,7 @@ static int register_cache(struct cache_sb *sb, struct cache_sb_disk *sb_disk,
 		goto err;
 	}
 
-	if (kobject_add(&ca->kobj, bdev_kobj(bdev), "bcache")) {
+	if (kobject_add(&ca->kobj, bdev_kobj(bdev_handle->bdev), "bcache")) {
 		err = "error calling kobject_add";
 		ret = -ENOMEM;
 		goto out;
@@ -2382,14 +2385,14 @@ static int register_cache(struct cache_sb *sb, struct cache_sb_disk *sb_disk,
 		goto out;
 	}
 
-	pr_info("registered cache device %pg\n", ca->bdev);
+	pr_info("registered cache device %pg\n", ca->bdev_handle->bdev);
 
 out:
 	kobject_put(&ca->kobj);
 
 err:
 	if (err)
-		pr_notice("error %pg: %s\n", ca->bdev, err);
+		pr_notice("error %pg: %s\n", ca->bdev_handle->bdev, err);
 
 	return ret;
 }
@@ -2445,7 +2448,7 @@ struct async_reg_args {
 	char *path;
 	struct cache_sb *sb;
 	struct cache_sb_disk *sb_disk;
-	struct block_device *bdev;
+	struct bdev_handle *bdev_handle;
 	void *holder;
 };
 
@@ -2456,8 +2459,8 @@ static void register_bdev_worker(struct work_struct *work)
 		container_of(work, struct async_reg_args, reg_work.work);
 
 	mutex_lock(&bch_register_lock);
-	if (register_bdev(args->sb, args->sb_disk, args->bdev, args->holder)
-	    < 0)
+	if (register_bdev(args->sb, args->sb_disk, args->bdev_handle,
+			  args->holder) < 0)
 		fail = true;
 	mutex_unlock(&bch_register_lock);
 
@@ -2477,7 +2480,8 @@ static void register_cache_worker(struct work_struct *work)
 		container_of(work, struct async_reg_args, reg_work.work);
 
 	/* blkdev_put() will be called in bch_cache_release() */
-	if (register_cache(args->sb, args->sb_disk, args->bdev, args->holder))
+	if (register_cache(args->sb, args->sb_disk, args->bdev_handle,
+			   args->holder))
 		fail = true;
 
 	if (fail)
@@ -2514,7 +2518,7 @@ static ssize_t register_bcache(struct kobject *k, struct kobj_attribute *attr,
 	char *path = NULL;
 	struct cache_sb *sb;
 	struct cache_sb_disk *sb_disk;
-	struct block_device *bdev, *bdev2;
+	struct bdev_handle *bdev_handle, *bdev_handle2;
 	void *holder = NULL;
 	ssize_t ret;
 	bool async_registration = false;
@@ -2547,15 +2551,15 @@ static ssize_t register_bcache(struct kobject *k, struct kobj_attribute *attr,
 
 	ret = -EINVAL;
 	err = "failed to open device";
-	bdev = blkdev_get_by_path(strim(path), BLK_OPEN_READ, NULL, NULL);
-	if (IS_ERR(bdev))
+	bdev_handle = bdev_open_by_path(strim(path), BLK_OPEN_READ, NULL, NULL);
+	if (IS_ERR(bdev_handle))
 		goto out_free_sb;
 
 	err = "failed to set blocksize";
-	if (set_blocksize(bdev, 4096))
+	if (set_blocksize(bdev_handle->bdev, 4096))
 		goto out_blkdev_put;
 
-	err = read_super(sb, bdev, &sb_disk);
+	err = read_super(sb, bdev_handle->bdev, &sb_disk);
 	if (err)
 		goto out_blkdev_put;
 
@@ -2567,13 +2571,13 @@ static ssize_t register_bcache(struct kobject *k, struct kobj_attribute *attr,
 	}
 
 	/* Now reopen in exclusive mode with proper holder */
-	bdev2 = blkdev_get_by_dev(bdev->bd_dev, BLK_OPEN_READ | BLK_OPEN_WRITE,
-				  holder, NULL);
-	blkdev_put(bdev, NULL);
-	bdev = bdev2;
-	if (IS_ERR(bdev)) {
-		ret = PTR_ERR(bdev);
-		bdev = NULL;
+	bdev_handle2 = bdev_open_by_dev(bdev_handle->bdev->bd_dev,
+			BLK_OPEN_READ | BLK_OPEN_WRITE, holder, NULL);
+	bdev_release(bdev_handle);
+	bdev_handle = bdev_handle2;
+	if (IS_ERR(bdev_handle)) {
+		ret = PTR_ERR(bdev_handle);
+		bdev_handle = NULL;
 		if (ret == -EBUSY) {
 			dev_t dev;
 
@@ -2608,7 +2612,7 @@ static ssize_t register_bcache(struct kobject *k, struct kobj_attribute *attr,
 		args->path	= path;
 		args->sb	= sb;
 		args->sb_disk	= sb_disk;
-		args->bdev	= bdev;
+		args->bdev_handle	= bdev_handle;
 		args->holder	= holder;
 		register_device_async(args);
 		/* No wait and returns to user space */
@@ -2617,14 +2621,14 @@ static ssize_t register_bcache(struct kobject *k, struct kobj_attribute *attr,
 
 	if (SB_IS_BDEV(sb)) {
 		mutex_lock(&bch_register_lock);
-		ret = register_bdev(sb, sb_disk, bdev, holder);
+		ret = register_bdev(sb, sb_disk, bdev_handle, holder);
 		mutex_unlock(&bch_register_lock);
 		/* blkdev_put() will be called in cached_dev_free() */
 		if (ret < 0)
 			goto out_free_sb;
 	} else {
 		/* blkdev_put() will be called in bch_cache_release() */
-		ret = register_cache(sb, sb_disk, bdev, holder);
+		ret = register_cache(sb, sb_disk, bdev_handle, holder);
 		if (ret)
 			goto out_free_sb;
 	}
@@ -2640,8 +2644,8 @@ static ssize_t register_bcache(struct kobject *k, struct kobj_attribute *attr,
 out_put_sb_page:
 	put_page(virt_to_page(sb_disk));
 out_blkdev_put:
-	if (bdev)
-		blkdev_put(bdev, holder);
+	if (bdev_handle)
+		bdev_release(bdev_handle);
 out_free_sb:
 	kfree(sb);
 out_free_path:
-- 
2.35.3


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* Re: [PATCH v2 0/29] block: Make blkdev_get_by_*() return handle
  2023-08-11 11:04 [PATCH v2 0/29] block: Make blkdev_get_by_*() return handle Jan Kara
  2023-08-11 11:04 ` [PATCH 09/29] bcache: Convert to bdev_open_by_path() Jan Kara
@ 2023-08-11 12:27 ` Christoph Hellwig
  2023-08-25  1:58 ` Al Viro
  2 siblings, 0 replies; 16+ messages in thread
From: Christoph Hellwig @ 2023-08-11 12:27 UTC (permalink / raw)
  To: Jan Kara
  Cc: linux-fsdevel, linux-block, Christoph Hellwig, Alasdair Kergon,
	Andrew Morton, Anna Schumaker, Chao Yu, Christian Borntraeger,
	Darrick J. Wong, Dave Kleikamp, David Sterba, dm-devel, drbd-dev,
	Gao Xiang, Jack Wang, Jaegeuk Kim, jfs-discussion, Joern Engel,
	Joseph Qi, Kent Overstreet, linux-bcache, linux-btrfs,
	linux-erofs, linux-ext4, linux-f2fs-devel, linux-mm, linux-mtd,
	linux-nfs, linux-nilfs, linux-nvme, linux-pm, linux-raid,
	linux-s390, linux-scsi, linux-xfs, Md. Haris Iqbal, Mike Snitzer,
	Minchan Kim, ocfs2-devel, reiserfs-devel, Sergey Senozhatsky,
	Song Liu, Sven Schnelle, target-devel, Ted Tso, Trond Myklebust,
	xen-devel

Except for a mostly cosmetic nitpick this looks good to me:

Acked-by: Christoph Hellwig <hch@lst.de>

That's not eactly the deep review I'd like to do, but as I'm about to
head out for vacation that's probably as good as it gets.

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 09/29] bcache: Convert to bdev_open_by_path()
  2023-08-11 11:04 ` [PATCH 09/29] bcache: Convert to bdev_open_by_path() Jan Kara
@ 2023-08-21  1:06   ` Eric Wheeler
  2023-08-21 17:50     ` Jan Kara
  0 siblings, 1 reply; 16+ messages in thread
From: Eric Wheeler @ 2023-08-21  1:06 UTC (permalink / raw)
  To: Jan Kara
  Cc: linux-fsdevel, linux-block, Christoph Hellwig, linux-bcache,
	Kent Overstreet, Coly Li

On Fri, 11 Aug 2023, Jan Kara wrote:
> Convert bcache to use bdev_open_by_path() and pass the handle around.
> 
> CC: linux-bcache@vger.kernel.org
> CC: Coly Li <colyli@suse.de
> CC: Kent Overstreet <kent.overstreet@gmail.com>
> Acked-by: Coly Li <colyli@suse.de>
> Signed-off-by: Jan Kara <jack@suse.cz>
> ---
>  drivers/md/bcache/bcache.h |  2 +
>  drivers/md/bcache/super.c  | 78 ++++++++++++++++++++------------------
>  2 files changed, 43 insertions(+), 37 deletions(-)
> 
> diff --git a/drivers/md/bcache/bcache.h b/drivers/md/bcache/bcache.h
> index 5a79bb3c272f..2aa3f2c1f719 100644
> --- a/drivers/md/bcache/bcache.h
> +++ b/drivers/md/bcache/bcache.h
> @@ -299,6 +299,7 @@ struct cached_dev {
>  	struct list_head	list;
>  	struct bcache_device	disk;
>  	struct block_device	*bdev;
> +	struct bdev_handle	*bdev_handle;

It looks like you've handled most if not all of the `block_device *bdev` 
refactor.  Can we drop `block_device *bdev` and fixup any remaining 
references?  More below.

>  
>  	struct cache_sb		sb;
>  	struct cache_sb_disk	*sb_disk;
> @@ -421,6 +422,7 @@ struct cache {
>  
>  	struct kobject		kobj;
>  	struct block_device	*bdev;
> +	struct bdev_handle	*bdev_handle;

ditto.

>  
>  	struct task_struct	*alloc_thread;
>  
> diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c
> index 0ae2b3676293..c11ac86be72b 100644
> --- a/drivers/md/bcache/super.c
> +++ b/drivers/md/bcache/super.c
> @@ -1368,8 +1368,8 @@ static void cached_dev_free(struct closure *cl)
>  	if (dc->sb_disk)
>  		put_page(virt_to_page(dc->sb_disk));
>  
> -	if (!IS_ERR_OR_NULL(dc->bdev))
> -		blkdev_put(dc->bdev, dc);
> +	if (dc->bdev_handle)
> +		bdev_release(dc->bdev_handle);

bdev_release does not reset dc->bdev, which could leave a hanging 
reference.

>  
>  	wake_up(&unregister_wait);
>  
> @@ -1444,7 +1444,7 @@ static int cached_dev_init(struct cached_dev *dc, unsigned int block_size)
>  /* Cached device - bcache superblock */
>  
>  static int register_bdev(struct cache_sb *sb, struct cache_sb_disk *sb_disk,
> -				 struct block_device *bdev,
> +				 struct bdev_handle *bdev_handle,
>  				 struct cached_dev *dc)
>  {
>  	const char *err = "cannot allocate memory";
> @@ -1452,14 +1452,15 @@ static int register_bdev(struct cache_sb *sb, struct cache_sb_disk *sb_disk,
>  	int ret = -ENOMEM;
>  
>  	memcpy(&dc->sb, sb, sizeof(struct cache_sb));
> -	dc->bdev = bdev;
> +	dc->bdev_handle = bdev_handle;
> +	dc->bdev = bdev_handle->bdev;

If I understand correctly, this patch duplicates the dc->bdev reference to 
exist as dc->bdev_handle->bdev _and_ dc->bdev. (Same for changes related 
to `struct cache`.)

This would mean future developers have to understand they are the same 
thing, and someone may not manage it correctly.

If block core is moving to `struct bdev_handle`, then can we drop 
`dc->bdev` and replace all occurances of `dc->bdev` with 
`bdev_handle->bdev`?  Or make an accessor macro/function like 
bdev_handle_get_bdev(dc->bdev_handle)?

Unless I misunderstand something here, I would NACK this as written 
because it increases the liklihood of future developer error.  

I've added a few other comments below, but my comments are not exhaustive:

>  	dc->sb_disk = sb_disk;
>  
>  	if (cached_dev_init(dc, sb->block_size << 9))
>  		goto err;
>  
>  	err = "error creating kobject";
> -	if (kobject_add(&dc->disk.kobj, bdev_kobj(bdev), "bcache"))
> +	if (kobject_add(&dc->disk.kobj, bdev_kobj(dc->bdev), "bcache"))
>  		goto err;
>  	if (bch_cache_accounting_add_kobjs(&dc->accounting, &dc->disk.kobj))
>  		goto err;
> @@ -2216,8 +2217,8 @@ void bch_cache_release(struct kobject *kobj)
>  	if (ca->sb_disk)
>  		put_page(virt_to_page(ca->sb_disk));
>  
> -	if (!IS_ERR_OR_NULL(ca->bdev))
> -		blkdev_put(ca->bdev, ca);
> +	if (ca->bdev_handle)
> +		bdev_release(ca->bdev_handle);
>  

ca->bdev is not cleaned up

>  	kfree(ca);
>  	module_put(THIS_MODULE);
> @@ -2337,16 +2338,18 @@ static int cache_alloc(struct cache *ca)
>  }
>  
>  static int register_cache(struct cache_sb *sb, struct cache_sb_disk *sb_disk,
> -				struct block_device *bdev, struct cache *ca)
> +				struct bdev_handle *bdev_handle,
> +				struct cache *ca)
>  {
>  	const char *err = NULL; /* must be set for any error case */
>  	int ret = 0;
>  
>  	memcpy(&ca->sb, sb, sizeof(struct cache_sb));
> -	ca->bdev = bdev;
> +	ca->bdev_handle = bdev_handle;
> +	ca->bdev = bdev_handle->bdev;
>  	ca->sb_disk = sb_disk;
>  
> -	if (bdev_max_discard_sectors((bdev)))
> +	if (bdev_max_discard_sectors((bdev_handle->bdev)))
>  		ca->discard = CACHE_DISCARD(&ca->sb);
>  
>  	ret = cache_alloc(ca);
> @@ -2354,10 +2357,10 @@ static int register_cache(struct cache_sb *sb, struct cache_sb_disk *sb_disk,
>  		/*
>  		 * If we failed here, it means ca->kobj is not initialized yet,
>  		 * kobject_put() won't be called and there is no chance to
> -		 * call blkdev_put() to bdev in bch_cache_release(). So we
> -		 * explicitly call blkdev_put() here.
> +		 * call bdev_release() to bdev in bch_cache_release(). So
> +		 * we explicitly call bdev_release() here.
>  		 */
> -		blkdev_put(bdev, ca);
> +		bdev_release(bdev_handle);

ca->bdev is not cleaned up

>  		if (ret == -ENOMEM)
>  			err = "cache_alloc(): -ENOMEM";
>  		else if (ret == -EPERM)
> @@ -2367,7 +2370,7 @@ static int register_cache(struct cache_sb *sb, struct cache_sb_disk *sb_disk,
>  		goto err;
>  	}
>  
> -	if (kobject_add(&ca->kobj, bdev_kobj(bdev), "bcache")) {
> +	if (kobject_add(&ca->kobj, bdev_kobj(bdev_handle->bdev), "bcache")) {
>  		err = "error calling kobject_add";
>  		ret = -ENOMEM;
>  		goto out;
> @@ -2382,14 +2385,14 @@ static int register_cache(struct cache_sb *sb, struct cache_sb_disk *sb_disk,
>  		goto out;
>  	}
>  
> -	pr_info("registered cache device %pg\n", ca->bdev);
> +	pr_info("registered cache device %pg\n", ca->bdev_handle->bdev);
>  
>  out:
>  	kobject_put(&ca->kobj);
>  
>  err:
>  	if (err)
> -		pr_notice("error %pg: %s\n", ca->bdev, err);
> +		pr_notice("error %pg: %s\n", ca->bdev_handle->bdev, err);
>  
>  	return ret;
>  }
> @@ -2445,7 +2448,7 @@ struct async_reg_args {
>  	char *path;
>  	struct cache_sb *sb;
>  	struct cache_sb_disk *sb_disk;
> -	struct block_device *bdev;
> +	struct bdev_handle *bdev_handle;
>  	void *holder;
>  };
>  
> @@ -2456,8 +2459,8 @@ static void register_bdev_worker(struct work_struct *work)
>  		container_of(work, struct async_reg_args, reg_work.work);
>  
>  	mutex_lock(&bch_register_lock);
> -	if (register_bdev(args->sb, args->sb_disk, args->bdev, args->holder)
> -	    < 0)
> +	if (register_bdev(args->sb, args->sb_disk, args->bdev_handle,
> +			  args->holder) < 0)
>  		fail = true;
>  	mutex_unlock(&bch_register_lock);
>  
> @@ -2477,7 +2480,8 @@ static void register_cache_worker(struct work_struct *work)
>  		container_of(work, struct async_reg_args, reg_work.work);
>  
>  	/* blkdev_put() will be called in bch_cache_release() */
> -	if (register_cache(args->sb, args->sb_disk, args->bdev, args->holder))
> +	if (register_cache(args->sb, args->sb_disk, args->bdev_handle,
> +			   args->holder))
>  		fail = true;
>  
>  	if (fail)
> @@ -2514,7 +2518,7 @@ static ssize_t register_bcache(struct kobject *k, struct kobj_attribute *attr,
>  	char *path = NULL;
>  	struct cache_sb *sb;
>  	struct cache_sb_disk *sb_disk;
> -	struct block_device *bdev, *bdev2;
> +	struct bdev_handle *bdev_handle, *bdev_handle2;
>  	void *holder = NULL;
>  	ssize_t ret;
>  	bool async_registration = false;
> @@ -2547,15 +2551,15 @@ static ssize_t register_bcache(struct kobject *k, struct kobj_attribute *attr,
>  
>  	ret = -EINVAL;
>  	err = "failed to open device";
> -	bdev = blkdev_get_by_path(strim(path), BLK_OPEN_READ, NULL, NULL);
> -	if (IS_ERR(bdev))
> +	bdev_handle = bdev_open_by_path(strim(path), BLK_OPEN_READ, NULL, NULL);
> +	if (IS_ERR(bdev_handle))
>  		goto out_free_sb;
>  
>  	err = "failed to set blocksize";
> -	if (set_blocksize(bdev, 4096))
> +	if (set_blocksize(bdev_handle->bdev, 4096))
>  		goto out_blkdev_put;
>  
> -	err = read_super(sb, bdev, &sb_disk);
> +	err = read_super(sb, bdev_handle->bdev, &sb_disk);
>  	if (err)
>  		goto out_blkdev_put;
>  
> @@ -2567,13 +2571,13 @@ static ssize_t register_bcache(struct kobject *k, struct kobj_attribute *attr,
>  	}
>  
>  	/* Now reopen in exclusive mode with proper holder */
> -	bdev2 = blkdev_get_by_dev(bdev->bd_dev, BLK_OPEN_READ | BLK_OPEN_WRITE,
> -				  holder, NULL);
> -	blkdev_put(bdev, NULL);
> -	bdev = bdev2;
> -	if (IS_ERR(bdev)) {
> -		ret = PTR_ERR(bdev);
> -		bdev = NULL;
> +	bdev_handle2 = bdev_open_by_dev(bdev_handle->bdev->bd_dev,
> +			BLK_OPEN_READ | BLK_OPEN_WRITE, holder, NULL);
> +	bdev_release(bdev_handle);
> +	bdev_handle = bdev_handle2;
> +	if (IS_ERR(bdev_handle)) {
> +		ret = PTR_ERR(bdev_handle);
> +		bdev_handle = NULL;
>  		if (ret == -EBUSY) {
>  			dev_t dev;
>  
> @@ -2608,7 +2612,7 @@ static ssize_t register_bcache(struct kobject *k, struct kobj_attribute *attr,
>  		args->path	= path;
>  		args->sb	= sb;
>  		args->sb_disk	= sb_disk;
> -		args->bdev	= bdev;
> +		args->bdev_handle	= bdev_handle;
>  		args->holder	= holder;
>  		register_device_async(args);
>  		/* No wait and returns to user space */
> @@ -2617,14 +2621,14 @@ static ssize_t register_bcache(struct kobject *k, struct kobj_attribute *attr,
>  
>  	if (SB_IS_BDEV(sb)) {
>  		mutex_lock(&bch_register_lock);
> -		ret = register_bdev(sb, sb_disk, bdev, holder);
> +		ret = register_bdev(sb, sb_disk, bdev_handle, holder);
>  		mutex_unlock(&bch_register_lock);
>  		/* blkdev_put() will be called in cached_dev_free() */
>  		if (ret < 0)
>  			goto out_free_sb;
>  	} else {
>  		/* blkdev_put() will be called in bch_cache_release() */
> -		ret = register_cache(sb, sb_disk, bdev, holder);
> +		ret = register_cache(sb, sb_disk, bdev_handle, holder);
>  		if (ret)
>  			goto out_free_sb;
>  	}
> @@ -2640,8 +2644,8 @@ static ssize_t register_bcache(struct kobject *k, struct kobj_attribute *attr,
>  out_put_sb_page:
>  	put_page(virt_to_page(sb_disk));
>  out_blkdev_put:
> -	if (bdev)
> -		blkdev_put(bdev, holder);
> +	if (bdev_handle)
> +		bdev_release(bdev_handle);
>  out_free_sb:
>  	kfree(sb);
>  out_free_path:
> -- 
> 2.35.3
> 
> 


--
Eric Wheeler



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 09/29] bcache: Convert to bdev_open_by_path()
  2023-08-21  1:06   ` Eric Wheeler
@ 2023-08-21 17:50     ` Jan Kara
  2023-08-21 18:54       ` Eric Wheeler
  0 siblings, 1 reply; 16+ messages in thread
From: Jan Kara @ 2023-08-21 17:50 UTC (permalink / raw)
  To: Eric Wheeler
  Cc: Jan Kara, linux-fsdevel, linux-block, Christoph Hellwig,
	linux-bcache, Kent Overstreet, Coly Li

On Sun 20-08-23 18:06:01, Eric Wheeler wrote:
> On Fri, 11 Aug 2023, Jan Kara wrote:
> > Convert bcache to use bdev_open_by_path() and pass the handle around.
> > 
> > CC: linux-bcache@vger.kernel.org
> > CC: Coly Li <colyli@suse.de
> > CC: Kent Overstreet <kent.overstreet@gmail.com>
> > Acked-by: Coly Li <colyli@suse.de>
> > Signed-off-by: Jan Kara <jack@suse.cz>
> > ---
> >  drivers/md/bcache/bcache.h |  2 +
> >  drivers/md/bcache/super.c  | 78 ++++++++++++++++++++------------------
> >  2 files changed, 43 insertions(+), 37 deletions(-)
> > 
> > diff --git a/drivers/md/bcache/bcache.h b/drivers/md/bcache/bcache.h
> > index 5a79bb3c272f..2aa3f2c1f719 100644
> > --- a/drivers/md/bcache/bcache.h
> > +++ b/drivers/md/bcache/bcache.h
> > @@ -299,6 +299,7 @@ struct cached_dev {
> >  	struct list_head	list;
> >  	struct bcache_device	disk;
> >  	struct block_device	*bdev;
> > +	struct bdev_handle	*bdev_handle;
> 
> It looks like you've handled most if not all of the `block_device *bdev` 
> refactor.  Can we drop `block_device *bdev` and fixup any remaining 
> references?  More below.

Well, we could but it's a lot of churn - like 53 dereferences in bcache.
So if bcache maintainer wants to go this way, sure we can do it. But
preferably as a separate cleanup patch on top of this series because the
series generates enough conflicts as is and this will make it considerably
worse.

> > @@ -421,6 +422,7 @@ struct cache {
> >  
> >  	struct kobject		kobj;
> >  	struct block_device	*bdev;
> > +	struct bdev_handle	*bdev_handle;
> 
> ditto.
> 
> >  
> >  	struct task_struct	*alloc_thread;
> >  
> > diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c
> > index 0ae2b3676293..c11ac86be72b 100644
> > --- a/drivers/md/bcache/super.c
> > +++ b/drivers/md/bcache/super.c
> > @@ -1368,8 +1368,8 @@ static void cached_dev_free(struct closure *cl)
> >  	if (dc->sb_disk)
> >  		put_page(virt_to_page(dc->sb_disk));
> >  
> > -	if (!IS_ERR_OR_NULL(dc->bdev))
> > -		blkdev_put(dc->bdev, dc);
> > +	if (dc->bdev_handle)
> > +		bdev_release(dc->bdev_handle);
> 
> bdev_release does not reset dc->bdev, which could leave a hanging 
> reference.

So after this, dc->bdev may reference freed block device that is true. But
the original code did not cleanup dc->bdev either so things just stay as
they were.

> > @@ -1444,7 +1444,7 @@ static int cached_dev_init(struct cached_dev *dc, unsigned int block_size)
> >  /* Cached device - bcache superblock */
> >  
> >  static int register_bdev(struct cache_sb *sb, struct cache_sb_disk *sb_disk,
> > -				 struct block_device *bdev,
> > +				 struct bdev_handle *bdev_handle,
> >  				 struct cached_dev *dc)
> >  {
> >  	const char *err = "cannot allocate memory";
> > @@ -1452,14 +1452,15 @@ static int register_bdev(struct cache_sb *sb, struct cache_sb_disk *sb_disk,
> >  	int ret = -ENOMEM;
> >  
> >  	memcpy(&dc->sb, sb, sizeof(struct cache_sb));
> > -	dc->bdev = bdev;
> > +	dc->bdev_handle = bdev_handle;
> > +	dc->bdev = bdev_handle->bdev;
> 
> If I understand correctly, this patch duplicates the dc->bdev reference to 
> exist as dc->bdev_handle->bdev _and_ dc->bdev. (Same for changes related 
> to `struct cache`.)

Well, dc->bdev isn't a reference anymore, just a shortcut so that people
don't have to write the long dc->bdev_handle->bdev (plus it limits the
churn this series generates as I've mentioned above). I can see why some
people needn't like this duplication so sure we can clean it up if that's
the concensus of bcache developers.
 
> This would mean future developers have to understand they are the same 
> thing, and someone may not manage it correctly.
> 
> If block core is moving to `struct bdev_handle`, then can we drop 
> `dc->bdev` and replace all occurances of `dc->bdev` with 
> `bdev_handle->bdev`?  Or make an accessor macro/function like 
> bdev_handle_get_bdev(dc->bdev_handle)?

Accessor is making things even longer and I don't see the benefit. So I'd
just go with dc->bdev_handle->bdev.

> Unless I misunderstand something here, I would NACK this as written 
> because it increases the liklihood of future developer error.  
> 
> I've added a few other comments below, but my comments are not exhaustive:
> 
> >  	dc->sb_disk = sb_disk;
> >  
> >  	if (cached_dev_init(dc, sb->block_size << 9))
> >  		goto err;
> >  
> >  	err = "error creating kobject";
> > -	if (kobject_add(&dc->disk.kobj, bdev_kobj(bdev), "bcache"))
> > +	if (kobject_add(&dc->disk.kobj, bdev_kobj(dc->bdev), "bcache"))
> >  		goto err;
> >  	if (bch_cache_accounting_add_kobjs(&dc->accounting, &dc->disk.kobj))
> >  		goto err;
> > @@ -2216,8 +2217,8 @@ void bch_cache_release(struct kobject *kobj)
> >  	if (ca->sb_disk)
> >  		put_page(virt_to_page(ca->sb_disk));
> >  
> > -	if (!IS_ERR_OR_NULL(ca->bdev))
> > -		blkdev_put(ca->bdev, ca);
> > +	if (ca->bdev_handle)
> > +		bdev_release(ca->bdev_handle);
> >  
> 
> ca->bdev is not cleaned up

Well, same comment as with dc->bdev - the old code didn't cleanup the
pointer either. Furthermore the structure is kfree()d in the line below so
there is really no point in zeroing the pointer.

> >  	kfree(ca);
> >  	module_put(THIS_MODULE);
> > @@ -2337,16 +2338,18 @@ static int cache_alloc(struct cache *ca)
> >  }
> >  
> >  static int register_cache(struct cache_sb *sb, struct cache_sb_disk *sb_disk,
> > -				struct block_device *bdev, struct cache *ca)
> > +				struct bdev_handle *bdev_handle,
> > +				struct cache *ca)
> >  {
> >  	const char *err = NULL; /* must be set for any error case */
> >  	int ret = 0;
> >  
> >  	memcpy(&ca->sb, sb, sizeof(struct cache_sb));
> > -	ca->bdev = bdev;
> > +	ca->bdev_handle = bdev_handle;
> > +	ca->bdev = bdev_handle->bdev;
> >  	ca->sb_disk = sb_disk;
> >  
> > -	if (bdev_max_discard_sectors((bdev)))
> > +	if (bdev_max_discard_sectors((bdev_handle->bdev)))
> >  		ca->discard = CACHE_DISCARD(&ca->sb);
> >  
> >  	ret = cache_alloc(ca);
> > @@ -2354,10 +2357,10 @@ static int register_cache(struct cache_sb *sb, struct cache_sb_disk *sb_disk,
> >  		/*
> >  		 * If we failed here, it means ca->kobj is not initialized yet,
> >  		 * kobject_put() won't be called and there is no chance to
> > -		 * call blkdev_put() to bdev in bch_cache_release(). So we
> > -		 * explicitly call blkdev_put() here.
> > +		 * call bdev_release() to bdev in bch_cache_release(). So
> > +		 * we explicitly call bdev_release() here.
> >  		 */
> > -		blkdev_put(bdev, ca);
> > +		bdev_release(bdev_handle);
> 
> ca->bdev is not cleaned up

So ca->bdev doesn't really need to be cleaned up here and the original code
wasn't cleaning it up either. So I don't see a problem here either... But
maybe I miss something.

								Honza
-- 
Jan Kara <jack@suse.com>
SUSE Labs, CR

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 09/29] bcache: Convert to bdev_open_by_path()
  2023-08-21 17:50     ` Jan Kara
@ 2023-08-21 18:54       ` Eric Wheeler
  2023-08-23 10:10         ` Coly Li
  0 siblings, 1 reply; 16+ messages in thread
From: Eric Wheeler @ 2023-08-21 18:54 UTC (permalink / raw)
  To: Jan Kara
  Cc: linux-fsdevel, linux-block, Christoph Hellwig, linux-bcache,
	Kent Overstreet, Coly Li

On Mon, 21 Aug 2023, Jan Kara wrote:
> On Sun 20-08-23 18:06:01, Eric Wheeler wrote:
> > On Fri, 11 Aug 2023, Jan Kara wrote:
> > > Convert bcache to use bdev_open_by_path() and pass the handle around.
> > > 
> > > CC: linux-bcache@vger.kernel.org
> > > CC: Coly Li <colyli@suse.de
> > > CC: Kent Overstreet <kent.overstreet@gmail.com>
> > > Acked-by: Coly Li <colyli@suse.de>
> > > Signed-off-by: Jan Kara <jack@suse.cz>
> > > ---
> > >  drivers/md/bcache/bcache.h |  2 +
> > >  drivers/md/bcache/super.c  | 78 ++++++++++++++++++++------------------
> > >  2 files changed, 43 insertions(+), 37 deletions(-)
> > > 
> > > diff --git a/drivers/md/bcache/bcache.h b/drivers/md/bcache/bcache.h
> > > index 5a79bb3c272f..2aa3f2c1f719 100644
> > > --- a/drivers/md/bcache/bcache.h
> > > +++ b/drivers/md/bcache/bcache.h
> > > @@ -299,6 +299,7 @@ struct cached_dev {
> > >  	struct list_head	list;
> > >  	struct bcache_device	disk;
> > >  	struct block_device	*bdev;
> > > +	struct bdev_handle	*bdev_handle;
> > 
> > It looks like you've handled most if not all of the `block_device *bdev` 
> > refactor.  Can we drop `block_device *bdev` and fixup any remaining 
> > references?  More below.
> 
> Well, we could but it's a lot of churn - like 53 dereferences in bcache.
> So if bcache maintainer wants to go this way, sure we can do it. But
> preferably as a separate cleanup patch on top of this series because the
> series generates enough conflicts as is and this will make it considerably
> worse.

A separate cleanup patch seems reasonable, I'll defer to Coly on this one 
since he's the maintainer.  I just wanted to point out the possible issue.  
Thanks for your work on this.

--
Eric Wheeler



> 
> > > @@ -421,6 +422,7 @@ struct cache {
> > >  
> > >  	struct kobject		kobj;
> > >  	struct block_device	*bdev;
> > > +	struct bdev_handle	*bdev_handle;
> > 
> > ditto.
> > 
> > >  
> > >  	struct task_struct	*alloc_thread;
> > >  
> > > diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c
> > > index 0ae2b3676293..c11ac86be72b 100644
> > > --- a/drivers/md/bcache/super.c
> > > +++ b/drivers/md/bcache/super.c
> > > @@ -1368,8 +1368,8 @@ static void cached_dev_free(struct closure *cl)
> > >  	if (dc->sb_disk)
> > >  		put_page(virt_to_page(dc->sb_disk));
> > >  
> > > -	if (!IS_ERR_OR_NULL(dc->bdev))
> > > -		blkdev_put(dc->bdev, dc);
> > > +	if (dc->bdev_handle)
> > > +		bdev_release(dc->bdev_handle);
> > 
> > bdev_release does not reset dc->bdev, which could leave a hanging 
> > reference.
> 
> So after this, dc->bdev may reference freed block device that is true. But
> the original code did not cleanup dc->bdev either so things just stay as
> they were.
> 
> > > @@ -1444,7 +1444,7 @@ static int cached_dev_init(struct cached_dev *dc, unsigned int block_size)
> > >  /* Cached device - bcache superblock */
> > >  
> > >  static int register_bdev(struct cache_sb *sb, struct cache_sb_disk *sb_disk,
> > > -				 struct block_device *bdev,
> > > +				 struct bdev_handle *bdev_handle,
> > >  				 struct cached_dev *dc)
> > >  {
> > >  	const char *err = "cannot allocate memory";
> > > @@ -1452,14 +1452,15 @@ static int register_bdev(struct cache_sb *sb, struct cache_sb_disk *sb_disk,
> > >  	int ret = -ENOMEM;
> > >  
> > >  	memcpy(&dc->sb, sb, sizeof(struct cache_sb));
> > > -	dc->bdev = bdev;
> > > +	dc->bdev_handle = bdev_handle;
> > > +	dc->bdev = bdev_handle->bdev;
> > 
> > If I understand correctly, this patch duplicates the dc->bdev reference to 
> > exist as dc->bdev_handle->bdev _and_ dc->bdev. (Same for changes related 
> > to `struct cache`.)
> 
> Well, dc->bdev isn't a reference anymore, just a shortcut so that people
> don't have to write the long dc->bdev_handle->bdev (plus it limits the
> churn this series generates as I've mentioned above). I can see why some
> people needn't like this duplication so sure we can clean it up if that's
> the concensus of bcache developers.
>  
> > This would mean future developers have to understand they are the same 
> > thing, and someone may not manage it correctly.
> > 
> > If block core is moving to `struct bdev_handle`, then can we drop 
> > `dc->bdev` and replace all occurances of `dc->bdev` with 
> > `bdev_handle->bdev`?  Or make an accessor macro/function like 
> > bdev_handle_get_bdev(dc->bdev_handle)?
> 
> Accessor is making things even longer and I don't see the benefit. So I'd
> just go with dc->bdev_handle->bdev.
> 
> > Unless I misunderstand something here, I would NACK this as written 
> > because it increases the liklihood of future developer error.  
> > 
> > I've added a few other comments below, but my comments are not exhaustive:
> > 
> > >  	dc->sb_disk = sb_disk;
> > >  
> > >  	if (cached_dev_init(dc, sb->block_size << 9))
> > >  		goto err;
> > >  
> > >  	err = "error creating kobject";
> > > -	if (kobject_add(&dc->disk.kobj, bdev_kobj(bdev), "bcache"))
> > > +	if (kobject_add(&dc->disk.kobj, bdev_kobj(dc->bdev), "bcache"))
> > >  		goto err;
> > >  	if (bch_cache_accounting_add_kobjs(&dc->accounting, &dc->disk.kobj))
> > >  		goto err;
> > > @@ -2216,8 +2217,8 @@ void bch_cache_release(struct kobject *kobj)
> > >  	if (ca->sb_disk)
> > >  		put_page(virt_to_page(ca->sb_disk));
> > >  
> > > -	if (!IS_ERR_OR_NULL(ca->bdev))
> > > -		blkdev_put(ca->bdev, ca);
> > > +	if (ca->bdev_handle)
> > > +		bdev_release(ca->bdev_handle);
> > >  
> > 
> > ca->bdev is not cleaned up
> 
> Well, same comment as with dc->bdev - the old code didn't cleanup the
> pointer either. Furthermore the structure is kfree()d in the line below so
> there is really no point in zeroing the pointer.
> 
> > >  	kfree(ca);
> > >  	module_put(THIS_MODULE);
> > > @@ -2337,16 +2338,18 @@ static int cache_alloc(struct cache *ca)
> > >  }
> > >  
> > >  static int register_cache(struct cache_sb *sb, struct cache_sb_disk *sb_disk,
> > > -				struct block_device *bdev, struct cache *ca)
> > > +				struct bdev_handle *bdev_handle,
> > > +				struct cache *ca)
> > >  {
> > >  	const char *err = NULL; /* must be set for any error case */
> > >  	int ret = 0;
> > >  
> > >  	memcpy(&ca->sb, sb, sizeof(struct cache_sb));
> > > -	ca->bdev = bdev;
> > > +	ca->bdev_handle = bdev_handle;
> > > +	ca->bdev = bdev_handle->bdev;
> > >  	ca->sb_disk = sb_disk;
> > >  
> > > -	if (bdev_max_discard_sectors((bdev)))
> > > +	if (bdev_max_discard_sectors((bdev_handle->bdev)))
> > >  		ca->discard = CACHE_DISCARD(&ca->sb);
> > >  
> > >  	ret = cache_alloc(ca);
> > > @@ -2354,10 +2357,10 @@ static int register_cache(struct cache_sb *sb, struct cache_sb_disk *sb_disk,
> > >  		/*
> > >  		 * If we failed here, it means ca->kobj is not initialized yet,
> > >  		 * kobject_put() won't be called and there is no chance to
> > > -		 * call blkdev_put() to bdev in bch_cache_release(). So we
> > > -		 * explicitly call blkdev_put() here.
> > > +		 * call bdev_release() to bdev in bch_cache_release(). So
> > > +		 * we explicitly call bdev_release() here.
> > >  		 */
> > > -		blkdev_put(bdev, ca);
> > > +		bdev_release(bdev_handle);
> > 
> > ca->bdev is not cleaned up
> 
> So ca->bdev doesn't really need to be cleaned up here and the original code
> wasn't cleaning it up either. So I don't see a problem here either... But
> maybe I miss something.
> 
> 								Honza
> -- 
> Jan Kara <jack@suse.com>
> SUSE Labs, CR
> 

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 09/29] bcache: Convert to bdev_open_by_path()
  2023-08-21 18:54       ` Eric Wheeler
@ 2023-08-23 10:10         ` Coly Li
  0 siblings, 0 replies; 16+ messages in thread
From: Coly Li @ 2023-08-23 10:10 UTC (permalink / raw)
  To: Eric Wheeler
  Cc: Jan Kara, linux-fsdevel, linux-block, Christoph Hellwig,
	Bcache Linux, Kent Overstreet



> 2023年8月22日 02:54,Eric Wheeler <bcache@lists.ewheeler.net> 写道:
> 
> On Mon, 21 Aug 2023, Jan Kara wrote:
>> On Sun 20-08-23 18:06:01, Eric Wheeler wrote:
>>> On Fri, 11 Aug 2023, Jan Kara wrote:
>>>> Convert bcache to use bdev_open_by_path() and pass the handle around.
>>>> 
>>>> CC: linux-bcache@vger.kernel.org
>>>> CC: Coly Li <colyli@suse.de
>>>> CC: Kent Overstreet <kent.overstreet@gmail.com>
>>>> Acked-by: Coly Li <colyli@suse.de>
>>>> Signed-off-by: Jan Kara <jack@suse.cz>
>>>> ---
>>>> drivers/md/bcache/bcache.h |  2 +
>>>> drivers/md/bcache/super.c  | 78 ++++++++++++++++++++------------------
>>>> 2 files changed, 43 insertions(+), 37 deletions(-)
>>>> 
>>>> diff --git a/drivers/md/bcache/bcache.h b/drivers/md/bcache/bcache.h
>>>> index 5a79bb3c272f..2aa3f2c1f719 100644
>>>> --- a/drivers/md/bcache/bcache.h
>>>> +++ b/drivers/md/bcache/bcache.h
>>>> @@ -299,6 +299,7 @@ struct cached_dev {
>>>> struct list_head list;
>>>> struct bcache_device disk;
>>>> struct block_device *bdev;
>>>> + struct bdev_handle *bdev_handle;
>>> 
>>> It looks like you've handled most if not all of the `block_device *bdev` 
>>> refactor.  Can we drop `block_device *bdev` and fixup any remaining 
>>> references?  More below.
>> 
>> Well, we could but it's a lot of churn - like 53 dereferences in bcache.
>> So if bcache maintainer wants to go this way, sure we can do it. But
>> preferably as a separate cleanup patch on top of this series because the
>> series generates enough conflicts as is and this will make it considerably
>> worse.
> 
> A separate cleanup patch seems reasonable, I'll defer to Coly on this one 
> since he's the maintainer.  I just wanted to point out the possible issue.  
> Thanks for your work on this.

Yes, the challenge of this series is from the block layer core, once the change in core part is accepted, the cleanup can be followed up if necessary.

Thank you all.

Coly Li


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v2 0/29] block: Make blkdev_get_by_*() return handle
  2023-08-11 11:04 [PATCH v2 0/29] block: Make blkdev_get_by_*() return handle Jan Kara
  2023-08-11 11:04 ` [PATCH 09/29] bcache: Convert to bdev_open_by_path() Jan Kara
  2023-08-11 12:27 ` [PATCH v2 0/29] block: Make blkdev_get_by_*() return handle Christoph Hellwig
@ 2023-08-25  1:58 ` Al Viro
  2023-08-25 13:47   ` Jan Kara
  2 siblings, 1 reply; 16+ messages in thread
From: Al Viro @ 2023-08-25  1:58 UTC (permalink / raw)
  To: Jan Kara
  Cc: linux-fsdevel, linux-block, Christoph Hellwig, Alasdair Kergon,
	Andrew Morton, Anna Schumaker, Chao Yu, Christian Borntraeger,
	Darrick J. Wong, Dave Kleikamp, David Sterba, dm-devel, drbd-dev,
	Gao Xiang, Jack Wang, Jaegeuk Kim, jfs-discussion, Joern Engel,
	Joseph Qi, Kent Overstreet, linux-bcache, linux-btrfs,
	linux-erofs, linux-ext4, linux-f2fs-devel, linux-mm, linux-mtd,
	linux-nfs, linux-nilfs, linux-nvme, linux-pm, linux-raid,
	linux-s390, linux-scsi, linux-xfs, Md. Haris Iqbal, Mike Snitzer,
	Minchan Kim, ocfs2-devel, reiserfs-devel, Sergey Senozhatsky,
	Song Liu, Sven Schnelle, target-devel, Ted Tso, Trond Myklebust,
	xen-devel

On Fri, Aug 11, 2023 at 01:04:31PM +0200, Jan Kara wrote:
> Hello,
> 
> this is a v2 of the patch series which implements the idea of blkdev_get_by_*()
> calls returning bdev_handle which is then passed to blkdev_put() [1]. This
> makes the get and put calls for bdevs more obviously matching and allows us to
> propagate context from get to put without having to modify all the users
> (again!).  In particular I need to propagate used open flags to blkdev_put() to
> be able count writeable opens and add support for blocking writes to mounted
> block devices. I'll send that series separately.
> 
> The series is based on Christian's vfs tree as of yesterday as there is quite
> some overlap. Patches have passed some reasonable testing - I've tested block
> changes, md, dm, bcache, xfs, btrfs, ext4, swap. This obviously doesn't cover
> everything so I'd like to ask respective maintainers to review / test their
> changes. Thanks! I've pushed out the full branch to:
> 
> git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs.git bdev_handle
> 
> to ease review / testing.

Hmm...  Completely Insane Idea(tm): how about turning that thing inside out and
having your bdev_open_by... return an actual opened struct file?

After all, we do that for sockets and pipes just fine and that's a whole lot
hotter area.

Suppose we leave blkdev_open()/blkdev_release() as-is.  No need to mess with
what we have for normal opened files for block devices.  And have block_open_by_dev()
that would find bdev, etc., same yours does and shove it into anon file.

Paired with plain fput() - no need to bother with new primitives for closing.
With a helper returning I_BDEV(bdev_file_inode(file)) to get from those to bdev.

NOTE: I'm not suggesting replacing ->s_bdev with struct file * if we do that -
we want that value cached, obviously.  Just store both...

Not saying it's a good idea, but... might be interesting to look into.
Comments?

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v2 0/29] block: Make blkdev_get_by_*() return handle
  2023-08-25  1:58 ` Al Viro
@ 2023-08-25 13:47   ` Jan Kara
  2023-08-26  2:28     ` Al Viro
                       ` (2 more replies)
  0 siblings, 3 replies; 16+ messages in thread
From: Jan Kara @ 2023-08-25 13:47 UTC (permalink / raw)
  To: Al Viro
  Cc: Jan Kara, linux-fsdevel, linux-block, Christoph Hellwig,
	Alasdair Kergon, Andrew Morton, Anna Schumaker, Chao Yu,
	Christian Borntraeger, Darrick J. Wong, Dave Kleikamp,
	David Sterba, dm-devel, drbd-dev, Gao Xiang, Jack Wang,
	Jaegeuk Kim, jfs-discussion, Joern Engel, Joseph Qi,
	Kent Overstreet, linux-bcache, linux-btrfs, linux-erofs,
	linux-ext4, linux-f2fs-devel, linux-mm, linux-mtd, linux-nfs,
	linux-nilfs, linux-nvme, linux-pm, linux-raid, linux-s390,
	linux-scsi, linux-xfs, Md. Haris Iqbal, Mike Snitzer,
	Minchan Kim, ocfs2-devel, reiserfs-devel, Sergey Senozhatsky,
	Song Liu, Sven Schnelle, target-devel, Ted Tso, Trond Myklebust,
	xen-devel, Jens Axboe, Christian Brauner

On Fri 25-08-23 02:58:43, Al Viro wrote:
> On Fri, Aug 11, 2023 at 01:04:31PM +0200, Jan Kara wrote:
> > Hello,
> > 
> > this is a v2 of the patch series which implements the idea of blkdev_get_by_*()
> > calls returning bdev_handle which is then passed to blkdev_put() [1]. This
> > makes the get and put calls for bdevs more obviously matching and allows us to
> > propagate context from get to put without having to modify all the users
> > (again!).  In particular I need to propagate used open flags to blkdev_put() to
> > be able count writeable opens and add support for blocking writes to mounted
> > block devices. I'll send that series separately.
> > 
> > The series is based on Christian's vfs tree as of yesterday as there is quite
> > some overlap. Patches have passed some reasonable testing - I've tested block
> > changes, md, dm, bcache, xfs, btrfs, ext4, swap. This obviously doesn't cover
> > everything so I'd like to ask respective maintainers to review / test their
> > changes. Thanks! I've pushed out the full branch to:
> > 
> > git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs.git bdev_handle
> > 
> > to ease review / testing.
> 
> Hmm...  Completely Insane Idea(tm): how about turning that thing inside out and
> having your bdev_open_by... return an actual opened struct file?
> 
> After all, we do that for sockets and pipes just fine and that's a whole lot
> hotter area.
> 
> Suppose we leave blkdev_open()/blkdev_release() as-is.  No need to mess with
> what we have for normal opened files for block devices.  And have block_open_by_dev()
> that would find bdev, etc., same yours does and shove it into anon file.
> 
> Paired with plain fput() - no need to bother with new primitives for closing.
> With a helper returning I_BDEV(bdev_file_inode(file)) to get from those to bdev.
> 
> NOTE: I'm not suggesting replacing ->s_bdev with struct file * if we do that -
> we want that value cached, obviously.  Just store both...
> 
> Not saying it's a good idea, but... might be interesting to look into.
> Comments?

I can see the appeal of not having to introduce the new bdev_handle type
and just using struct file which unifies in-kernel and userspace block
device opens. But I can see downsides too - the last fput() happening from
task work makes me a bit nervous whether it will not break something
somewhere with exclusive bdev opens. Getting from struct file to bdev is
somewhat harder but I guess a helper like F_BDEV() would solve that just
fine.

So besides my last fput() worry about I think this could work and would be
probably a bit nicer than what I have. But before going and redoing the whole
series let me gather some more feedback so that we don't go back and forth.
Christoph, Christian, Jens, any opinion?

								Honza
-- 
Jan Kara <jack@suse.com>
SUSE Labs, CR

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v2 0/29] block: Make blkdev_get_by_*() return handle
  2023-08-25 13:47   ` Jan Kara
@ 2023-08-26  2:28     ` Al Viro
  2023-08-28 14:27       ` Christoph Hellwig
  2023-08-28 13:20     ` Christian Brauner
  2023-08-28 14:22     ` Christoph Hellwig
  2 siblings, 1 reply; 16+ messages in thread
From: Al Viro @ 2023-08-26  2:28 UTC (permalink / raw)
  To: Jan Kara
  Cc: linux-fsdevel, linux-block, Christoph Hellwig, Alasdair Kergon,
	Andrew Morton, Anna Schumaker, Chao Yu, Christian Borntraeger,
	Darrick J. Wong, Dave Kleikamp, David Sterba, dm-devel, drbd-dev,
	Gao Xiang, Jack Wang, Jaegeuk Kim, jfs-discussion, Joern Engel,
	Joseph Qi, Kent Overstreet, linux-bcache, linux-btrfs,
	linux-erofs, linux-ext4, linux-f2fs-devel, linux-mm, linux-mtd,
	linux-nfs, linux-nilfs, linux-nvme, linux-pm, linux-raid,
	linux-s390, linux-scsi, linux-xfs, Md. Haris Iqbal, Mike Snitzer,
	Minchan Kim, ocfs2-devel, reiserfs-devel, Sergey Senozhatsky,
	Song Liu, Sven Schnelle, target-devel, Ted Tso, Trond Myklebust,
	xen-devel, Jens Axboe, Christian Brauner

On Fri, Aug 25, 2023 at 03:47:56PM +0200, Jan Kara wrote:

> I can see the appeal of not having to introduce the new bdev_handle type
> and just using struct file which unifies in-kernel and userspace block
> device opens. But I can see downsides too - the last fput() happening from
> task work makes me a bit nervous whether it will not break something
> somewhere with exclusive bdev opens. Getting from struct file to bdev is
> somewhat harder but I guess a helper like F_BDEV() would solve that just
> fine.
> 
> So besides my last fput() worry about I think this could work and would be
> probably a bit nicer than what I have. But before going and redoing the whole
> series let me gather some more feedback so that we don't go back and forth.
> Christoph, Christian, Jens, any opinion?

Redoing is not an issue - it can be done on top of your series just
as well.  Async behaviour of fput() might be, but...  need to look
through the actual users; for a lot of them it's perfectly fine.

FWIW, from a cursory look there appears to be a missing primitive: take
an opened bdev (or bdev_handle, with your variant, or opened file if we
go that way eventually) and claim it.

I mean, look at claim_swapfile() for example:
                p->bdev = blkdev_get_by_dev(inode->i_rdev,
                                   FMODE_READ | FMODE_WRITE | FMODE_EXCL, p);
                if (IS_ERR(p->bdev)) {
                        error = PTR_ERR(p->bdev);
                        p->bdev = NULL;
                        return error;
                }
                p->old_block_size = block_size(p->bdev);
                error = set_blocksize(p->bdev, PAGE_SIZE);
                if (error < 0)
                        return error;
we already have the file opened, and we keep it opened all the way until
the swapoff(2); here we have noticed that it's a block device and we
	* open the fucker again (by device number), this time claiming
it with our swap_info_struct as holder, to be closed at swapoff(2) time
(just before we close the file)
	* flip the block size to PAGE_SIZE, to be reverted at swapoff(2)
time That really looks like it ought to be
	* take the opened file, see that it's a block device
	* try to claim it with that holder
	* on success, flip the block size
with close_filp() in the swapoff(2) (or failure exit path in swapon(2))
doing what it would've done for an O_EXCL opened block device.
The only difference from O_EXCL userland open is that here we would
end up with holder pointing not to struct file in question, but to our
swap_info_struct.  It will do the right thing.

This extra open is entirely due to "well, we need to claim it and the
primitive that does that happens to be tied to opening"; feels rather
counter-intuitive.

For that matter, we could add an explicit "unclaim" primitive - might
be easier to follow.  That would add another example where that could
be used - in blkdev_bszset() we have an opened block device (it's an
ioctl, after all), we want to change block size and we *really* don't
want to have that happen under a mounted filesystem.  So if it's not
opened exclusive, we do a temporary exclusive open of own and act on
that instead.   Might as well go for a temporary claim...

BTW, what happens if two threads call ioctl(fd, BLKBSZSET, &n)
for the same descriptor that happens to have been opened O_EXCL?
Without O_EXCL they would've been unable to claim the sucker at the same
time - the holder we are using is the address of a function argument,
i.e. something that points to kernel stack of the caller.  Those would
conflict and we either get set_blocksize() calls fully serialized, or
one of the callers would eat -EBUSY.  Not so in "opened with O_EXCL"
case - they can very well overlap and IIRC set_blocksize() does *not*
expect that kind of crap...  It's all under CAP_SYS_ADMIN, so it's not
as if it was a meaningful security hole anyway, but it does look fishy.

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v2 0/29] block: Make blkdev_get_by_*() return handle
  2023-08-25 13:47   ` Jan Kara
  2023-08-26  2:28     ` Al Viro
@ 2023-08-28 13:20     ` Christian Brauner
  2023-08-28 14:22     ` Christoph Hellwig
  2 siblings, 0 replies; 16+ messages in thread
From: Christian Brauner @ 2023-08-28 13:20 UTC (permalink / raw)
  To: Jan Kara
  Cc: Al Viro, linux-fsdevel, linux-block, Christoph Hellwig,
	Alasdair Kergon, Andrew Morton, Anna Schumaker, Chao Yu,
	Christian Borntraeger, Darrick J. Wong, Dave Kleikamp,
	David Sterba, dm-devel, drbd-dev, Gao Xiang, Jack Wang,
	Jaegeuk Kim, jfs-discussion, Joern Engel, Joseph Qi,
	Kent Overstreet, linux-bcache, linux-btrfs, linux-erofs,
	linux-ext4, linux-f2fs-devel, linux-mm, linux-mtd, linux-nfs,
	linux-nilfs, linux-nvme, linux-pm, linux-raid, linux-s390,
	linux-scsi, linux-xfs, Md. Haris Iqbal, Mike Snitzer,
	Minchan Kim, ocfs2-devel, reiserfs-devel, Sergey Senozhatsky,
	Song Liu, Sven Schnelle, target-devel, Ted Tso, Trond Myklebust,
	xen-devel, Jens Axboe

> So besides my last fput() worry about I think this could work and would be
> probably a bit nicer than what I have. But before going and redoing the whole
> series let me gather some more feedback so that we don't go back and forth.
> Christoph, Christian, Jens, any opinion?

I'll be a bit under water for the next few days, I expect but I'll get
back to this. I think not making you redo this whole thing from scratch
is what I'd prefer unless there's really clear advantages. But I don't
want to offer a haphazard opinion in the middle of the merge window.

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v2 0/29] block: Make blkdev_get_by_*() return handle
  2023-08-25 13:47   ` Jan Kara
  2023-08-26  2:28     ` Al Viro
  2023-08-28 13:20     ` Christian Brauner
@ 2023-08-28 14:22     ` Christoph Hellwig
  2 siblings, 0 replies; 16+ messages in thread
From: Christoph Hellwig @ 2023-08-28 14:22 UTC (permalink / raw)
  To: Jan Kara
  Cc: Al Viro, linux-fsdevel, linux-block, Christoph Hellwig,
	Alasdair Kergon, Andrew Morton, Anna Schumaker, Chao Yu,
	Christian Borntraeger, Darrick J. Wong, Dave Kleikamp,
	David Sterba, dm-devel, drbd-dev, Gao Xiang, Jack Wang,
	Jaegeuk Kim, jfs-discussion, Joern Engel, Joseph Qi,
	Kent Overstreet, linux-bcache, linux-btrfs, linux-erofs,
	linux-ext4, linux-f2fs-devel, linux-mm, linux-mtd, linux-nfs,
	linux-nilfs, linux-nvme, linux-pm, linux-raid, linux-s390,
	linux-scsi, linux-xfs, Md. Haris Iqbal, Mike Snitzer,
	Minchan Kim, ocfs2-devel, reiserfs-devel, Sergey Senozhatsky,
	Song Liu, Sven Schnelle, target-devel, Ted Tso, Trond Myklebust,
	xen-devel, Jens Axboe, Christian Brauner

On Fri, Aug 25, 2023 at 03:47:56PM +0200, Jan Kara wrote:
> I can see the appeal of not having to introduce the new bdev_handle type
> and just using struct file which unifies in-kernel and userspace block
> device opens. But I can see downsides too - the last fput() happening from
> task work makes me a bit nervous whether it will not break something
> somewhere with exclusive bdev opens. Getting from struct file to bdev is
> somewhat harder but I guess a helper like F_BDEV() would solve that just
> fine.
> 
> So besides my last fput() worry about I think this could work and would be
> probably a bit nicer than what I have. But before going and redoing the whole
> series let me gather some more feedback so that we don't go back and forth.
> Christoph, Christian, Jens, any opinion?

I did think about the file a bit.  The fact that we'd need something
like an anon_file for the by_dev open was always a huge turn off for
me, but maybe my concern is overblown.  Having a struct file would
actually be really useful for a bunch of users.


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v2 0/29] block: Make blkdev_get_by_*() return handle
  2023-08-26  2:28     ` Al Viro
@ 2023-08-28 14:27       ` Christoph Hellwig
  0 siblings, 0 replies; 16+ messages in thread
From: Christoph Hellwig @ 2023-08-28 14:27 UTC (permalink / raw)
  To: Al Viro
  Cc: Jan Kara, linux-fsdevel, linux-block, Christoph Hellwig,
	Alasdair Kergon, Andrew Morton, Anna Schumaker, Chao Yu,
	Christian Borntraeger, Darrick J. Wong, Dave Kleikamp,
	David Sterba, dm-devel, drbd-dev, Gao Xiang, Jack Wang,
	Jaegeuk Kim, jfs-discussion, Joern Engel, Joseph Qi,
	Kent Overstreet, linux-bcache, linux-btrfs, linux-erofs,
	linux-ext4, linux-f2fs-devel, linux-mm, linux-mtd, linux-nfs,
	linux-nilfs, linux-nvme, linux-pm, linux-raid, linux-s390,
	linux-scsi, linux-xfs, Md. Haris Iqbal, Mike Snitzer,
	Minchan Kim, ocfs2-devel, reiserfs-devel, Sergey Senozhatsky,
	Song Liu, Sven Schnelle, target-devel, Ted Tso, Trond Myklebust,
	xen-devel, Jens Axboe, Christian Brauner

On Sat, Aug 26, 2023 at 03:28:52AM +0100, Al Viro wrote:
> I mean, look at claim_swapfile() for example:
>                 p->bdev = blkdev_get_by_dev(inode->i_rdev,
>                                    FMODE_READ | FMODE_WRITE | FMODE_EXCL, p);
>                 if (IS_ERR(p->bdev)) {
>                         error = PTR_ERR(p->bdev);
>                         p->bdev = NULL;
>                         return error;
>                 }
>                 p->old_block_size = block_size(p->bdev);
>                 error = set_blocksize(p->bdev, PAGE_SIZE);
>                 if (error < 0)
>                         return error;
> we already have the file opened, and we keep it opened all the way until
> the swapoff(2); here we have noticed that it's a block device and we
> 	* open the fucker again (by device number), this time claiming
> it with our swap_info_struct as holder, to be closed at swapoff(2) time
> (just before we close the file)

Note that some drivers look at FMODE_EXCL/BLK_OPEN_EXCL in ->open.
These are probably bogus and maybe we want to kill them, but that will
need an audit first.

> BTW, what happens if two threads call ioctl(fd, BLKBSZSET, &n)
> for the same descriptor that happens to have been opened O_EXCL?
> Without O_EXCL they would've been unable to claim the sucker at the same
> time - the holder we are using is the address of a function argument,
> i.e. something that points to kernel stack of the caller.  Those would
> conflict and we either get set_blocksize() calls fully serialized, or
> one of the callers would eat -EBUSY.  Not so in "opened with O_EXCL"
> case - they can very well overlap and IIRC set_blocksize() does *not*
> expect that kind of crap...  It's all under CAP_SYS_ADMIN, so it's not
> as if it was a meaningful security hole anyway, but it does look fishy.

The user get to keep the pieces..  BLKBSZSET is kinda bogus anyway
as the soft blocksize only matters for buffer_head-like I/O, and
there only for file systems.  Not idea why anyone would set it manually.

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH 09/29] bcache: Convert to bdev_open_by_path()
  2023-08-23 10:48 [PATCH v3 " Jan Kara
  2023-08-23 10:48 ` [PATCH 09/29] bcache: Convert to bdev_open_by_path() Jan Kara
@ 2023-09-27  9:34 ` Jan Kara
  1 sibling, 0 replies; 16+ messages in thread
From: Jan Kara @ 2023-09-27  9:34 UTC (permalink / raw)
  To: Christian Brauner
  Cc: linux-fsdevel, linux-block, Christoph Hellwig, Jan Kara,
	linux-bcache, Kent Overstreet, Christoph Hellwig, Coly Li

Convert bcache to use bdev_open_by_path() and pass the handle around.

CC: linux-bcache@vger.kernel.org
CC: Coly Li <colyli@suse.de
CC: Kent Overstreet <kent.overstreet@gmail.com>
Acked-by: Christoph Hellwig <hch@lst.de>
Acked-by: Christian Brauner <brauner@kernel.org>
Acked-by: Coly Li <colyli@suse.de>
Signed-off-by: Jan Kara <jack@suse.cz>
---
 drivers/md/bcache/bcache.h |  2 +
 drivers/md/bcache/super.c  | 78 ++++++++++++++++++++------------------
 2 files changed, 43 insertions(+), 37 deletions(-)

diff --git a/drivers/md/bcache/bcache.h b/drivers/md/bcache/bcache.h
index 5a79bb3c272f..2aa3f2c1f719 100644
--- a/drivers/md/bcache/bcache.h
+++ b/drivers/md/bcache/bcache.h
@@ -299,6 +299,7 @@ struct cached_dev {
 	struct list_head	list;
 	struct bcache_device	disk;
 	struct block_device	*bdev;
+	struct bdev_handle	*bdev_handle;
 
 	struct cache_sb		sb;
 	struct cache_sb_disk	*sb_disk;
@@ -421,6 +422,7 @@ struct cache {
 
 	struct kobject		kobj;
 	struct block_device	*bdev;
+	struct bdev_handle	*bdev_handle;
 
 	struct task_struct	*alloc_thread;
 
diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c
index 0ae2b3676293..c11ac86be72b 100644
--- a/drivers/md/bcache/super.c
+++ b/drivers/md/bcache/super.c
@@ -1368,8 +1368,8 @@ static void cached_dev_free(struct closure *cl)
 	if (dc->sb_disk)
 		put_page(virt_to_page(dc->sb_disk));
 
-	if (!IS_ERR_OR_NULL(dc->bdev))
-		blkdev_put(dc->bdev, dc);
+	if (dc->bdev_handle)
+		bdev_release(dc->bdev_handle);
 
 	wake_up(&unregister_wait);
 
@@ -1444,7 +1444,7 @@ static int cached_dev_init(struct cached_dev *dc, unsigned int block_size)
 /* Cached device - bcache superblock */
 
 static int register_bdev(struct cache_sb *sb, struct cache_sb_disk *sb_disk,
-				 struct block_device *bdev,
+				 struct bdev_handle *bdev_handle,
 				 struct cached_dev *dc)
 {
 	const char *err = "cannot allocate memory";
@@ -1452,14 +1452,15 @@ static int register_bdev(struct cache_sb *sb, struct cache_sb_disk *sb_disk,
 	int ret = -ENOMEM;
 
 	memcpy(&dc->sb, sb, sizeof(struct cache_sb));
-	dc->bdev = bdev;
+	dc->bdev_handle = bdev_handle;
+	dc->bdev = bdev_handle->bdev;
 	dc->sb_disk = sb_disk;
 
 	if (cached_dev_init(dc, sb->block_size << 9))
 		goto err;
 
 	err = "error creating kobject";
-	if (kobject_add(&dc->disk.kobj, bdev_kobj(bdev), "bcache"))
+	if (kobject_add(&dc->disk.kobj, bdev_kobj(dc->bdev), "bcache"))
 		goto err;
 	if (bch_cache_accounting_add_kobjs(&dc->accounting, &dc->disk.kobj))
 		goto err;
@@ -2216,8 +2217,8 @@ void bch_cache_release(struct kobject *kobj)
 	if (ca->sb_disk)
 		put_page(virt_to_page(ca->sb_disk));
 
-	if (!IS_ERR_OR_NULL(ca->bdev))
-		blkdev_put(ca->bdev, ca);
+	if (ca->bdev_handle)
+		bdev_release(ca->bdev_handle);
 
 	kfree(ca);
 	module_put(THIS_MODULE);
@@ -2337,16 +2338,18 @@ static int cache_alloc(struct cache *ca)
 }
 
 static int register_cache(struct cache_sb *sb, struct cache_sb_disk *sb_disk,
-				struct block_device *bdev, struct cache *ca)
+				struct bdev_handle *bdev_handle,
+				struct cache *ca)
 {
 	const char *err = NULL; /* must be set for any error case */
 	int ret = 0;
 
 	memcpy(&ca->sb, sb, sizeof(struct cache_sb));
-	ca->bdev = bdev;
+	ca->bdev_handle = bdev_handle;
+	ca->bdev = bdev_handle->bdev;
 	ca->sb_disk = sb_disk;
 
-	if (bdev_max_discard_sectors((bdev)))
+	if (bdev_max_discard_sectors((bdev_handle->bdev)))
 		ca->discard = CACHE_DISCARD(&ca->sb);
 
 	ret = cache_alloc(ca);
@@ -2354,10 +2357,10 @@ static int register_cache(struct cache_sb *sb, struct cache_sb_disk *sb_disk,
 		/*
 		 * If we failed here, it means ca->kobj is not initialized yet,
 		 * kobject_put() won't be called and there is no chance to
-		 * call blkdev_put() to bdev in bch_cache_release(). So we
-		 * explicitly call blkdev_put() here.
+		 * call bdev_release() to bdev in bch_cache_release(). So
+		 * we explicitly call bdev_release() here.
 		 */
-		blkdev_put(bdev, ca);
+		bdev_release(bdev_handle);
 		if (ret == -ENOMEM)
 			err = "cache_alloc(): -ENOMEM";
 		else if (ret == -EPERM)
@@ -2367,7 +2370,7 @@ static int register_cache(struct cache_sb *sb, struct cache_sb_disk *sb_disk,
 		goto err;
 	}
 
-	if (kobject_add(&ca->kobj, bdev_kobj(bdev), "bcache")) {
+	if (kobject_add(&ca->kobj, bdev_kobj(bdev_handle->bdev), "bcache")) {
 		err = "error calling kobject_add";
 		ret = -ENOMEM;
 		goto out;
@@ -2382,14 +2385,14 @@ static int register_cache(struct cache_sb *sb, struct cache_sb_disk *sb_disk,
 		goto out;
 	}
 
-	pr_info("registered cache device %pg\n", ca->bdev);
+	pr_info("registered cache device %pg\n", ca->bdev_handle->bdev);
 
 out:
 	kobject_put(&ca->kobj);
 
 err:
 	if (err)
-		pr_notice("error %pg: %s\n", ca->bdev, err);
+		pr_notice("error %pg: %s\n", ca->bdev_handle->bdev, err);
 
 	return ret;
 }
@@ -2445,7 +2448,7 @@ struct async_reg_args {
 	char *path;
 	struct cache_sb *sb;
 	struct cache_sb_disk *sb_disk;
-	struct block_device *bdev;
+	struct bdev_handle *bdev_handle;
 	void *holder;
 };
 
@@ -2456,8 +2459,8 @@ static void register_bdev_worker(struct work_struct *work)
 		container_of(work, struct async_reg_args, reg_work.work);
 
 	mutex_lock(&bch_register_lock);
-	if (register_bdev(args->sb, args->sb_disk, args->bdev, args->holder)
-	    < 0)
+	if (register_bdev(args->sb, args->sb_disk, args->bdev_handle,
+			  args->holder) < 0)
 		fail = true;
 	mutex_unlock(&bch_register_lock);
 
@@ -2477,7 +2480,8 @@ static void register_cache_worker(struct work_struct *work)
 		container_of(work, struct async_reg_args, reg_work.work);
 
 	/* blkdev_put() will be called in bch_cache_release() */
-	if (register_cache(args->sb, args->sb_disk, args->bdev, args->holder))
+	if (register_cache(args->sb, args->sb_disk, args->bdev_handle,
+			   args->holder))
 		fail = true;
 
 	if (fail)
@@ -2514,7 +2518,7 @@ static ssize_t register_bcache(struct kobject *k, struct kobj_attribute *attr,
 	char *path = NULL;
 	struct cache_sb *sb;
 	struct cache_sb_disk *sb_disk;
-	struct block_device *bdev, *bdev2;
+	struct bdev_handle *bdev_handle, *bdev_handle2;
 	void *holder = NULL;
 	ssize_t ret;
 	bool async_registration = false;
@@ -2547,15 +2551,15 @@ static ssize_t register_bcache(struct kobject *k, struct kobj_attribute *attr,
 
 	ret = -EINVAL;
 	err = "failed to open device";
-	bdev = blkdev_get_by_path(strim(path), BLK_OPEN_READ, NULL, NULL);
-	if (IS_ERR(bdev))
+	bdev_handle = bdev_open_by_path(strim(path), BLK_OPEN_READ, NULL, NULL);
+	if (IS_ERR(bdev_handle))
 		goto out_free_sb;
 
 	err = "failed to set blocksize";
-	if (set_blocksize(bdev, 4096))
+	if (set_blocksize(bdev_handle->bdev, 4096))
 		goto out_blkdev_put;
 
-	err = read_super(sb, bdev, &sb_disk);
+	err = read_super(sb, bdev_handle->bdev, &sb_disk);
 	if (err)
 		goto out_blkdev_put;
 
@@ -2567,13 +2571,13 @@ static ssize_t register_bcache(struct kobject *k, struct kobj_attribute *attr,
 	}
 
 	/* Now reopen in exclusive mode with proper holder */
-	bdev2 = blkdev_get_by_dev(bdev->bd_dev, BLK_OPEN_READ | BLK_OPEN_WRITE,
-				  holder, NULL);
-	blkdev_put(bdev, NULL);
-	bdev = bdev2;
-	if (IS_ERR(bdev)) {
-		ret = PTR_ERR(bdev);
-		bdev = NULL;
+	bdev_handle2 = bdev_open_by_dev(bdev_handle->bdev->bd_dev,
+			BLK_OPEN_READ | BLK_OPEN_WRITE, holder, NULL);
+	bdev_release(bdev_handle);
+	bdev_handle = bdev_handle2;
+	if (IS_ERR(bdev_handle)) {
+		ret = PTR_ERR(bdev_handle);
+		bdev_handle = NULL;
 		if (ret == -EBUSY) {
 			dev_t dev;
 
@@ -2608,7 +2612,7 @@ static ssize_t register_bcache(struct kobject *k, struct kobj_attribute *attr,
 		args->path	= path;
 		args->sb	= sb;
 		args->sb_disk	= sb_disk;
-		args->bdev	= bdev;
+		args->bdev_handle	= bdev_handle;
 		args->holder	= holder;
 		register_device_async(args);
 		/* No wait and returns to user space */
@@ -2617,14 +2621,14 @@ static ssize_t register_bcache(struct kobject *k, struct kobj_attribute *attr,
 
 	if (SB_IS_BDEV(sb)) {
 		mutex_lock(&bch_register_lock);
-		ret = register_bdev(sb, sb_disk, bdev, holder);
+		ret = register_bdev(sb, sb_disk, bdev_handle, holder);
 		mutex_unlock(&bch_register_lock);
 		/* blkdev_put() will be called in cached_dev_free() */
 		if (ret < 0)
 			goto out_free_sb;
 	} else {
 		/* blkdev_put() will be called in bch_cache_release() */
-		ret = register_cache(sb, sb_disk, bdev, holder);
+		ret = register_cache(sb, sb_disk, bdev_handle, holder);
 		if (ret)
 			goto out_free_sb;
 	}
@@ -2640,8 +2644,8 @@ static ssize_t register_bcache(struct kobject *k, struct kobj_attribute *attr,
 out_put_sb_page:
 	put_page(virt_to_page(sb_disk));
 out_blkdev_put:
-	if (bdev)
-		blkdev_put(bdev, holder);
+	if (bdev_handle)
+		bdev_release(bdev_handle);
 out_free_sb:
 	kfree(sb);
 out_free_path:
-- 
2.35.3


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* Re: [PATCH 09/29] bcache: Convert to bdev_open_by_path()
  2023-08-23 10:48 ` [PATCH 09/29] bcache: Convert to bdev_open_by_path() Jan Kara
@ 2023-08-25 12:06   ` Christian Brauner
  0 siblings, 0 replies; 16+ messages in thread
From: Christian Brauner @ 2023-08-25 12:06 UTC (permalink / raw)
  To: Jan Kara
  Cc: Jens Axboe, linux-fsdevel, linux-block, Christoph Hellwig,
	linux-bcache, Kent Overstreet, Christoph Hellwig, Coly Li

On Wed, Aug 23, 2023 at 12:48:20PM +0200, Jan Kara wrote:
> Convert bcache to use bdev_open_by_path() and pass the handle around.
> 
> CC: linux-bcache@vger.kernel.org
> CC: Coly Li <colyli@suse.de
> CC: Kent Overstreet <kent.overstreet@gmail.com>
> Acked-by: Christoph Hellwig <hch@lst.de>
> Acked-by: Coly Li <colyli@suse.de>
> Signed-off-by: Jan Kara <jack@suse.cz>
> ---

Looks good to me,
Acked-by: Christian Brauner <brauner@kernel.org>

> -	if (!IS_ERR_OR_NULL(dc->bdev))
> -		blkdev_put(dc->bdev, dc);
> +	if (dc->bdev_handle)
> +		bdev_release(dc->bdev_handle);

Fwiw, these conversions confused me a little as the old check gave the
impression that this could be set to an error pointer somehow.

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH 09/29] bcache: Convert to bdev_open_by_path()
  2023-08-23 10:48 [PATCH v3 " Jan Kara
@ 2023-08-23 10:48 ` Jan Kara
  2023-08-25 12:06   ` Christian Brauner
  2023-09-27  9:34 ` Jan Kara
  1 sibling, 1 reply; 16+ messages in thread
From: Jan Kara @ 2023-08-23 10:48 UTC (permalink / raw)
  To: Christian Brauner
  Cc: Jens Axboe, linux-fsdevel, linux-block, Christoph Hellwig,
	Jan Kara, linux-bcache, Kent Overstreet, Christoph Hellwig,
	Coly Li

Convert bcache to use bdev_open_by_path() and pass the handle around.

CC: linux-bcache@vger.kernel.org
CC: Coly Li <colyli@suse.de
CC: Kent Overstreet <kent.overstreet@gmail.com>
Acked-by: Christoph Hellwig <hch@lst.de>
Acked-by: Coly Li <colyli@suse.de>
Signed-off-by: Jan Kara <jack@suse.cz>
---
 drivers/md/bcache/bcache.h |  2 +
 drivers/md/bcache/super.c  | 78 ++++++++++++++++++++------------------
 2 files changed, 43 insertions(+), 37 deletions(-)

diff --git a/drivers/md/bcache/bcache.h b/drivers/md/bcache/bcache.h
index 5a79bb3c272f..2aa3f2c1f719 100644
--- a/drivers/md/bcache/bcache.h
+++ b/drivers/md/bcache/bcache.h
@@ -299,6 +299,7 @@ struct cached_dev {
 	struct list_head	list;
 	struct bcache_device	disk;
 	struct block_device	*bdev;
+	struct bdev_handle	*bdev_handle;
 
 	struct cache_sb		sb;
 	struct cache_sb_disk	*sb_disk;
@@ -421,6 +422,7 @@ struct cache {
 
 	struct kobject		kobj;
 	struct block_device	*bdev;
+	struct bdev_handle	*bdev_handle;
 
 	struct task_struct	*alloc_thread;
 
diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c
index 0ae2b3676293..c11ac86be72b 100644
--- a/drivers/md/bcache/super.c
+++ b/drivers/md/bcache/super.c
@@ -1368,8 +1368,8 @@ static void cached_dev_free(struct closure *cl)
 	if (dc->sb_disk)
 		put_page(virt_to_page(dc->sb_disk));
 
-	if (!IS_ERR_OR_NULL(dc->bdev))
-		blkdev_put(dc->bdev, dc);
+	if (dc->bdev_handle)
+		bdev_release(dc->bdev_handle);
 
 	wake_up(&unregister_wait);
 
@@ -1444,7 +1444,7 @@ static int cached_dev_init(struct cached_dev *dc, unsigned int block_size)
 /* Cached device - bcache superblock */
 
 static int register_bdev(struct cache_sb *sb, struct cache_sb_disk *sb_disk,
-				 struct block_device *bdev,
+				 struct bdev_handle *bdev_handle,
 				 struct cached_dev *dc)
 {
 	const char *err = "cannot allocate memory";
@@ -1452,14 +1452,15 @@ static int register_bdev(struct cache_sb *sb, struct cache_sb_disk *sb_disk,
 	int ret = -ENOMEM;
 
 	memcpy(&dc->sb, sb, sizeof(struct cache_sb));
-	dc->bdev = bdev;
+	dc->bdev_handle = bdev_handle;
+	dc->bdev = bdev_handle->bdev;
 	dc->sb_disk = sb_disk;
 
 	if (cached_dev_init(dc, sb->block_size << 9))
 		goto err;
 
 	err = "error creating kobject";
-	if (kobject_add(&dc->disk.kobj, bdev_kobj(bdev), "bcache"))
+	if (kobject_add(&dc->disk.kobj, bdev_kobj(dc->bdev), "bcache"))
 		goto err;
 	if (bch_cache_accounting_add_kobjs(&dc->accounting, &dc->disk.kobj))
 		goto err;
@@ -2216,8 +2217,8 @@ void bch_cache_release(struct kobject *kobj)
 	if (ca->sb_disk)
 		put_page(virt_to_page(ca->sb_disk));
 
-	if (!IS_ERR_OR_NULL(ca->bdev))
-		blkdev_put(ca->bdev, ca);
+	if (ca->bdev_handle)
+		bdev_release(ca->bdev_handle);
 
 	kfree(ca);
 	module_put(THIS_MODULE);
@@ -2337,16 +2338,18 @@ static int cache_alloc(struct cache *ca)
 }
 
 static int register_cache(struct cache_sb *sb, struct cache_sb_disk *sb_disk,
-				struct block_device *bdev, struct cache *ca)
+				struct bdev_handle *bdev_handle,
+				struct cache *ca)
 {
 	const char *err = NULL; /* must be set for any error case */
 	int ret = 0;
 
 	memcpy(&ca->sb, sb, sizeof(struct cache_sb));
-	ca->bdev = bdev;
+	ca->bdev_handle = bdev_handle;
+	ca->bdev = bdev_handle->bdev;
 	ca->sb_disk = sb_disk;
 
-	if (bdev_max_discard_sectors((bdev)))
+	if (bdev_max_discard_sectors((bdev_handle->bdev)))
 		ca->discard = CACHE_DISCARD(&ca->sb);
 
 	ret = cache_alloc(ca);
@@ -2354,10 +2357,10 @@ static int register_cache(struct cache_sb *sb, struct cache_sb_disk *sb_disk,
 		/*
 		 * If we failed here, it means ca->kobj is not initialized yet,
 		 * kobject_put() won't be called and there is no chance to
-		 * call blkdev_put() to bdev in bch_cache_release(). So we
-		 * explicitly call blkdev_put() here.
+		 * call bdev_release() to bdev in bch_cache_release(). So
+		 * we explicitly call bdev_release() here.
 		 */
-		blkdev_put(bdev, ca);
+		bdev_release(bdev_handle);
 		if (ret == -ENOMEM)
 			err = "cache_alloc(): -ENOMEM";
 		else if (ret == -EPERM)
@@ -2367,7 +2370,7 @@ static int register_cache(struct cache_sb *sb, struct cache_sb_disk *sb_disk,
 		goto err;
 	}
 
-	if (kobject_add(&ca->kobj, bdev_kobj(bdev), "bcache")) {
+	if (kobject_add(&ca->kobj, bdev_kobj(bdev_handle->bdev), "bcache")) {
 		err = "error calling kobject_add";
 		ret = -ENOMEM;
 		goto out;
@@ -2382,14 +2385,14 @@ static int register_cache(struct cache_sb *sb, struct cache_sb_disk *sb_disk,
 		goto out;
 	}
 
-	pr_info("registered cache device %pg\n", ca->bdev);
+	pr_info("registered cache device %pg\n", ca->bdev_handle->bdev);
 
 out:
 	kobject_put(&ca->kobj);
 
 err:
 	if (err)
-		pr_notice("error %pg: %s\n", ca->bdev, err);
+		pr_notice("error %pg: %s\n", ca->bdev_handle->bdev, err);
 
 	return ret;
 }
@@ -2445,7 +2448,7 @@ struct async_reg_args {
 	char *path;
 	struct cache_sb *sb;
 	struct cache_sb_disk *sb_disk;
-	struct block_device *bdev;
+	struct bdev_handle *bdev_handle;
 	void *holder;
 };
 
@@ -2456,8 +2459,8 @@ static void register_bdev_worker(struct work_struct *work)
 		container_of(work, struct async_reg_args, reg_work.work);
 
 	mutex_lock(&bch_register_lock);
-	if (register_bdev(args->sb, args->sb_disk, args->bdev, args->holder)
-	    < 0)
+	if (register_bdev(args->sb, args->sb_disk, args->bdev_handle,
+			  args->holder) < 0)
 		fail = true;
 	mutex_unlock(&bch_register_lock);
 
@@ -2477,7 +2480,8 @@ static void register_cache_worker(struct work_struct *work)
 		container_of(work, struct async_reg_args, reg_work.work);
 
 	/* blkdev_put() will be called in bch_cache_release() */
-	if (register_cache(args->sb, args->sb_disk, args->bdev, args->holder))
+	if (register_cache(args->sb, args->sb_disk, args->bdev_handle,
+			   args->holder))
 		fail = true;
 
 	if (fail)
@@ -2514,7 +2518,7 @@ static ssize_t register_bcache(struct kobject *k, struct kobj_attribute *attr,
 	char *path = NULL;
 	struct cache_sb *sb;
 	struct cache_sb_disk *sb_disk;
-	struct block_device *bdev, *bdev2;
+	struct bdev_handle *bdev_handle, *bdev_handle2;
 	void *holder = NULL;
 	ssize_t ret;
 	bool async_registration = false;
@@ -2547,15 +2551,15 @@ static ssize_t register_bcache(struct kobject *k, struct kobj_attribute *attr,
 
 	ret = -EINVAL;
 	err = "failed to open device";
-	bdev = blkdev_get_by_path(strim(path), BLK_OPEN_READ, NULL, NULL);
-	if (IS_ERR(bdev))
+	bdev_handle = bdev_open_by_path(strim(path), BLK_OPEN_READ, NULL, NULL);
+	if (IS_ERR(bdev_handle))
 		goto out_free_sb;
 
 	err = "failed to set blocksize";
-	if (set_blocksize(bdev, 4096))
+	if (set_blocksize(bdev_handle->bdev, 4096))
 		goto out_blkdev_put;
 
-	err = read_super(sb, bdev, &sb_disk);
+	err = read_super(sb, bdev_handle->bdev, &sb_disk);
 	if (err)
 		goto out_blkdev_put;
 
@@ -2567,13 +2571,13 @@ static ssize_t register_bcache(struct kobject *k, struct kobj_attribute *attr,
 	}
 
 	/* Now reopen in exclusive mode with proper holder */
-	bdev2 = blkdev_get_by_dev(bdev->bd_dev, BLK_OPEN_READ | BLK_OPEN_WRITE,
-				  holder, NULL);
-	blkdev_put(bdev, NULL);
-	bdev = bdev2;
-	if (IS_ERR(bdev)) {
-		ret = PTR_ERR(bdev);
-		bdev = NULL;
+	bdev_handle2 = bdev_open_by_dev(bdev_handle->bdev->bd_dev,
+			BLK_OPEN_READ | BLK_OPEN_WRITE, holder, NULL);
+	bdev_release(bdev_handle);
+	bdev_handle = bdev_handle2;
+	if (IS_ERR(bdev_handle)) {
+		ret = PTR_ERR(bdev_handle);
+		bdev_handle = NULL;
 		if (ret == -EBUSY) {
 			dev_t dev;
 
@@ -2608,7 +2612,7 @@ static ssize_t register_bcache(struct kobject *k, struct kobj_attribute *attr,
 		args->path	= path;
 		args->sb	= sb;
 		args->sb_disk	= sb_disk;
-		args->bdev	= bdev;
+		args->bdev_handle	= bdev_handle;
 		args->holder	= holder;
 		register_device_async(args);
 		/* No wait and returns to user space */
@@ -2617,14 +2621,14 @@ static ssize_t register_bcache(struct kobject *k, struct kobj_attribute *attr,
 
 	if (SB_IS_BDEV(sb)) {
 		mutex_lock(&bch_register_lock);
-		ret = register_bdev(sb, sb_disk, bdev, holder);
+		ret = register_bdev(sb, sb_disk, bdev_handle, holder);
 		mutex_unlock(&bch_register_lock);
 		/* blkdev_put() will be called in cached_dev_free() */
 		if (ret < 0)
 			goto out_free_sb;
 	} else {
 		/* blkdev_put() will be called in bch_cache_release() */
-		ret = register_cache(sb, sb_disk, bdev, holder);
+		ret = register_cache(sb, sb_disk, bdev_handle, holder);
 		if (ret)
 			goto out_free_sb;
 	}
@@ -2640,8 +2644,8 @@ static ssize_t register_bcache(struct kobject *k, struct kobj_attribute *attr,
 out_put_sb_page:
 	put_page(virt_to_page(sb_disk));
 out_blkdev_put:
-	if (bdev)
-		blkdev_put(bdev, holder);
+	if (bdev_handle)
+		bdev_release(bdev_handle);
 out_free_sb:
 	kfree(sb);
 out_free_path:
-- 
2.35.3


^ permalink raw reply related	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2023-09-27  9:34 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-08-11 11:04 [PATCH v2 0/29] block: Make blkdev_get_by_*() return handle Jan Kara
2023-08-11 11:04 ` [PATCH 09/29] bcache: Convert to bdev_open_by_path() Jan Kara
2023-08-21  1:06   ` Eric Wheeler
2023-08-21 17:50     ` Jan Kara
2023-08-21 18:54       ` Eric Wheeler
2023-08-23 10:10         ` Coly Li
2023-08-11 12:27 ` [PATCH v2 0/29] block: Make blkdev_get_by_*() return handle Christoph Hellwig
2023-08-25  1:58 ` Al Viro
2023-08-25 13:47   ` Jan Kara
2023-08-26  2:28     ` Al Viro
2023-08-28 14:27       ` Christoph Hellwig
2023-08-28 13:20     ` Christian Brauner
2023-08-28 14:22     ` Christoph Hellwig
2023-08-23 10:48 [PATCH v3 " Jan Kara
2023-08-23 10:48 ` [PATCH 09/29] bcache: Convert to bdev_open_by_path() Jan Kara
2023-08-25 12:06   ` Christian Brauner
2023-09-27  9:34 ` Jan Kara

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).