diff options
| author | Jan Kara <jack@suse.cz> | 2026-03-26 10:54:16 +0100 |
|---|---|---|
| committer | Christian Brauner <brauner@kernel.org> | 2026-03-26 15:03:29 +0100 |
| commit | 972b9dd4e4180fbb2352bf2f0e015b7b63f5cca0 (patch) | |
| tree | 746fa70b1014c62081f78af7e77a49650c27e31a /fs/buffer.c | |
| parent | 23dae9e189de56c462a99c1695c1a2b3c499251b (diff) | |
| download | lwn-972b9dd4e4180fbb2352bf2f0e015b7b63f5cca0.tar.gz lwn-972b9dd4e4180fbb2352bf2f0e015b7b63f5cca0.zip | |
fs: Ignore inode metadata buffers in inode_lru_isolate()
There are only a few filesystems that use generic tracking of inode
metadata buffer heads. As such the logic to reclaim tracked metadata
buffer heads in inode_lru_isolate() doesn't bring a benefit big enough
to justify intertwining of inode reclaim and metadata buffer head
tracking. Just treat tracked metadata buffer heads as any other metadata
filesystem has to properly clean up on inode eviction and stop handling
it in inode_lru_isolate(). As a result filesystems using generic
tracking of metadata buffer heads may now see dirty metadata buffers in
their .evict methods more often which can slow down inode reclaim but
given these filesystems aren't used in performance demanding setups we
should be fine.
Signed-off-by: Jan Kara <jack@suse.cz>
Link: https://patch.msgid.link/20260326095354.16340-64-jack@suse.cz
Tested-by: syzbot@syzkaller.appspotmail.com
Signed-off-by: Christian Brauner <brauner@kernel.org>
Diffstat (limited to 'fs/buffer.c')
| -rw-r--r-- | fs/buffer.c | 29 |
1 files changed, 0 insertions, 29 deletions
diff --git a/fs/buffer.c b/fs/buffer.c index 1bc0f22f3cc2..bd48644e1bf8 100644 --- a/fs/buffer.c +++ b/fs/buffer.c @@ -879,35 +879,6 @@ void invalidate_inode_buffers(struct inode *inode) EXPORT_SYMBOL(invalidate_inode_buffers); /* - * Remove any clean buffers from the inode's buffer list. This is called - * when we're trying to free the inode itself. Those buffers can pin it. - * - * Returns true if all buffers were removed. - */ -int remove_inode_buffers(struct inode *inode) -{ - int ret = 1; - - if (inode_has_buffers(inode)) { - struct address_space *mapping = &inode->i_data; - struct list_head *list = &mapping->i_private_list; - struct address_space *buffer_mapping = mapping->i_private_data; - - spin_lock(&buffer_mapping->i_private_lock); - while (!list_empty(list)) { - struct buffer_head *bh = BH_ENTRY(list->next); - if (buffer_dirty(bh)) { - ret = 0; - break; - } - __remove_assoc_queue(bh); - } - spin_unlock(&buffer_mapping->i_private_lock); - } - return ret; -} - -/* * Create the appropriate buffers when given a folio for data area and * the size of each buffer.. Use the bh->b_this_page linked list to * follow the buffers created. Return NULL if unable to create more |
