linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCHES] ->bd_inode elimination
@ 2024-05-08  6:35 Al Viro
  2024-05-08  6:42 ` [PATCHES part 1 1/7] ext4: remove block_device_ejected() Al Viro
  2024-05-08  6:44 ` [PATCHES part 2 01/10] block_device: add a pointer to struct address_space (page cache of bdev) Al Viro
  0 siblings, 2 replies; 18+ messages in thread
From: Al Viro @ 2024-05-08  6:35 UTC (permalink / raw)
  To: linux-fsdevel; +Cc: Christian Brauner, Christoph Hellwig, Jens Axboe

There'd been several issues around struct block_device::bd_inode.

It points to coallocated inode and it's unpleasant in several respects.
We definitely need stuff that sits in that sucker, but we need a sane
set of primitives for accessing those.

I've a branch that does, among other things, have ->bd_inode eliminated;
see #bd_inode or #bdev (identical resulting trees) in viro/vfs.git for
the current state of that thing.  The problem is to do it with sane
topology, though.

First, a summary of ->bd_inode users:
	* most of them want the address_space of block device, which is
currently found as ->bd_inode->i_mapping, either directly or with minor
massage.  I've added ->bd_mapping for that.
	* there are several places where gendisk and partition code
wants to unhash or drop the coallocated inode.  Exposure is similar to
add_bdev(); I went for a couple of extra primitives with the same
visibility (bdev_unhash() and bdev_drop()).
	* there are users in block/bdev.c, where we know how block_device
and associated inode are allocated; there we can easily get ->bd_inode
value via container_of().  A couple of existing inline helpers can simply
move there (disk_live() and block_size(); neither is used on hot paths,
so the cost of call is not an issue).
	* there are places that implemented an equivalent of bdev_nr_bytes()
by reading ->i_size of associated inode.  Might as well use bdev_nr_bytes()
and be done with that.
	* 2 oddballs - nilfs_attach_log_writer() and dasd_format().  Both
want the associated inode.  I'm somewhat suspicious about the former
(looks like it might be a layering violation) and there's definitely
quite a few things wrong about the latter.  Neither is on the fast
path; I went for ->bd_mapping->host, admittedly unidiomatic there.
	* there's some outright dead code.

And that's it.  The main problem is keeping topology sane.  A part of
that had been in vfs/vfs.git#vfs.super, and the things would be easier
if we could replace that pile.

#work.bd_inode is the variant keeping vfs.super as-is; identical tree
with saner topology is in #work.bdev and IMO it makes a lot more sense.

#work.bdev starts at #work.set_blocksize (as posted); what follows is
	* cleanups, dead code elimination and adding missing primitives
7 commits, all but the last one reordered from current vfs.super;
some of that from me, some from Yu Kuai.  The tip of that is #work.bd_inode-0
	* merge-in of invariant branch with 2 erofs patches (#misc.erofs,
as posted and acked by erofs maintainer)
	* After that merge we have ->bd_mapping introduction and conversions,
handling of ->bd_inode users in block/bdev.c, followed by nilfs and s390
oddballs handling and finally removal of now-unused ->bd_inode.
That's #work.bd_inode-1.  Several of those are close to ones currently
in vfs.super.
	* merge with #work.bd_flags-2 (as posted).

Please, review.  Individual patches (on #work.bd_inode-{0,1}; #misc.erofs
and work.{set_blocksize,bd_flags-2} had been already posted) in followups.

I think the series makes more sense in this form; the downside is that
it replaces the current vfs/vfs.git#vfs.super, but AFAICS nothings other
than vfs.all pulls from that, so it's not too drastic.

Overall shortlog:
Al Viro (34):
      erofs: switch erofs_bread() to passing offset instead of block number
      erofs_buf: store address_space instead of inode
      bcache_register(): don't bother with set_blocksize()
      pktcdvd: sort set_blocksize() calls out
      swapon(2)/swapoff(2): don't bother with block size
      swapon(2): open swap with O_EXCL
      zram: don't bother with reopening - just use O_EXCL for open
      swsusp: don't bother with setting block size
      btrfs_get_bdev_and_sb(): call set_blocksize() only for exclusive opens
      set_blocksize(): switch to passing struct file *
      make set_blocksize() fail unless block device is opened exclusive
      Use bdev_is_paritition() instead of open-coding it
      wrapper for access to ->bd_partno
      bdev: infrastructure for flags
      bdev: move ->bd_read_only to ->__bd_flags
      bdev: move ->bd_write_holder into ->__bd_flags
      bdev: move ->bd_has_subit_bio to ->__bd_flags
      bdev: move ->bd_ro_warned to ->__bd_flags
      bdev: move ->bd_make_it_fail to ->__bd_flags
      blkdev_write_iter(): saner way to get inode and bdev
      dm-vdo: use bdev_nr_bytes(bdev) instead of i_size_read(bdev->bd_inode)
      missing helpers: bdev_unhash(), bdev_drop()
      Merge branch 'misc.erofs' into work.bdev
      block_device: add a pointer to struct address_space (page cache of bdev)
      use ->bd_mapping instead of ->bd_inode->i_mapping
      grow_dev_folio(): we only want ->bd_inode->i_mapping there
      blk_ioctl_{discard,zeroout}(): we only want ->bd_inode->i_mapping here...
      fs/buffer.c: massage the remaining users of ->bd_inode to ->bd_mapping
      gfs2: more obvious initializations of mapping->host
      block/bdev.c: use the knowledge of inode/bdev coallocation
      nilfs_attach_log_writer(): use ->bd_mapping->host instead of ->bd_inode
      dasd_format(): killing the last remaining user of ->bd_inode
      RIP ->bd_inode
      Merge branch 'work.bd_flags-2' into work.bdev

Yu Kuai (4):
      ext4: remove block_device_ejected()
      bcachefs: remove dead function bdev_sectors()
      block2mtd: prevent direct access of bd_inode
      block: move two helpers into bdev.c

Diffstat:

 Documentation/filesystems/porting.rst  |  7 +++
 block/bdev.c                           | 97 +++++++++++++++++++++++-----------
 block/blk-core.c                       | 17 +++---
 block/blk-mq.c                         |  2 +-
 block/blk-zoned.c                      |  4 +-
 block/blk.h                            |  2 +
 block/early-lookup.c                   |  2 +-
 block/fops.c                           |  4 +-
 block/genhd.c                          | 23 ++++----
 block/ioctl.c                          | 40 +++++++-------
 block/partitions/core.c                | 20 +++----
 drivers/block/pktcdvd.c                |  7 +--
 drivers/block/zram/zram_drv.c          | 29 +++-------
 drivers/block/zram/zram_drv.h          |  2 +-
 drivers/md/bcache/super.c              |  6 +--
 drivers/md/dm-vdo/dm-vdo-target.c      |  4 +-
 drivers/md/dm-vdo/indexer/io-factory.c |  2 +-
 drivers/mtd/devices/block2mtd.c        |  6 ++-
 drivers/s390/block/dasd_ioctl.c        |  2 +-
 drivers/scsi/scsicam.c                 |  2 +-
 fs/bcachefs/util.h                     |  5 --
 fs/btrfs/dev-replace.c                 |  2 +-
 fs/btrfs/disk-io.c                     |  6 +--
 fs/btrfs/volumes.c                     | 15 +++---
 fs/btrfs/zoned.c                       |  2 +-
 fs/buffer.c                            | 26 ++++-----
 fs/cramfs/inode.c                      |  2 +-
 fs/erofs/data.c                        | 12 ++---
 fs/erofs/dir.c                         |  4 +-
 fs/erofs/internal.h                    |  4 +-
 fs/erofs/namei.c                       |  6 +--
 fs/erofs/super.c                       |  8 +--
 fs/erofs/xattr.c                       | 37 +++++--------
 fs/erofs/zdata.c                       |  6 +--
 fs/ext4/dir.c                          |  2 +-
 fs/ext4/ext4_jbd2.c                    |  2 +-
 fs/ext4/super.c                        | 26 ++-------
 fs/gfs2/glock.c                        |  2 +-
 fs/gfs2/ops_fstype.c                   |  2 +-
 fs/jbd2/journal.c                      |  2 +-
 fs/nilfs2/segment.c                    |  2 +-
 fs/reiserfs/journal.c                  |  5 +-
 fs/xfs/xfs_buf.c                       |  2 +-
 include/linux/blk_types.h              | 19 +++----
 include/linux/blkdev.h                 | 40 +++++++++-----
 include/linux/buffer_head.h            |  4 +-
 include/linux/jbd2.h                   |  4 +-
 include/linux/part_stat.h              |  2 +-
 include/linux/swap.h                   |  2 -
 kernel/power/swap.c                    |  7 +--
 lib/vsprintf.c                         |  4 +-
 mm/swapfile.c                          | 29 +---------
 52 files changed, 275 insertions(+), 294 deletions(-)

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

* [PATCHES part 1 1/7] ext4: remove block_device_ejected()
  2024-05-08  6:35 [PATCHES] ->bd_inode elimination Al Viro
@ 2024-05-08  6:42 ` Al Viro
  2024-05-08  6:42   ` [PATCHES part 1 2/7] bcachefs: remove dead function bdev_sectors() Al Viro
                     ` (5 more replies)
  2024-05-08  6:44 ` [PATCHES part 2 01/10] block_device: add a pointer to struct address_space (page cache of bdev) Al Viro
  1 sibling, 6 replies; 18+ messages in thread
From: Al Viro @ 2024-05-08  6:42 UTC (permalink / raw)
  To: linux-fsdevel; +Cc: axboe, brauner, hch

From: Yu Kuai <yukuai3@huawei.com>

block_device_ejected() is added by commit bdfe0cbd746a ("Revert
"ext4: remove block_device_ejected"") in 2015. At that time 'bdi->wb'
is destroyed synchronized from del_gendisk(), hence if ext4 is still
mounted, and then mark_buffer_dirty() will reference destroyed 'wb'.
However, such problem doesn't exist anymore:

- commit d03f6cdc1fc4 ("block: Dynamically allocate and refcount
backing_dev_info") switch bdi to use refcounting;
- commit 13eec2363ef0 ("fs: Get proper reference for s_bdi"), will grab
additional reference of bdi while mounting, so that 'bdi->wb' will not
be destroyed until generic_shutdown_super().

Hence remove this dead function block_device_ejected().

Signed-off-by: Yu Kuai <yukuai3@huawei.com>
Reviewed-by: Jan Kara <jack@suse.cz>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Link: https://lore.kernel.org/r/20240411145346.2516848-7-viro@zeniv.linux.org.uk
Signed-off-by: Christian Brauner <brauner@kernel.org>
---
 fs/ext4/super.c | 18 ------------------
 1 file changed, 18 deletions(-)

diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 9988b3a40b42..b255f798f449 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -492,22 +492,6 @@ static void ext4_maybe_update_superblock(struct super_block *sb)
 		schedule_work(&EXT4_SB(sb)->s_sb_upd_work);
 }
 
-/*
- * The del_gendisk() function uninitializes the disk-specific data
- * structures, including the bdi structure, without telling anyone
- * else.  Once this happens, any attempt to call mark_buffer_dirty()
- * (for example, by ext4_commit_super), will cause a kernel OOPS.
- * This is a kludge to prevent these oops until we can put in a proper
- * hook in del_gendisk() to inform the VFS and file system layers.
- */
-static int block_device_ejected(struct super_block *sb)
-{
-	struct inode *bd_inode = sb->s_bdev->bd_inode;
-	struct backing_dev_info *bdi = inode_to_bdi(bd_inode);
-
-	return bdi->dev == NULL;
-}
-
 static void ext4_journal_commit_callback(journal_t *journal, transaction_t *txn)
 {
 	struct super_block		*sb = journal->j_private;
@@ -6172,8 +6156,6 @@ static int ext4_commit_super(struct super_block *sb)
 
 	if (!sbh)
 		return -EINVAL;
-	if (block_device_ejected(sb))
-		return -ENODEV;
 
 	ext4_update_super(sb);
 
-- 
2.39.2


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

* [PATCHES part 1 2/7] bcachefs: remove dead function bdev_sectors()
  2024-05-08  6:42 ` [PATCHES part 1 1/7] ext4: remove block_device_ejected() Al Viro
@ 2024-05-08  6:42   ` Al Viro
  2024-05-08  6:42   ` [PATCHES part 1 3/7] blkdev_write_iter(): saner way to get inode and bdev Al Viro
                     ` (4 subsequent siblings)
  5 siblings, 0 replies; 18+ messages in thread
From: Al Viro @ 2024-05-08  6:42 UTC (permalink / raw)
  To: linux-fsdevel; +Cc: axboe, brauner, hch

From: Yu Kuai <yukuai3@huawei.com>

bdev_sectors() is not used hence remove it.

Signed-off-by: Yu Kuai <yukuai3@huawei.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Jan Kara <jack@suse.cz>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Link: https://lore.kernel.org/r/20240411145346.2516848-10-viro@zeniv.linux.org.uk
Acked-by: Kent Overstreet <kent.overstreet@linux.dev>
Signed-off-by: Christian Brauner <brauner@kernel.org>
---
 fs/bcachefs/util.h | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/fs/bcachefs/util.h b/fs/bcachefs/util.h
index 5cf885b09986..5d2c470a49ac 100644
--- a/fs/bcachefs/util.h
+++ b/fs/bcachefs/util.h
@@ -445,11 +445,6 @@ static inline unsigned fract_exp_two(unsigned x, unsigned fract_bits)
 void bch2_bio_map(struct bio *bio, void *base, size_t);
 int bch2_bio_alloc_pages(struct bio *, size_t, gfp_t);
 
-static inline sector_t bdev_sectors(struct block_device *bdev)
-{
-	return bdev->bd_inode->i_size >> 9;
-}
-
 #define closure_bio_submit(bio, cl)					\
 do {									\
 	closure_get(cl);						\
-- 
2.39.2


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

* [PATCHES part 1 3/7] blkdev_write_iter(): saner way to get inode and bdev
  2024-05-08  6:42 ` [PATCHES part 1 1/7] ext4: remove block_device_ejected() Al Viro
  2024-05-08  6:42   ` [PATCHES part 1 2/7] bcachefs: remove dead function bdev_sectors() Al Viro
@ 2024-05-08  6:42   ` Al Viro
  2024-05-08  6:42   ` [PATCHES part 1 4/7] dm-vdo: use bdev_nr_bytes(bdev) instead of i_size_read(bdev->bd_inode) Al Viro
                     ` (3 subsequent siblings)
  5 siblings, 0 replies; 18+ messages in thread
From: Al Viro @ 2024-05-08  6:42 UTC (permalink / raw)
  To: linux-fsdevel; +Cc: axboe, brauner, hch

... same as in other methods - bdev_file_inode() and I_BDEV() of that.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Link: https://lore.kernel.org/r/20240411145346.2516848-5-viro@zeniv.linux.org.uk
Signed-off-by: Christian Brauner <brauner@kernel.org>
---
 block/fops.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/block/fops.c b/block/fops.c
index 679d9b752fe8..9d0f36688a5d 100644
--- a/block/fops.c
+++ b/block/fops.c
@@ -668,8 +668,8 @@ static ssize_t blkdev_buffered_write(struct kiocb *iocb, struct iov_iter *from)
 static ssize_t blkdev_write_iter(struct kiocb *iocb, struct iov_iter *from)
 {
 	struct file *file = iocb->ki_filp;
-	struct block_device *bdev = I_BDEV(file->f_mapping->host);
-	struct inode *bd_inode = bdev->bd_inode;
+	struct inode *bd_inode = bdev_file_inode(file);
+	struct block_device *bdev = I_BDEV(bd_inode);
 	loff_t size = bdev_nr_bytes(bdev);
 	size_t shorted = 0;
 	ssize_t ret;
-- 
2.39.2


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

* [PATCHES part 1 4/7] dm-vdo: use bdev_nr_bytes(bdev) instead of i_size_read(bdev->bd_inode)
  2024-05-08  6:42 ` [PATCHES part 1 1/7] ext4: remove block_device_ejected() Al Viro
  2024-05-08  6:42   ` [PATCHES part 1 2/7] bcachefs: remove dead function bdev_sectors() Al Viro
  2024-05-08  6:42   ` [PATCHES part 1 3/7] blkdev_write_iter(): saner way to get inode and bdev Al Viro
@ 2024-05-08  6:42   ` Al Viro
  2024-05-08  6:42   ` [PATCHES part 1 5/7] block2mtd: prevent direct access of bd_inode Al Viro
                     ` (2 subsequent siblings)
  5 siblings, 0 replies; 18+ messages in thread
From: Al Viro @ 2024-05-08  6:42 UTC (permalink / raw)
  To: linux-fsdevel; +Cc: axboe, brauner, hch

going to be faster, actually - shift is cheaper than dereference...

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Link: https://lore.kernel.org/r/20240411145346.2516848-9-viro@zeniv.linux.org.uk
Reviewed-by: Matthew Sakai <msakai@redhat.com>
Signed-off-by: Christian Brauner <brauner@kernel.org>
---
 drivers/md/dm-vdo/dm-vdo-target.c      | 4 ++--
 drivers/md/dm-vdo/indexer/io-factory.c | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/md/dm-vdo/dm-vdo-target.c b/drivers/md/dm-vdo/dm-vdo-target.c
index 5a4b0a927f56..b423bec6458b 100644
--- a/drivers/md/dm-vdo/dm-vdo-target.c
+++ b/drivers/md/dm-vdo/dm-vdo-target.c
@@ -878,7 +878,7 @@ static int parse_device_config(int argc, char **argv, struct dm_target *ti,
 	}
 
 	if (config->version == 0) {
-		u64 device_size = i_size_read(config->owned_device->bdev->bd_inode);
+		u64 device_size = bdev_nr_bytes(config->owned_device->bdev);
 
 		config->physical_blocks = device_size / VDO_BLOCK_SIZE;
 	}
@@ -1011,7 +1011,7 @@ static void vdo_status(struct dm_target *ti, status_type_t status_type,
 
 static block_count_t __must_check get_underlying_device_block_count(const struct vdo *vdo)
 {
-	return i_size_read(vdo_get_backing_device(vdo)->bd_inode) / VDO_BLOCK_SIZE;
+	return bdev_nr_bytes(vdo_get_backing_device(vdo)) / VDO_BLOCK_SIZE;
 }
 
 static int __must_check process_vdo_message_locked(struct vdo *vdo, unsigned int argc,
diff --git a/drivers/md/dm-vdo/indexer/io-factory.c b/drivers/md/dm-vdo/indexer/io-factory.c
index 515765d35794..1bee9d63dc0a 100644
--- a/drivers/md/dm-vdo/indexer/io-factory.c
+++ b/drivers/md/dm-vdo/indexer/io-factory.c
@@ -90,7 +90,7 @@ void uds_put_io_factory(struct io_factory *factory)
 
 size_t uds_get_writable_size(struct io_factory *factory)
 {
-	return i_size_read(factory->bdev->bd_inode);
+	return bdev_nr_bytes(factory->bdev);
 }
 
 /* Create a struct dm_bufio_client for an index region starting at offset. */
-- 
2.39.2


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

* [PATCHES part 1 5/7] block2mtd: prevent direct access of bd_inode
  2024-05-08  6:42 ` [PATCHES part 1 1/7] ext4: remove block_device_ejected() Al Viro
                     ` (2 preceding siblings ...)
  2024-05-08  6:42   ` [PATCHES part 1 4/7] dm-vdo: use bdev_nr_bytes(bdev) instead of i_size_read(bdev->bd_inode) Al Viro
@ 2024-05-08  6:42   ` Al Viro
  2024-05-08  6:43   ` [PATCHES part 1 6/7] block: move two helpers into bdev.c Al Viro
  2024-05-08  6:43   ` [PATCHES part 1 7/7] missing helpers: bdev_unhash(), bdev_drop() Al Viro
  5 siblings, 0 replies; 18+ messages in thread
From: Al Viro @ 2024-05-08  6:42 UTC (permalink / raw)
  To: linux-fsdevel; +Cc: axboe, brauner, hch

From: Yu Kuai <yukuai3@huawei.com>

All we need is size, and that can be obtained via bdev_nr_bytes()

Signed-off-by: Yu Kuai <yukuai3@huawei.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Jan Kara <jack@suse.cz>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Link: https://lore.kernel.org/r/20240411145346.2516848-11-viro@zeniv.linux.org.uk
Signed-off-by: Christian Brauner <brauner@kernel.org>
---
 drivers/mtd/devices/block2mtd.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/mtd/devices/block2mtd.c b/drivers/mtd/devices/block2mtd.c
index caacdc0a3819..b06c8dd51562 100644
--- a/drivers/mtd/devices/block2mtd.c
+++ b/drivers/mtd/devices/block2mtd.c
@@ -265,6 +265,7 @@ static struct block2mtd_dev *add_device(char *devname, int erase_size,
 	struct file *bdev_file;
 	struct block_device *bdev;
 	struct block2mtd_dev *dev;
+	loff_t size;
 	char *name;
 
 	if (!devname)
@@ -291,7 +292,8 @@ static struct block2mtd_dev *add_device(char *devname, int erase_size,
 		goto err_free_block2mtd;
 	}
 
-	if ((long)bdev->bd_inode->i_size % erase_size) {
+	size = bdev_nr_bytes(bdev);
+	if ((long)size % erase_size) {
 		pr_err("erasesize must be a divisor of device size\n");
 		goto err_free_block2mtd;
 	}
@@ -309,7 +311,7 @@ static struct block2mtd_dev *add_device(char *devname, int erase_size,
 
 	dev->mtd.name = name;
 
-	dev->mtd.size = bdev->bd_inode->i_size & PAGE_MASK;
+	dev->mtd.size = size & PAGE_MASK;
 	dev->mtd.erasesize = erase_size;
 	dev->mtd.writesize = 1;
 	dev->mtd.writebufsize = PAGE_SIZE;
-- 
2.39.2


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

* [PATCHES part 1 6/7] block: move two helpers into bdev.c
  2024-05-08  6:42 ` [PATCHES part 1 1/7] ext4: remove block_device_ejected() Al Viro
                     ` (3 preceding siblings ...)
  2024-05-08  6:42   ` [PATCHES part 1 5/7] block2mtd: prevent direct access of bd_inode Al Viro
@ 2024-05-08  6:43   ` Al Viro
  2024-05-08  6:43   ` [PATCHES part 1 7/7] missing helpers: bdev_unhash(), bdev_drop() Al Viro
  5 siblings, 0 replies; 18+ messages in thread
From: Al Viro @ 2024-05-08  6:43 UTC (permalink / raw)
  To: linux-fsdevel; +Cc: axboe, brauner, hch

From: Yu Kuai <yukuai3@huawei.com>

disk_live() and block_size() access bd_inode directly, prepare to remove
the field bd_inode from block_device, and only access bd_inode in block
layer.

Signed-off-by: Yu Kuai <yukuai3@huawei.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Jan Kara <jack@suse.cz>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Link: https://lore.kernel.org/r/20240411145346.2516848-8-viro@zeniv.linux.org.uk
Signed-off-by: Christian Brauner <brauner@kernel.org>
---
 block/bdev.c           | 12 ++++++++++++
 include/linux/blkdev.h | 12 ++----------
 2 files changed, 14 insertions(+), 10 deletions(-)

diff --git a/block/bdev.c b/block/bdev.c
index a89bce368b64..536233ac3e99 100644
--- a/block/bdev.c
+++ b/block/bdev.c
@@ -1257,6 +1257,18 @@ void bdev_statx_dioalign(struct inode *inode, struct kstat *stat)
 	blkdev_put_no_open(bdev);
 }
 
+bool disk_live(struct gendisk *disk)
+{
+	return !inode_unhashed(disk->part0->bd_inode);
+}
+EXPORT_SYMBOL_GPL(disk_live);
+
+unsigned int block_size(struct block_device *bdev)
+{
+	return 1 << bdev->bd_inode->i_blkbits;
+}
+EXPORT_SYMBOL_GPL(block_size);
+
 static int __init setup_bdev_allow_write_mounted(char *str)
 {
 	if (kstrtobool(str, &bdev_allow_write_mounted))
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 20c749b2ebc2..99ac98ed9548 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -211,11 +211,6 @@ struct gendisk {
 	struct blk_independent_access_ranges *ia_ranges;
 };
 
-static inline bool disk_live(struct gendisk *disk)
-{
-	return !inode_unhashed(disk->part0->bd_inode);
-}
-
 /**
  * disk_openers - returns how many openers are there for a disk
  * @disk: disk to check
@@ -1364,11 +1359,6 @@ static inline unsigned int blksize_bits(unsigned int size)
 	return order_base_2(size >> SECTOR_SHIFT) + SECTOR_SHIFT;
 }
 
-static inline unsigned int block_size(struct block_device *bdev)
-{
-	return 1 << bdev->bd_inode->i_blkbits;
-}
-
 int kblockd_schedule_work(struct work_struct *work);
 int kblockd_mod_delayed_work_on(int cpu, struct delayed_work *dwork, unsigned long delay);
 
@@ -1536,6 +1526,8 @@ void blkdev_put_no_open(struct block_device *bdev);
 
 struct block_device *I_BDEV(struct inode *inode);
 struct block_device *file_bdev(struct file *bdev_file);
+bool disk_live(struct gendisk *disk);
+unsigned int block_size(struct block_device *bdev);
 
 #ifdef CONFIG_BLOCK
 void invalidate_bdev(struct block_device *bdev);
-- 
2.39.2


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

* [PATCHES part 1 7/7] missing helpers: bdev_unhash(), bdev_drop()
  2024-05-08  6:42 ` [PATCHES part 1 1/7] ext4: remove block_device_ejected() Al Viro
                     ` (4 preceding siblings ...)
  2024-05-08  6:43   ` [PATCHES part 1 6/7] block: move two helpers into bdev.c Al Viro
@ 2024-05-08  6:43   ` Al Viro
  5 siblings, 0 replies; 18+ messages in thread
From: Al Viro @ 2024-05-08  6:43 UTC (permalink / raw)
  To: linux-fsdevel; +Cc: axboe, brauner, hch

bdev_unhash(): make block device invisible to lookups by device number
bdev_drop(): drop reference to associated inode.

Both are internal, for use by genhd and partition-related code - similar
to bdev_add().  The logics in there (especially the lifetime-related
parts of it) ought to be cleaned up, but that's a separate story; here
we just encapsulate getting to associated inode.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 block/bdev.c            | 10 ++++++++++
 block/blk.h             |  2 ++
 block/genhd.c           |  6 +++---
 block/partitions/core.c |  6 +++---
 4 files changed, 18 insertions(+), 6 deletions(-)

diff --git a/block/bdev.c b/block/bdev.c
index 536233ac3e99..28e6f0423857 100644
--- a/block/bdev.c
+++ b/block/bdev.c
@@ -451,6 +451,16 @@ void bdev_add(struct block_device *bdev, dev_t dev)
 	insert_inode_hash(bdev->bd_inode);
 }
 
+void bdev_unhash(struct block_device *bdev)
+{
+	remove_inode_hash(bdev->bd_inode);
+}
+
+void bdev_drop(struct block_device *bdev)
+{
+	iput(bdev->bd_inode);
+}
+
 long nr_blockdev_pages(void)
 {
 	struct inode *inode;
diff --git a/block/blk.h b/block/blk.h
index d9f584984bc4..e3347e1030d5 100644
--- a/block/blk.h
+++ b/block/blk.h
@@ -428,6 +428,8 @@ static inline int blkdev_zone_mgmt_ioctl(struct block_device *bdev,
 
 struct block_device *bdev_alloc(struct gendisk *disk, u8 partno);
 void bdev_add(struct block_device *bdev, dev_t dev);
+void bdev_unhash(struct block_device *bdev);
+void bdev_drop(struct block_device *bdev);
 
 int blk_alloc_ext_minor(void);
 void blk_free_ext_minor(unsigned int minor);
diff --git a/block/genhd.c b/block/genhd.c
index bb29a68e1d67..93f5118b7d41 100644
--- a/block/genhd.c
+++ b/block/genhd.c
@@ -656,7 +656,7 @@ void del_gendisk(struct gendisk *disk)
 	 */
 	mutex_lock(&disk->open_mutex);
 	xa_for_each(&disk->part_tbl, idx, part)
-		remove_inode_hash(part->bd_inode);
+		bdev_unhash(part);
 	mutex_unlock(&disk->open_mutex);
 
 	/*
@@ -1191,7 +1191,7 @@ static void disk_release(struct device *dev)
 	if (test_bit(GD_ADDED, &disk->state) && disk->fops->free_disk)
 		disk->fops->free_disk(disk);
 
-	iput(disk->part0->bd_inode);	/* frees the disk */
+	bdev_drop(disk->part0);	/* frees the disk */
 }
 
 static int block_uevent(const struct device *dev, struct kobj_uevent_env *env)
@@ -1381,7 +1381,7 @@ struct gendisk *__alloc_disk_node(struct request_queue *q, int node_id,
 out_destroy_part_tbl:
 	xa_destroy(&disk->part_tbl);
 	disk->part0->bd_disk = NULL;
-	iput(disk->part0->bd_inode);
+	bdev_drop(disk->part0);
 out_free_bdi:
 	bdi_put(disk->bdi);
 out_free_bioset:
diff --git a/block/partitions/core.c b/block/partitions/core.c
index b11e88c82c8c..2b75e325c63b 100644
--- a/block/partitions/core.c
+++ b/block/partitions/core.c
@@ -243,7 +243,7 @@ static const struct attribute_group *part_attr_groups[] = {
 static void part_release(struct device *dev)
 {
 	put_disk(dev_to_bdev(dev)->bd_disk);
-	iput(dev_to_bdev(dev)->bd_inode);
+	bdev_drop(dev_to_bdev(dev));
 }
 
 static int part_uevent(const struct device *dev, struct kobj_uevent_env *env)
@@ -469,7 +469,7 @@ int bdev_del_partition(struct gendisk *disk, int partno)
 	 * Just delete the partition and invalidate it.
 	 */
 
-	remove_inode_hash(part->bd_inode);
+	bdev_unhash(part);
 	invalidate_bdev(part);
 	drop_partition(part);
 	ret = 0;
@@ -655,7 +655,7 @@ int bdev_disk_changed(struct gendisk *disk, bool invalidate)
 		 * it cannot be looked up any more even when openers
 		 * still hold references.
 		 */
-		remove_inode_hash(part->bd_inode);
+		bdev_unhash(part);
 
 		/*
 		 * If @disk->open_partitions isn't elevated but there's
-- 
2.39.2


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

* [PATCHES part 2 01/10] block_device: add a pointer to struct address_space (page cache of bdev)
  2024-05-08  6:35 [PATCHES] ->bd_inode elimination Al Viro
  2024-05-08  6:42 ` [PATCHES part 1 1/7] ext4: remove block_device_ejected() Al Viro
@ 2024-05-08  6:44 ` Al Viro
  2024-05-08  6:44   ` [PATCHES part 2 02/10] use ->bd_mapping instead of ->bd_inode->i_mapping Al Viro
                     ` (8 more replies)
  1 sibling, 9 replies; 18+ messages in thread
From: Al Viro @ 2024-05-08  6:44 UTC (permalink / raw)
  To: linux-fsdevel; +Cc: axboe, brauner, hch

points to ->i_data of coallocated inode.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Link: https://lore.kernel.org/r/20240411145346.2516848-1-viro@zeniv.linux.org.uk
Signed-off-by: Christian Brauner <brauner@kernel.org>
---
 block/bdev.c              | 1 +
 include/linux/blk_types.h | 1 +
 2 files changed, 2 insertions(+)

diff --git a/block/bdev.c b/block/bdev.c
index 28e6f0423857..8e19101cbbb0 100644
--- a/block/bdev.c
+++ b/block/bdev.c
@@ -419,6 +419,7 @@ struct block_device *bdev_alloc(struct gendisk *disk, u8 partno)
 	mutex_init(&bdev->bd_holder_lock);
 	bdev->bd_partno = partno;
 	bdev->bd_inode = inode;
+	bdev->bd_mapping = &inode->i_data;
 	bdev->bd_queue = disk->queue;
 	if (partno)
 		bdev->bd_has_submit_bio = disk->part0->bd_has_submit_bio;
diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h
index cb1526ec44b5..6438c75cbb35 100644
--- a/include/linux/blk_types.h
+++ b/include/linux/blk_types.h
@@ -51,6 +51,7 @@ struct block_device {
 	bool			bd_has_submit_bio;
 	dev_t			bd_dev;
 	struct inode		*bd_inode;	/* will die */
+	struct address_space	*bd_mapping;	/* page cache */
 
 	atomic_t		bd_openers;
 	spinlock_t		bd_size_lock; /* for bd_inode->i_size updates */
-- 
2.39.2


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

* [PATCHES part 2 02/10] use ->bd_mapping instead of ->bd_inode->i_mapping
  2024-05-08  6:44 ` [PATCHES part 2 01/10] block_device: add a pointer to struct address_space (page cache of bdev) Al Viro
@ 2024-05-08  6:44   ` Al Viro
  2024-05-08  6:44   ` [PATCHES part 2 03/10] grow_dev_folio(): we only want ->bd_inode->i_mapping there Al Viro
                     ` (7 subsequent siblings)
  8 siblings, 0 replies; 18+ messages in thread
From: Al Viro @ 2024-05-08  6:44 UTC (permalink / raw)
  To: linux-fsdevel; +Cc: axboe, brauner, hch

Just the low-hanging fruit...

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Link: https://lore.kernel.org/r/20240411145346.2516848-2-viro@zeniv.linux.org.uk
Signed-off-by: Christian Brauner <brauner@kernel.org>
---
 block/bdev.c                | 18 +++++++++---------
 block/blk-zoned.c           |  4 ++--
 block/genhd.c               |  2 +-
 block/ioctl.c               |  4 ++--
 block/partitions/core.c     |  2 +-
 drivers/md/bcache/super.c   |  2 +-
 drivers/scsi/scsicam.c      |  2 +-
 fs/btrfs/disk-io.c          |  6 +++---
 fs/btrfs/volumes.c          |  2 +-
 fs/btrfs/zoned.c            |  2 +-
 fs/buffer.c                 |  2 +-
 fs/cramfs/inode.c           |  2 +-
 fs/erofs/data.c             |  2 +-
 fs/ext4/dir.c               |  2 +-
 fs/ext4/ext4_jbd2.c         |  2 +-
 fs/ext4/super.c             |  6 +++---
 fs/jbd2/journal.c           |  2 +-
 include/linux/buffer_head.h |  4 ++--
 include/linux/jbd2.h        |  4 ++--
 19 files changed, 35 insertions(+), 35 deletions(-)

diff --git a/block/bdev.c b/block/bdev.c
index 8e19101cbbb0..00017af92a51 100644
--- a/block/bdev.c
+++ b/block/bdev.c
@@ -76,7 +76,7 @@ static void bdev_write_inode(struct block_device *bdev)
 /* Kill _all_ buffers and pagecache , dirty or not.. */
 static void kill_bdev(struct block_device *bdev)
 {
-	struct address_space *mapping = bdev->bd_inode->i_mapping;
+	struct address_space *mapping = bdev->bd_mapping;
 
 	if (mapping_empty(mapping))
 		return;
@@ -88,7 +88,7 @@ static void kill_bdev(struct block_device *bdev)
 /* Invalidate clean unused buffers and pagecache. */
 void invalidate_bdev(struct block_device *bdev)
 {
-	struct address_space *mapping = bdev->bd_inode->i_mapping;
+	struct address_space *mapping = bdev->bd_mapping;
 
 	if (mapping->nrpages) {
 		invalidate_bh_lrus();
@@ -116,7 +116,7 @@ int truncate_bdev_range(struct block_device *bdev, blk_mode_t mode,
 			goto invalidate;
 	}
 
-	truncate_inode_pages_range(bdev->bd_inode->i_mapping, lstart, lend);
+	truncate_inode_pages_range(bdev->bd_mapping, lstart, lend);
 	if (!(mode & BLK_OPEN_EXCL))
 		bd_abort_claiming(bdev, truncate_bdev_range);
 	return 0;
@@ -126,7 +126,7 @@ int truncate_bdev_range(struct block_device *bdev, blk_mode_t mode,
 	 * Someone else has handle exclusively open. Try invalidating instead.
 	 * The 'end' argument is inclusive so the rounding is safe.
 	 */
-	return invalidate_inode_pages2_range(bdev->bd_inode->i_mapping,
+	return invalidate_inode_pages2_range(bdev->bd_mapping,
 					     lstart >> PAGE_SHIFT,
 					     lend >> PAGE_SHIFT);
 }
@@ -198,7 +198,7 @@ int sync_blockdev_nowait(struct block_device *bdev)
 {
 	if (!bdev)
 		return 0;
-	return filemap_flush(bdev->bd_inode->i_mapping);
+	return filemap_flush(bdev->bd_mapping);
 }
 EXPORT_SYMBOL_GPL(sync_blockdev_nowait);
 
@@ -210,13 +210,13 @@ int sync_blockdev(struct block_device *bdev)
 {
 	if (!bdev)
 		return 0;
-	return filemap_write_and_wait(bdev->bd_inode->i_mapping);
+	return filemap_write_and_wait(bdev->bd_mapping);
 }
 EXPORT_SYMBOL(sync_blockdev);
 
 int sync_blockdev_range(struct block_device *bdev, loff_t lstart, loff_t lend)
 {
-	return filemap_write_and_wait_range(bdev->bd_inode->i_mapping,
+	return filemap_write_and_wait_range(bdev->bd_mapping,
 			lstart, lend);
 }
 EXPORT_SYMBOL(sync_blockdev_range);
@@ -445,7 +445,7 @@ void bdev_set_nr_sectors(struct block_device *bdev, sector_t sectors)
 void bdev_add(struct block_device *bdev, dev_t dev)
 {
 	if (bdev_stable_writes(bdev))
-		mapping_set_stable_writes(bdev->bd_inode->i_mapping);
+		mapping_set_stable_writes(bdev->bd_mapping);
 	bdev->bd_dev = dev;
 	bdev->bd_inode->i_rdev = dev;
 	bdev->bd_inode->i_ino = dev;
@@ -925,7 +925,7 @@ int bdev_open(struct block_device *bdev, blk_mode_t mode, void *holder,
 		bdev_file->f_mode |= FMODE_NOWAIT;
 	if (mode & BLK_OPEN_RESTRICT_WRITES)
 		bdev_file->f_mode |= FMODE_WRITE_RESTRICTED;
-	bdev_file->f_mapping = bdev->bd_inode->i_mapping;
+	bdev_file->f_mapping = bdev->bd_mapping;
 	bdev_file->f_wb_err = filemap_sample_wb_err(bdev_file->f_mapping);
 	bdev_file->private_data = holder;
 
diff --git a/block/blk-zoned.c b/block/blk-zoned.c
index da0f4b2a8fa0..b008bcd4889c 100644
--- a/block/blk-zoned.c
+++ b/block/blk-zoned.c
@@ -398,7 +398,7 @@ int blkdev_zone_mgmt_ioctl(struct block_device *bdev, blk_mode_t mode,
 		op = REQ_OP_ZONE_RESET;
 
 		/* Invalidate the page cache, including dirty pages. */
-		filemap_invalidate_lock(bdev->bd_inode->i_mapping);
+		filemap_invalidate_lock(bdev->bd_mapping);
 		ret = blkdev_truncate_zone_range(bdev, mode, &zrange);
 		if (ret)
 			goto fail;
@@ -420,7 +420,7 @@ int blkdev_zone_mgmt_ioctl(struct block_device *bdev, blk_mode_t mode,
 
 fail:
 	if (cmd == BLKRESETZONE)
-		filemap_invalidate_unlock(bdev->bd_inode->i_mapping);
+		filemap_invalidate_unlock(bdev->bd_mapping);
 
 	return ret;
 }
diff --git a/block/genhd.c b/block/genhd.c
index 93f5118b7d41..2bf05bd0f071 100644
--- a/block/genhd.c
+++ b/block/genhd.c
@@ -745,7 +745,7 @@ void invalidate_disk(struct gendisk *disk)
 	struct block_device *bdev = disk->part0;
 
 	invalidate_bdev(bdev);
-	bdev->bd_inode->i_mapping->wb_err = 0;
+	bdev->bd_mapping->wb_err = 0;
 	set_capacity(disk, 0);
 }
 EXPORT_SYMBOL(invalidate_disk);
diff --git a/block/ioctl.c b/block/ioctl.c
index 1c800364bc70..7c13d8bed453 100644
--- a/block/ioctl.c
+++ b/block/ioctl.c
@@ -152,12 +152,12 @@ static int blk_ioctl_secure_erase(struct block_device *bdev, blk_mode_t mode,
 	if (start + len > bdev_nr_bytes(bdev))
 		return -EINVAL;
 
-	filemap_invalidate_lock(bdev->bd_inode->i_mapping);
+	filemap_invalidate_lock(bdev->bd_mapping);
 	err = truncate_bdev_range(bdev, mode, start, start + len - 1);
 	if (!err)
 		err = blkdev_issue_secure_erase(bdev, start >> 9, len >> 9,
 						GFP_KERNEL);
-	filemap_invalidate_unlock(bdev->bd_inode->i_mapping);
+	filemap_invalidate_unlock(bdev->bd_mapping);
 	return err;
 }
 
diff --git a/block/partitions/core.c b/block/partitions/core.c
index 2b75e325c63b..63ee317dfff0 100644
--- a/block/partitions/core.c
+++ b/block/partitions/core.c
@@ -704,7 +704,7 @@ EXPORT_SYMBOL_GPL(bdev_disk_changed);
 
 void *read_part_sector(struct parsed_partitions *state, sector_t n, Sector *p)
 {
-	struct address_space *mapping = state->disk->part0->bd_inode->i_mapping;
+	struct address_space *mapping = state->disk->part0->bd_mapping;
 	struct folio *folio;
 
 	if (n >= get_capacity(state->disk)) {
diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c
index 0ee5e17ae2dd..277ad958cf53 100644
--- a/drivers/md/bcache/super.c
+++ b/drivers/md/bcache/super.c
@@ -171,7 +171,7 @@ static const char *read_super(struct cache_sb *sb, struct block_device *bdev,
 	struct page *page;
 	unsigned int i;
 
-	page = read_cache_page_gfp(bdev->bd_inode->i_mapping,
+	page = read_cache_page_gfp(bdev->bd_mapping,
 				   SB_OFFSET >> PAGE_SHIFT, GFP_KERNEL);
 	if (IS_ERR(page))
 		return "IO error";
diff --git a/drivers/scsi/scsicam.c b/drivers/scsi/scsicam.c
index e2c7d8ef205f..dd69342bbe78 100644
--- a/drivers/scsi/scsicam.c
+++ b/drivers/scsi/scsicam.c
@@ -32,7 +32,7 @@
  */
 unsigned char *scsi_bios_ptable(struct block_device *dev)
 {
-	struct address_space *mapping = bdev_whole(dev)->bd_inode->i_mapping;
+	struct address_space *mapping = bdev_whole(dev)->bd_mapping;
 	unsigned char *res = NULL;
 	struct folio *folio;
 
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 3df5477d48a8..f10e894b0bf5 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -3651,7 +3651,7 @@ struct btrfs_super_block *btrfs_read_dev_one_super(struct block_device *bdev,
 	struct btrfs_super_block *super;
 	struct page *page;
 	u64 bytenr, bytenr_orig;
-	struct address_space *mapping = bdev->bd_inode->i_mapping;
+	struct address_space *mapping = bdev->bd_mapping;
 	int ret;
 
 	bytenr_orig = btrfs_sb_offset(copy_num);
@@ -3738,7 +3738,7 @@ static int write_dev_supers(struct btrfs_device *device,
 			    struct btrfs_super_block *sb, int max_mirrors)
 {
 	struct btrfs_fs_info *fs_info = device->fs_info;
-	struct address_space *mapping = device->bdev->bd_inode->i_mapping;
+	struct address_space *mapping = device->bdev->bd_mapping;
 	SHASH_DESC_ON_STACK(shash, fs_info->csum_shash);
 	int i;
 	int errors = 0;
@@ -3855,7 +3855,7 @@ static int wait_dev_supers(struct btrfs_device *device, int max_mirrors)
 		    device->commit_total_bytes)
 			break;
 
-		page = find_get_page(device->bdev->bd_inode->i_mapping,
+		page = find_get_page(device->bdev->bd_mapping,
 				     bytenr >> PAGE_SHIFT);
 		if (!page) {
 			errors++;
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 65c03ddecc59..33d357e5f9c5 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -1290,7 +1290,7 @@ static struct btrfs_super_block *btrfs_read_disk_super(struct block_device *bdev
 		return ERR_PTR(-EINVAL);
 
 	/* pull in the page with our super */
-	page = read_cache_page_gfp(bdev->bd_inode->i_mapping, index, GFP_KERNEL);
+	page = read_cache_page_gfp(bdev->bd_mapping, index, GFP_KERNEL);
 
 	if (IS_ERR(page))
 		return ERR_CAST(page);
diff --git a/fs/btrfs/zoned.c b/fs/btrfs/zoned.c
index 4cba80b34387..9b43fa493219 100644
--- a/fs/btrfs/zoned.c
+++ b/fs/btrfs/zoned.c
@@ -118,7 +118,7 @@ static int sb_write_pointer(struct block_device *bdev, struct blk_zone *zones,
 		return -ENOENT;
 	} else if (full[0] && full[1]) {
 		/* Compare two super blocks */
-		struct address_space *mapping = bdev->bd_inode->i_mapping;
+		struct address_space *mapping = bdev->bd_mapping;
 		struct page *page[BTRFS_NR_SB_LOG_ZONES];
 		struct btrfs_super_block *super[BTRFS_NR_SB_LOG_ZONES];
 		int i;
diff --git a/fs/buffer.c b/fs/buffer.c
index 4f73d23c2c46..d5a0932ae68d 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -1463,7 +1463,7 @@ __bread_gfp(struct block_device *bdev, sector_t block,
 {
 	struct buffer_head *bh;
 
-	gfp |= mapping_gfp_constraint(bdev->bd_inode->i_mapping, ~__GFP_FS);
+	gfp |= mapping_gfp_constraint(bdev->bd_mapping, ~__GFP_FS);
 
 	/*
 	 * Prefer looping in the allocator rather than here, at least that
diff --git a/fs/cramfs/inode.c b/fs/cramfs/inode.c
index 9901057a15ba..460690ca0174 100644
--- a/fs/cramfs/inode.c
+++ b/fs/cramfs/inode.c
@@ -183,7 +183,7 @@ static int next_buffer;
 static void *cramfs_blkdev_read(struct super_block *sb, unsigned int offset,
 				unsigned int len)
 {
-	struct address_space *mapping = sb->s_bdev->bd_inode->i_mapping;
+	struct address_space *mapping = sb->s_bdev->bd_mapping;
 	struct file_ra_state ra = {};
 	struct page *pages[BLKS_PER_BUF];
 	unsigned i, blocknr, buffer;
diff --git a/fs/erofs/data.c b/fs/erofs/data.c
index e1a170e45c70..5fc03c1e2757 100644
--- a/fs/erofs/data.c
+++ b/fs/erofs/data.c
@@ -68,7 +68,7 @@ void erofs_init_metabuf(struct erofs_buf *buf, struct super_block *sb)
 	if (erofs_is_fscache_mode(sb))
 		buf->mapping = EROFS_SB(sb)->s_fscache->inode->i_mapping;
 	else
-		buf->mapping = sb->s_bdev->bd_inode->i_mapping;
+		buf->mapping = sb->s_bdev->bd_mapping;
 }
 
 void *erofs_read_metabuf(struct erofs_buf *buf, struct super_block *sb,
diff --git a/fs/ext4/dir.c b/fs/ext4/dir.c
index 3985f8c33f95..ff4514e4626b 100644
--- a/fs/ext4/dir.c
+++ b/fs/ext4/dir.c
@@ -192,7 +192,7 @@ static int ext4_readdir(struct file *file, struct dir_context *ctx)
 					(PAGE_SHIFT - inode->i_blkbits);
 			if (!ra_has_index(&file->f_ra, index))
 				page_cache_sync_readahead(
-					sb->s_bdev->bd_inode->i_mapping,
+					sb->s_bdev->bd_mapping,
 					&file->f_ra, file,
 					index, 1);
 			file->f_ra.prev_pos = (loff_t)index << PAGE_SHIFT;
diff --git a/fs/ext4/ext4_jbd2.c b/fs/ext4/ext4_jbd2.c
index 5d8055161acd..da4a82456383 100644
--- a/fs/ext4/ext4_jbd2.c
+++ b/fs/ext4/ext4_jbd2.c
@@ -206,7 +206,7 @@ static void ext4_journal_abort_handle(const char *caller, unsigned int line,
 
 static void ext4_check_bdev_write_error(struct super_block *sb)
 {
-	struct address_space *mapping = sb->s_bdev->bd_inode->i_mapping;
+	struct address_space *mapping = sb->s_bdev->bd_mapping;
 	struct ext4_sb_info *sbi = EXT4_SB(sb);
 	int err;
 
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index b255f798f449..02042eb91806 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -244,7 +244,7 @@ static struct buffer_head *__ext4_sb_bread_gfp(struct super_block *sb,
 struct buffer_head *ext4_sb_bread(struct super_block *sb, sector_t block,
 				   blk_opf_t op_flags)
 {
-	gfp_t gfp = mapping_gfp_constraint(sb->s_bdev->bd_inode->i_mapping,
+	gfp_t gfp = mapping_gfp_constraint(sb->s_bdev->bd_mapping,
 			~__GFP_FS) | __GFP_MOVABLE;
 
 	return __ext4_sb_bread_gfp(sb, block, op_flags, gfp);
@@ -253,7 +253,7 @@ struct buffer_head *ext4_sb_bread(struct super_block *sb, sector_t block,
 struct buffer_head *ext4_sb_bread_unmovable(struct super_block *sb,
 					    sector_t block)
 {
-	gfp_t gfp = mapping_gfp_constraint(sb->s_bdev->bd_inode->i_mapping,
+	gfp_t gfp = mapping_gfp_constraint(sb->s_bdev->bd_mapping,
 			~__GFP_FS);
 
 	return __ext4_sb_bread_gfp(sb, block, 0, gfp);
@@ -5556,7 +5556,7 @@ static int __ext4_fill_super(struct fs_context *fc, struct super_block *sb)
 	 * used to detect the metadata async write error.
 	 */
 	spin_lock_init(&sbi->s_bdev_wb_lock);
-	errseq_check_and_advance(&sb->s_bdev->bd_inode->i_mapping->wb_err,
+	errseq_check_and_advance(&sb->s_bdev->bd_mapping->wb_err,
 				 &sbi->s_bdev_wb_err);
 	EXT4_SB(sb)->s_mount_state |= EXT4_ORPHAN_FS;
 	ext4_orphan_cleanup(sb, es);
diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c
index b6c114c11b97..03c4b9214f56 100644
--- a/fs/jbd2/journal.c
+++ b/fs/jbd2/journal.c
@@ -2009,7 +2009,7 @@ static int __jbd2_journal_erase(journal_t *journal, unsigned int flags)
 		byte_count = (block_stop - block_start + 1) *
 				journal->j_blocksize;
 
-		truncate_inode_pages_range(journal->j_dev->bd_inode->i_mapping,
+		truncate_inode_pages_range(journal->j_dev->bd_mapping,
 				byte_start, byte_stop);
 
 		if (flags & JBD2_JOURNAL_FLUSH_DISCARD) {
diff --git a/include/linux/buffer_head.h b/include/linux/buffer_head.h
index d78454a4dd1f..e58a0d63409a 100644
--- a/include/linux/buffer_head.h
+++ b/include/linux/buffer_head.h
@@ -338,7 +338,7 @@ static inline struct buffer_head *getblk_unmovable(struct block_device *bdev,
 {
 	gfp_t gfp;
 
-	gfp = mapping_gfp_constraint(bdev->bd_inode->i_mapping, ~__GFP_FS);
+	gfp = mapping_gfp_constraint(bdev->bd_mapping, ~__GFP_FS);
 	gfp |= __GFP_NOFAIL;
 
 	return bdev_getblk(bdev, block, size, gfp);
@@ -349,7 +349,7 @@ static inline struct buffer_head *__getblk(struct block_device *bdev,
 {
 	gfp_t gfp;
 
-	gfp = mapping_gfp_constraint(bdev->bd_inode->i_mapping, ~__GFP_FS);
+	gfp = mapping_gfp_constraint(bdev->bd_mapping, ~__GFP_FS);
 	gfp |= __GFP_MOVABLE | __GFP_NOFAIL;
 
 	return bdev_getblk(bdev, block, size, gfp);
diff --git a/include/linux/jbd2.h b/include/linux/jbd2.h
index 971f3e826e15..ac31c37816f7 100644
--- a/include/linux/jbd2.h
+++ b/include/linux/jbd2.h
@@ -1696,7 +1696,7 @@ static inline void jbd2_journal_abort_handle(handle_t *handle)
 
 static inline void jbd2_init_fs_dev_write_error(journal_t *journal)
 {
-	struct address_space *mapping = journal->j_fs_dev->bd_inode->i_mapping;
+	struct address_space *mapping = journal->j_fs_dev->bd_mapping;
 
 	/*
 	 * Save the original wb_err value of client fs's bdev mapping which
@@ -1707,7 +1707,7 @@ static inline void jbd2_init_fs_dev_write_error(journal_t *journal)
 
 static inline int jbd2_check_fs_dev_write_error(journal_t *journal)
 {
-	struct address_space *mapping = journal->j_fs_dev->bd_inode->i_mapping;
+	struct address_space *mapping = journal->j_fs_dev->bd_mapping;
 
 	return errseq_check(&mapping->wb_err,
 			    READ_ONCE(journal->j_fs_dev_wb_err));
-- 
2.39.2


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

* [PATCHES part 2 03/10] grow_dev_folio(): we only want ->bd_inode->i_mapping there
  2024-05-08  6:44 ` [PATCHES part 2 01/10] block_device: add a pointer to struct address_space (page cache of bdev) Al Viro
  2024-05-08  6:44   ` [PATCHES part 2 02/10] use ->bd_mapping instead of ->bd_inode->i_mapping Al Viro
@ 2024-05-08  6:44   ` Al Viro
  2024-05-08  6:44   ` [PATCHES part 2 04/10] blk_ioctl_{discard,zeroout}(): we only want ->bd_inode->i_mapping here Al Viro
                     ` (6 subsequent siblings)
  8 siblings, 0 replies; 18+ messages in thread
From: Al Viro @ 2024-05-08  6:44 UTC (permalink / raw)
  To: linux-fsdevel; +Cc: axboe, brauner, hch

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Link: https://lore.kernel.org/r/20240411145346.2516848-3-viro@zeniv.linux.org.uk
Reviewed-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Signed-off-by: Christian Brauner <brauner@kernel.org>
---
 fs/buffer.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/fs/buffer.c b/fs/buffer.c
index d5a0932ae68d..78a4e95ba2f2 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -1034,12 +1034,12 @@ static sector_t folio_init_buffers(struct folio *folio,
 static bool grow_dev_folio(struct block_device *bdev, sector_t block,
 		pgoff_t index, unsigned size, gfp_t gfp)
 {
-	struct inode *inode = bdev->bd_inode;
+	struct address_space *mapping = bdev->bd_mapping;
 	struct folio *folio;
 	struct buffer_head *bh;
 	sector_t end_block = 0;
 
-	folio = __filemap_get_folio(inode->i_mapping, index,
+	folio = __filemap_get_folio(mapping, index,
 			FGP_LOCK | FGP_ACCESSED | FGP_CREAT, gfp);
 	if (IS_ERR(folio))
 		return false;
@@ -1073,10 +1073,10 @@ static bool grow_dev_folio(struct block_device *bdev, sector_t block,
 	 * lock to be atomic wrt __find_get_block(), which does not
 	 * run under the folio lock.
 	 */
-	spin_lock(&inode->i_mapping->i_private_lock);
+	spin_lock(&mapping->i_private_lock);
 	link_dev_buffers(folio, bh);
 	end_block = folio_init_buffers(folio, bdev, size);
-	spin_unlock(&inode->i_mapping->i_private_lock);
+	spin_unlock(&mapping->i_private_lock);
 unlock:
 	folio_unlock(folio);
 	folio_put(folio);
-- 
2.39.2


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

* [PATCHES part 2 04/10] blk_ioctl_{discard,zeroout}(): we only want ->bd_inode->i_mapping here...
  2024-05-08  6:44 ` [PATCHES part 2 01/10] block_device: add a pointer to struct address_space (page cache of bdev) Al Viro
  2024-05-08  6:44   ` [PATCHES part 2 02/10] use ->bd_mapping instead of ->bd_inode->i_mapping Al Viro
  2024-05-08  6:44   ` [PATCHES part 2 03/10] grow_dev_folio(): we only want ->bd_inode->i_mapping there Al Viro
@ 2024-05-08  6:44   ` Al Viro
  2024-05-08  6:44   ` [PATCHES part 2 05/10] fs/buffer.c: massage the remaining users of ->bd_inode to ->bd_mapping Al Viro
                     ` (5 subsequent siblings)
  8 siblings, 0 replies; 18+ messages in thread
From: Al Viro @ 2024-05-08  6:44 UTC (permalink / raw)
  To: linux-fsdevel; +Cc: axboe, brauner, hch

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Link: https://lore.kernel.org/r/20240411145346.2516848-6-viro@zeniv.linux.org.uk
Signed-off-by: Christian Brauner <brauner@kernel.org>
---
 block/ioctl.c | 10 ++++------
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/block/ioctl.c b/block/ioctl.c
index 7c13d8bed453..831d6350ca25 100644
--- a/block/ioctl.c
+++ b/block/ioctl.c
@@ -97,7 +97,6 @@ static int blk_ioctl_discard(struct block_device *bdev, blk_mode_t mode,
 {
 	uint64_t range[2];
 	uint64_t start, len, end;
-	struct inode *inode = bdev->bd_inode;
 	int err;
 
 	if (!(mode & BLK_OPEN_WRITE))
@@ -121,13 +120,13 @@ static int blk_ioctl_discard(struct block_device *bdev, blk_mode_t mode,
 	    end > bdev_nr_bytes(bdev))
 		return -EINVAL;
 
-	filemap_invalidate_lock(inode->i_mapping);
+	filemap_invalidate_lock(bdev->bd_mapping);
 	err = truncate_bdev_range(bdev, mode, start, start + len - 1);
 	if (err)
 		goto fail;
 	err = blkdev_issue_discard(bdev, start >> 9, len >> 9, GFP_KERNEL);
 fail:
-	filemap_invalidate_unlock(inode->i_mapping);
+	filemap_invalidate_unlock(bdev->bd_mapping);
 	return err;
 }
 
@@ -167,7 +166,6 @@ static int blk_ioctl_zeroout(struct block_device *bdev, blk_mode_t mode,
 {
 	uint64_t range[2];
 	uint64_t start, end, len;
-	struct inode *inode = bdev->bd_inode;
 	int err;
 
 	if (!(mode & BLK_OPEN_WRITE))
@@ -190,7 +188,7 @@ static int blk_ioctl_zeroout(struct block_device *bdev, blk_mode_t mode,
 		return -EINVAL;
 
 	/* Invalidate the page cache, including dirty pages */
-	filemap_invalidate_lock(inode->i_mapping);
+	filemap_invalidate_lock(bdev->bd_mapping);
 	err = truncate_bdev_range(bdev, mode, start, end);
 	if (err)
 		goto fail;
@@ -199,7 +197,7 @@ static int blk_ioctl_zeroout(struct block_device *bdev, blk_mode_t mode,
 				   BLKDEV_ZERO_NOUNMAP);
 
 fail:
-	filemap_invalidate_unlock(inode->i_mapping);
+	filemap_invalidate_unlock(bdev->bd_mapping);
 	return err;
 }
 
-- 
2.39.2


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

* [PATCHES part 2 05/10] fs/buffer.c: massage the remaining users of ->bd_inode to ->bd_mapping
  2024-05-08  6:44 ` [PATCHES part 2 01/10] block_device: add a pointer to struct address_space (page cache of bdev) Al Viro
                     ` (2 preceding siblings ...)
  2024-05-08  6:44   ` [PATCHES part 2 04/10] blk_ioctl_{discard,zeroout}(): we only want ->bd_inode->i_mapping here Al Viro
@ 2024-05-08  6:44   ` Al Viro
  2024-05-08  6:44   ` [PATCHES part 2 06/10] gfs2: more obvious initializations of mapping->host Al Viro
                     ` (4 subsequent siblings)
  8 siblings, 0 replies; 18+ messages in thread
From: Al Viro @ 2024-05-08  6:44 UTC (permalink / raw)
  To: linux-fsdevel; +Cc: axboe, brauner, hch

both for ->i_blkbits and both want the address_space in question anyway.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 fs/buffer.c | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/fs/buffer.c b/fs/buffer.c
index 78a4e95ba2f2..ac29e0f221bc 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -189,8 +189,8 @@ EXPORT_SYMBOL(end_buffer_write_sync);
 static struct buffer_head *
 __find_get_block_slow(struct block_device *bdev, sector_t block)
 {
-	struct inode *bd_inode = bdev->bd_inode;
-	struct address_space *bd_mapping = bd_inode->i_mapping;
+	struct address_space *bd_mapping = bdev->bd_mapping;
+	const int blkbits = bd_mapping->host->i_blkbits;
 	struct buffer_head *ret = NULL;
 	pgoff_t index;
 	struct buffer_head *bh;
@@ -199,7 +199,7 @@ __find_get_block_slow(struct block_device *bdev, sector_t block)
 	int all_mapped = 1;
 	static DEFINE_RATELIMIT_STATE(last_warned, HZ, 1);
 
-	index = ((loff_t)block << bd_inode->i_blkbits) / PAGE_SIZE;
+	index = ((loff_t)block << blkbits) / PAGE_SIZE;
 	folio = __filemap_get_folio(bd_mapping, index, FGP_ACCESSED, 0);
 	if (IS_ERR(folio))
 		goto out;
@@ -233,7 +233,7 @@ __find_get_block_slow(struct block_device *bdev, sector_t block)
 		       (unsigned long long)block,
 		       (unsigned long long)bh->b_blocknr,
 		       bh->b_state, bh->b_size, bdev,
-		       1 << bd_inode->i_blkbits);
+		       1 << blkbits);
 	}
 out_unlock:
 	spin_unlock(&bd_mapping->i_private_lock);
@@ -1696,16 +1696,16 @@ EXPORT_SYMBOL(create_empty_buffers);
  */
 void clean_bdev_aliases(struct block_device *bdev, sector_t block, sector_t len)
 {
-	struct inode *bd_inode = bdev->bd_inode;
-	struct address_space *bd_mapping = bd_inode->i_mapping;
+	struct address_space *bd_mapping = bdev->bd_mapping;
+	const int blkbits = bd_mapping->host->i_blkbits;
 	struct folio_batch fbatch;
-	pgoff_t index = ((loff_t)block << bd_inode->i_blkbits) / PAGE_SIZE;
+	pgoff_t index = ((loff_t)block << blkbits) / PAGE_SIZE;
 	pgoff_t end;
 	int i, count;
 	struct buffer_head *bh;
 	struct buffer_head *head;
 
-	end = ((loff_t)(block + len - 1) << bd_inode->i_blkbits) / PAGE_SIZE;
+	end = ((loff_t)(block + len - 1) << blkbits) / PAGE_SIZE;
 	folio_batch_init(&fbatch);
 	while (filemap_get_folios(bd_mapping, &index, end, &fbatch)) {
 		count = folio_batch_count(&fbatch);
-- 
2.39.2


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

* [PATCHES part 2 06/10] gfs2: more obvious initializations of mapping->host
  2024-05-08  6:44 ` [PATCHES part 2 01/10] block_device: add a pointer to struct address_space (page cache of bdev) Al Viro
                     ` (3 preceding siblings ...)
  2024-05-08  6:44   ` [PATCHES part 2 05/10] fs/buffer.c: massage the remaining users of ->bd_inode to ->bd_mapping Al Viro
@ 2024-05-08  6:44   ` Al Viro
  2024-05-08  6:44   ` [PATCHES part 2 07/10] block/bdev.c: use the knowledge of inode/bdev coallocation Al Viro
                     ` (3 subsequent siblings)
  8 siblings, 0 replies; 18+ messages in thread
From: Al Viro @ 2024-05-08  6:44 UTC (permalink / raw)
  To: linux-fsdevel; +Cc: axboe, brauner, hch

what's going on is copying the ->host of bdev's address_space

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Link: https://lore.kernel.org/r/20240411145346.2516848-4-viro@zeniv.linux.org.uk
Signed-off-by: Christian Brauner <brauner@kernel.org>
---
 fs/gfs2/glock.c      | 2 +-
 fs/gfs2/ops_fstype.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c
index 34540f9d011c..1ebcf6c90f2b 100644
--- a/fs/gfs2/glock.c
+++ b/fs/gfs2/glock.c
@@ -1227,7 +1227,7 @@ int gfs2_glock_get(struct gfs2_sbd *sdp, u64 number,
 	mapping = gfs2_glock2aspace(gl);
 	if (mapping) {
                 mapping->a_ops = &gfs2_meta_aops;
-		mapping->host = s->s_bdev->bd_inode;
+		mapping->host = s->s_bdev->bd_mapping->host;
 		mapping->flags = 0;
 		mapping_set_gfp_mask(mapping, GFP_NOFS);
 		mapping->i_private_data = NULL;
diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c
index 572d58e86296..fcf7dfd14f52 100644
--- a/fs/gfs2/ops_fstype.c
+++ b/fs/gfs2/ops_fstype.c
@@ -114,7 +114,7 @@ static struct gfs2_sbd *init_sbd(struct super_block *sb)
 
 	address_space_init_once(mapping);
 	mapping->a_ops = &gfs2_rgrp_aops;
-	mapping->host = sb->s_bdev->bd_inode;
+	mapping->host = sb->s_bdev->bd_mapping->host;
 	mapping->flags = 0;
 	mapping_set_gfp_mask(mapping, GFP_NOFS);
 	mapping->i_private_data = NULL;
-- 
2.39.2


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

* [PATCHES part 2 07/10] block/bdev.c: use the knowledge of inode/bdev coallocation
  2024-05-08  6:44 ` [PATCHES part 2 01/10] block_device: add a pointer to struct address_space (page cache of bdev) Al Viro
                     ` (4 preceding siblings ...)
  2024-05-08  6:44   ` [PATCHES part 2 06/10] gfs2: more obvious initializations of mapping->host Al Viro
@ 2024-05-08  6:44   ` Al Viro
  2024-05-08  6:44   ` [PATCHES part 2 08/10] nilfs_attach_log_writer(): use ->bd_mapping->host instead of ->bd_inode Al Viro
                     ` (2 subsequent siblings)
  8 siblings, 0 replies; 18+ messages in thread
From: Al Viro @ 2024-05-08  6:44 UTC (permalink / raw)
  To: linux-fsdevel; +Cc: axboe, brauner, hch

Here we know that bdevfs inodes are coallocated with struct block_device
and we can get to ->bd_inode value without any dereferencing.  Introduce
an inlined helper (static, *not* exported, purely internal for bdev.c)
that gets an associated inode by block_device - BD_INODE(bdev).

NOTE: leave it static; nobody outside of block/bdev.c has any business
playing with that.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 block/bdev.c | 32 +++++++++++++++++++-------------
 1 file changed, 19 insertions(+), 13 deletions(-)

diff --git a/block/bdev.c b/block/bdev.c
index 00017af92a51..a8c66cc1d6b8 100644
--- a/block/bdev.c
+++ b/block/bdev.c
@@ -43,6 +43,11 @@ static inline struct bdev_inode *BDEV_I(struct inode *inode)
 	return container_of(inode, struct bdev_inode, vfs_inode);
 }
 
+static inline struct inode *BD_INODE(struct block_device *bdev)
+{
+	return &container_of(bdev, struct bdev_inode, bdev)->vfs_inode;
+}
+
 struct block_device *I_BDEV(struct inode *inode)
 {
 	return &BDEV_I(inode)->bdev;
@@ -57,7 +62,7 @@ EXPORT_SYMBOL(file_bdev);
 
 static void bdev_write_inode(struct block_device *bdev)
 {
-	struct inode *inode = bdev->bd_inode;
+	struct inode *inode = BD_INODE(bdev);
 	int ret;
 
 	spin_lock(&inode->i_lock);
@@ -134,14 +139,14 @@ int truncate_bdev_range(struct block_device *bdev, blk_mode_t mode,
 static void set_init_blocksize(struct block_device *bdev)
 {
 	unsigned int bsize = bdev_logical_block_size(bdev);
-	loff_t size = i_size_read(bdev->bd_inode);
+	loff_t size = i_size_read(BD_INODE(bdev));
 
 	while (bsize < PAGE_SIZE) {
 		if (size & bsize)
 			break;
 		bsize <<= 1;
 	}
-	bdev->bd_inode->i_blkbits = blksize_bits(bsize);
+	BD_INODE(bdev)->i_blkbits = blksize_bits(bsize);
 }
 
 int set_blocksize(struct file *file, int size)
@@ -437,29 +442,30 @@ struct block_device *bdev_alloc(struct gendisk *disk, u8 partno)
 void bdev_set_nr_sectors(struct block_device *bdev, sector_t sectors)
 {
 	spin_lock(&bdev->bd_size_lock);
-	i_size_write(bdev->bd_inode, (loff_t)sectors << SECTOR_SHIFT);
+	i_size_write(BD_INODE(bdev), (loff_t)sectors << SECTOR_SHIFT);
 	bdev->bd_nr_sectors = sectors;
 	spin_unlock(&bdev->bd_size_lock);
 }
 
 void bdev_add(struct block_device *bdev, dev_t dev)
 {
+	struct inode *inode = BD_INODE(bdev);
 	if (bdev_stable_writes(bdev))
 		mapping_set_stable_writes(bdev->bd_mapping);
 	bdev->bd_dev = dev;
-	bdev->bd_inode->i_rdev = dev;
-	bdev->bd_inode->i_ino = dev;
-	insert_inode_hash(bdev->bd_inode);
+	inode->i_rdev = dev;
+	inode->i_ino = dev;
+	insert_inode_hash(inode);
 }
 
 void bdev_unhash(struct block_device *bdev)
 {
-	remove_inode_hash(bdev->bd_inode);
+	remove_inode_hash(BD_INODE(bdev));
 }
 
 void bdev_drop(struct block_device *bdev)
 {
-	iput(bdev->bd_inode);
+	iput(BD_INODE(bdev));
 }
 
 long nr_blockdev_pages(void)
@@ -987,13 +993,13 @@ struct file *bdev_file_open_by_dev(dev_t dev, blk_mode_t mode, void *holder,
 		return ERR_PTR(-ENXIO);
 
 	flags = blk_to_file_flags(mode);
-	bdev_file = alloc_file_pseudo_noaccount(bdev->bd_inode,
+	bdev_file = alloc_file_pseudo_noaccount(BD_INODE(bdev),
 			blockdev_mnt, "", flags | O_LARGEFILE, &def_blk_fops);
 	if (IS_ERR(bdev_file)) {
 		blkdev_put_no_open(bdev);
 		return bdev_file;
 	}
-	ihold(bdev->bd_inode);
+	ihold(BD_INODE(bdev));
 
 	ret = bdev_open(bdev, mode, holder, hops, bdev_file);
 	if (ret) {
@@ -1270,13 +1276,13 @@ void bdev_statx_dioalign(struct inode *inode, struct kstat *stat)
 
 bool disk_live(struct gendisk *disk)
 {
-	return !inode_unhashed(disk->part0->bd_inode);
+	return !inode_unhashed(BD_INODE(disk->part0));
 }
 EXPORT_SYMBOL_GPL(disk_live);
 
 unsigned int block_size(struct block_device *bdev)
 {
-	return 1 << bdev->bd_inode->i_blkbits;
+	return 1 << BD_INODE(bdev)->i_blkbits;
 }
 EXPORT_SYMBOL_GPL(block_size);
 
-- 
2.39.2


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

* [PATCHES part 2 08/10] nilfs_attach_log_writer(): use ->bd_mapping->host instead of ->bd_inode
  2024-05-08  6:44 ` [PATCHES part 2 01/10] block_device: add a pointer to struct address_space (page cache of bdev) Al Viro
                     ` (5 preceding siblings ...)
  2024-05-08  6:44   ` [PATCHES part 2 07/10] block/bdev.c: use the knowledge of inode/bdev coallocation Al Viro
@ 2024-05-08  6:44   ` Al Viro
  2024-05-08  6:44   ` [PATCHES part 2 09/10] dasd_format(): killing the last remaining user " Al Viro
  2024-05-08  6:44   ` [PATCHES part 2 10/10] RIP ->bd_inode Al Viro
  8 siblings, 0 replies; 18+ messages in thread
From: Al Viro @ 2024-05-08  6:44 UTC (permalink / raw)
  To: linux-fsdevel; +Cc: axboe, brauner, hch

I suspect that inode_attach_wb() use is rather unidiomatic, but
that's a separate story - in any case, its use is a few times
per mount *and* the route by which we access that inode is
"the host of address_space a page belongs to".

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 fs/nilfs2/segment.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c
index aa5290cb7467..15188e799580 100644
--- a/fs/nilfs2/segment.c
+++ b/fs/nilfs2/segment.c
@@ -2790,7 +2790,7 @@ int nilfs_attach_log_writer(struct super_block *sb, struct nilfs_root *root)
 	if (!nilfs->ns_writer)
 		return -ENOMEM;
 
-	inode_attach_wb(nilfs->ns_bdev->bd_inode, NULL);
+	inode_attach_wb(nilfs->ns_bdev->bd_mapping->host, NULL);
 
 	err = nilfs_segctor_start_thread(nilfs->ns_writer);
 	if (unlikely(err))
-- 
2.39.2


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

* [PATCHES part 2 09/10] dasd_format(): killing the last remaining user of ->bd_inode
  2024-05-08  6:44 ` [PATCHES part 2 01/10] block_device: add a pointer to struct address_space (page cache of bdev) Al Viro
                     ` (6 preceding siblings ...)
  2024-05-08  6:44   ` [PATCHES part 2 08/10] nilfs_attach_log_writer(): use ->bd_mapping->host instead of ->bd_inode Al Viro
@ 2024-05-08  6:44   ` Al Viro
  2024-05-08  6:44   ` [PATCHES part 2 10/10] RIP ->bd_inode Al Viro
  8 siblings, 0 replies; 18+ messages in thread
From: Al Viro @ 2024-05-08  6:44 UTC (permalink / raw)
  To: linux-fsdevel; +Cc: axboe, brauner, hch

What happens here is almost certainly wrong.  However,
	* it's the last remaining user of ->bd_inode anywhere in the tree
	* it is *NOT* a fast path by any stretch of imagination

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 drivers/s390/block/dasd_ioctl.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/s390/block/dasd_ioctl.c b/drivers/s390/block/dasd_ioctl.c
index 7e0ed7032f76..eb5dcbe37230 100644
--- a/drivers/s390/block/dasd_ioctl.c
+++ b/drivers/s390/block/dasd_ioctl.c
@@ -215,7 +215,7 @@ dasd_format(struct dasd_block *block, struct format_data_t *fdata)
 	 * enabling the device later.
 	 */
 	if (fdata->start_unit == 0) {
-		block->gdp->part0->bd_inode->i_blkbits =
+		block->gdp->part0->bd_mapping->host->i_blkbits =
 			blksize_bits(fdata->blksize);
 	}
 
-- 
2.39.2


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

* [PATCHES part 2 10/10] RIP ->bd_inode
  2024-05-08  6:44 ` [PATCHES part 2 01/10] block_device: add a pointer to struct address_space (page cache of bdev) Al Viro
                     ` (7 preceding siblings ...)
  2024-05-08  6:44   ` [PATCHES part 2 09/10] dasd_format(): killing the last remaining user " Al Viro
@ 2024-05-08  6:44   ` Al Viro
  8 siblings, 0 replies; 18+ messages in thread
From: Al Viro @ 2024-05-08  6:44 UTC (permalink / raw)
  To: linux-fsdevel; +Cc: axboe, brauner, hch

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 block/bdev.c              | 1 -
 include/linux/blk_types.h | 1 -
 2 files changed, 2 deletions(-)

diff --git a/block/bdev.c b/block/bdev.c
index a8c66cc1d6b8..0849a9cfa2b6 100644
--- a/block/bdev.c
+++ b/block/bdev.c
@@ -423,7 +423,6 @@ struct block_device *bdev_alloc(struct gendisk *disk, u8 partno)
 	spin_lock_init(&bdev->bd_size_lock);
 	mutex_init(&bdev->bd_holder_lock);
 	bdev->bd_partno = partno;
-	bdev->bd_inode = inode;
 	bdev->bd_mapping = &inode->i_data;
 	bdev->bd_queue = disk->queue;
 	if (partno)
diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h
index 6438c75cbb35..5616d059cb23 100644
--- a/include/linux/blk_types.h
+++ b/include/linux/blk_types.h
@@ -50,7 +50,6 @@ struct block_device {
 	bool			bd_write_holder;
 	bool			bd_has_submit_bio;
 	dev_t			bd_dev;
-	struct inode		*bd_inode;	/* will die */
 	struct address_space	*bd_mapping;	/* page cache */
 
 	atomic_t		bd_openers;
-- 
2.39.2


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

end of thread, other threads:[~2024-05-08  6:44 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-05-08  6:35 [PATCHES] ->bd_inode elimination Al Viro
2024-05-08  6:42 ` [PATCHES part 1 1/7] ext4: remove block_device_ejected() Al Viro
2024-05-08  6:42   ` [PATCHES part 1 2/7] bcachefs: remove dead function bdev_sectors() Al Viro
2024-05-08  6:42   ` [PATCHES part 1 3/7] blkdev_write_iter(): saner way to get inode and bdev Al Viro
2024-05-08  6:42   ` [PATCHES part 1 4/7] dm-vdo: use bdev_nr_bytes(bdev) instead of i_size_read(bdev->bd_inode) Al Viro
2024-05-08  6:42   ` [PATCHES part 1 5/7] block2mtd: prevent direct access of bd_inode Al Viro
2024-05-08  6:43   ` [PATCHES part 1 6/7] block: move two helpers into bdev.c Al Viro
2024-05-08  6:43   ` [PATCHES part 1 7/7] missing helpers: bdev_unhash(), bdev_drop() Al Viro
2024-05-08  6:44 ` [PATCHES part 2 01/10] block_device: add a pointer to struct address_space (page cache of bdev) Al Viro
2024-05-08  6:44   ` [PATCHES part 2 02/10] use ->bd_mapping instead of ->bd_inode->i_mapping Al Viro
2024-05-08  6:44   ` [PATCHES part 2 03/10] grow_dev_folio(): we only want ->bd_inode->i_mapping there Al Viro
2024-05-08  6:44   ` [PATCHES part 2 04/10] blk_ioctl_{discard,zeroout}(): we only want ->bd_inode->i_mapping here Al Viro
2024-05-08  6:44   ` [PATCHES part 2 05/10] fs/buffer.c: massage the remaining users of ->bd_inode to ->bd_mapping Al Viro
2024-05-08  6:44   ` [PATCHES part 2 06/10] gfs2: more obvious initializations of mapping->host Al Viro
2024-05-08  6:44   ` [PATCHES part 2 07/10] block/bdev.c: use the knowledge of inode/bdev coallocation Al Viro
2024-05-08  6:44   ` [PATCHES part 2 08/10] nilfs_attach_log_writer(): use ->bd_mapping->host instead of ->bd_inode Al Viro
2024-05-08  6:44   ` [PATCHES part 2 09/10] dasd_format(): killing the last remaining user " Al Viro
2024-05-08  6:44   ` [PATCHES part 2 10/10] RIP ->bd_inode Al Viro

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).