From: Dave Chinner <david@fromorbit.com>
To: Christian Brauner <brauner@kernel.org>
Cc: Mateusz Guzik <mjguzik@gmail.com>,
viro@zeniv.linux.org.uk, jack@suse.cz,
linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org,
hughd@google.com, linux-ext4@vger.kernel.org, tytso@mit.edu,
linux-mm@kvack.org
Subject: Re: [PATCH v3 1/3] vfs: support caching symlink lengths in inodes
Date: Fri, 22 Nov 2024 12:56:48 +1100 [thread overview]
Message-ID: <Zz_k4CtwOKGUbr6V@dread.disaster.area> (raw)
In-Reply-To: <20241121-seilschaft-zeitig-7c8c3431bd00@brauner>
On Thu, Nov 21, 2024 at 11:12:52AM +0100, Christian Brauner wrote:
> I think that i_devices should be moved into the union as it's really
> only used with i_cdev but it's not that easily done because list_head
> needs to be initialized.
I'm planning on using i_devices with block devices, too, so the
block device list doesn't need to use i_sb_list anymore (similar to
how i_devices is used by the char dev infrastructure. See the patch
below...
> I roughly envisioned something like:
>
> union {
> struct {
> struct cdev *i_cdev;
> struct list_head i_devices;
> };
> struct {
> char *i_link;
> unsigned int i_link_len;
> };
> struct pipe_inode_info *i_pipe;
> unsigned i_dir_seq;
> };
>
I'd probably have to undo any unioning/association with i_cdev to
use i_devices with block devs...
-Dave
--
Dave Chinner
david@fromorbit.com
bdev: stop using sb->s_inodes
From: Dave Chinner <dchinner@redhat.com>
Iteration of block device inodes is done via the
blockdev_superblock->s_inodes list. We want to remove this list and
the inode i_sb_list list heads, so we need some other way for block
devices to be iterated.
Take a leaf from the chardev code and use the inode->i_devices list
head to link all the block device inodes together and replace the
s_inodes list with a bdev private global list.
Signed-off-by: Dave Chinner <dchinner@redhat.com>
---
block/bdev.c | 56 +++++++++++++++++++++++++++++++++++++++-----------------
1 file changed, 39 insertions(+), 17 deletions(-)
diff --git a/block/bdev.c b/block/bdev.c
index 33f9c4605e3a..d733507f584a 100644
--- a/block/bdev.c
+++ b/block/bdev.c
@@ -317,6 +317,8 @@ EXPORT_SYMBOL(bdev_thaw);
static __cacheline_aligned_in_smp DEFINE_MUTEX(bdev_lock);
static struct kmem_cache *bdev_cachep __ro_after_init;
+static LIST_HEAD(bdev_inodes);
+static DEFINE_SPINLOCK(bdev_inodes_lock);
static struct inode *bdev_alloc_inode(struct super_block *sb)
{
@@ -362,6 +364,10 @@ static void init_once(void *data)
static void bdev_evict_inode(struct inode *inode)
{
+ spin_lock(&bdev_inodes_lock);
+ list_del_init(&inode->i_devices);
+ spin_unlock(&bdev_inodes_lock);
+
truncate_inode_pages_final(&inode->i_data);
invalidate_inode_buffers(inode); /* is it needed here? */
clear_inode(inode);
@@ -412,19 +418,35 @@ void __init bdev_cache_init(void)
blockdev_superblock = blockdev_mnt->mnt_sb; /* For writeback */
}
-struct block_device *bdev_alloc(struct gendisk *disk, u8 partno)
+static struct inode *bdev_new_inode(void)
{
- struct block_device *bdev;
struct inode *inode;
- inode = new_inode(blockdev_superblock);
+ inode = new_inode_pseudo(blockdev_superblock);
if (!inode)
return NULL;
+
+ spin_lock(&bdev_inodes_lock);
+ list_add(&inode->i_devices, &bdev_inodes);
+ spin_unlock(&bdev_inodes_lock);
+
inode->i_mode = S_IFBLK;
inode->i_rdev = 0;
inode->i_data.a_ops = &def_blk_aops;
mapping_set_gfp_mask(&inode->i_data, GFP_USER);
+ return inode;
+}
+
+struct block_device *bdev_alloc(struct gendisk *disk, u8 partno)
+{
+ struct block_device *bdev;
+ struct inode *inode;
+
+ inode = bdev_new_inode();
+ if (!inode)
+ return NULL;
+
bdev = I_BDEV(inode);
mutex_init(&bdev->bd_fsfreeze_mutex);
spin_lock_init(&bdev->bd_size_lock);
@@ -477,10 +499,10 @@ long nr_blockdev_pages(void)
struct inode *inode;
long ret = 0;
- spin_lock(&blockdev_superblock->s_inode_list_lock);
- list_for_each_entry(inode, &blockdev_superblock->s_inodes, i_sb_list)
+ spin_lock(&bdev_inodes_lock);
+ list_for_each_entry(inode, &bdev_inodes, i_devices)
ret += inode->i_mapping->nrpages;
- spin_unlock(&blockdev_superblock->s_inode_list_lock);
+ spin_unlock(&bdev_inodes_lock);
return ret;
}
@@ -1218,8 +1240,8 @@ void sync_bdevs(bool wait)
{
struct inode *inode, *old_inode = NULL;
- spin_lock(&blockdev_superblock->s_inode_list_lock);
- list_for_each_entry(inode, &blockdev_superblock->s_inodes, i_sb_list) {
+ spin_lock(&bdev_inodes_lock);
+ list_for_each_entry(inode, &bdev_inodes, i_devices) {
struct address_space *mapping = inode->i_mapping;
struct block_device *bdev;
@@ -1231,14 +1253,14 @@ void sync_bdevs(bool wait)
}
__iget(inode);
spin_unlock(&inode->i_lock);
- spin_unlock(&blockdev_superblock->s_inode_list_lock);
+ spin_unlock(&bdev_inodes_lock);
+
/*
- * We hold a reference to 'inode' so it couldn't have been
- * removed from s_inodes list while we dropped the
- * s_inode_list_lock We cannot iput the inode now as we can
- * be holding the last reference and we cannot iput it under
- * s_inode_list_lock. So we keep the reference and iput it
- * later.
+ * We hold a reference to 'inode' so it won't get removed from
+ * bdev inodes list while we drop the lock. We need to hold the
+ * reference until we have a reference on the next inode on the
+ * list, so we can't drop it until the next time we let go of
+ * the bdev_inodes_lock.
*/
iput(old_inode);
old_inode = inode;
@@ -1260,9 +1282,9 @@ void sync_bdevs(bool wait)
}
mutex_unlock(&bdev->bd_disk->open_mutex);
- spin_lock(&blockdev_superblock->s_inode_list_lock);
+ spin_lock(&bdev_inodes_lock);
}
- spin_unlock(&blockdev_superblock->s_inode_list_lock);
+ spin_unlock(&bdev_inodes_lock);
iput(old_inode);
}
next prev parent reply other threads:[~2024-11-22 1:56 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-11-20 11:20 [PATCH v3 0/3] symlink length caching Mateusz Guzik
2024-11-20 11:20 ` [PATCH v3 1/3] vfs: support caching symlink lengths in inodes Mateusz Guzik
2024-11-21 10:12 ` Christian Brauner
2024-11-21 13:56 ` Mateusz Guzik
2024-11-22 1:56 ` Dave Chinner [this message]
2024-11-20 11:20 ` [PATCH v3 2/3] ext4: use inode_set_cached_link() Mateusz Guzik
2024-11-21 11:58 ` Jan Kara
2024-11-20 11:20 ` [PATCH v3 3/3] tmpfs: " Mateusz Guzik
2024-11-21 11:59 ` Jan Kara
2024-11-21 12:34 ` [PATCH v3 0/3] symlink length caching Christian Brauner
2026-02-03 4:20 ` Al Viro
2026-02-03 14:13 ` Christian Brauner
2024-11-21 14:16 ` Jeff Layton
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=Zz_k4CtwOKGUbr6V@dread.disaster.area \
--to=david@fromorbit.com \
--cc=brauner@kernel.org \
--cc=hughd@google.com \
--cc=jack@suse.cz \
--cc=linux-ext4@vger.kernel.org \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=mjguzik@gmail.com \
--cc=tytso@mit.edu \
--cc=viro@zeniv.linux.org.uk \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.