diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2026-04-13 12:46:42 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2026-04-13 12:46:42 -0700 |
| commit | fc825e513cd494cfcbeb47acf5738fe64f3a9051 (patch) | |
| tree | 3f3fde91e0f50331d8558bb66fd3213272bf4818 /fs/ext4 | |
| parent | 2802f9407299c8e17bb8e1311e2ea7816f550649 (diff) | |
| parent | 6e22726900ea54d72cbc6f053c0fa581de023de6 (diff) | |
Merge tag 'vfs-7.1-rc1.bh.metadata' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs
Pull vfs buffer_head updates from Christian Brauner:
"This cleans up the mess that has accumulated over the years in
metadata buffer_head tracking for inodes.
It moves the tracking into dedicated structure in filesystem-private
part of the inode (so that we don't use private_list, private_data,
and private_lock in struct address_space), and also moves couple other
users of private_data and private_list so these are removed from
struct address_space saving 3 longs in struct inode for 99% of inodes"
* tag 'vfs-7.1-rc1.bh.metadata' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs: (42 commits)
fs: Drop i_private_list from address_space
fs: Drop mapping_metadata_bhs from address space
ext4: Track metadata bhs in fs-private inode part
minix: Track metadata bhs in fs-private inode part
udf: Track metadata bhs in fs-private inode part
fat: Track metadata bhs in fs-private inode part
bfs: Track metadata bhs in fs-private inode part
affs: Track metadata bhs in fs-private inode part
ext2: Track metadata bhs in fs-private inode part
fs: Provide functions for handling mapping_metadata_bhs directly
fs: Switch inode_has_buffers() to take mapping_metadata_bhs
fs: Make bhs point to mapping_metadata_bhs
fs: Move metadata bhs tracking to a separate struct
fs: Fold fsync_buffers_list() into sync_mapping_buffers()
fs: Drop osync_buffers_list()
kvm: Use private inode list instead of i_private_list
fs: Remove i_private_data
aio: Stop using i_private_data and i_private_lock
hugetlbfs: Stop using i_private_data
fs: Stop using i_private_data for metadata bh tracking
...
Diffstat (limited to 'fs/ext4')
| -rw-r--r-- | fs/ext4/ext4.h | 1 | ||||
| -rw-r--r-- | fs/ext4/ext4_jbd2.c | 3 | ||||
| -rw-r--r-- | fs/ext4/fsync.c | 5 | ||||
| -rw-r--r-- | fs/ext4/inode.c | 9 | ||||
| -rw-r--r-- | fs/ext4/super.c | 4 |
5 files changed, 13 insertions, 9 deletions
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 1aa4622f812b..0cf68f85dfd1 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -1121,6 +1121,7 @@ struct ext4_inode_info { struct rw_semaphore i_data_sem; struct inode vfs_inode; struct jbd2_inode *jinode; + struct mapping_metadata_bhs i_metadata_bhs; /* * File creation time. Its function is same as that of diff --git a/fs/ext4/ext4_jbd2.c b/fs/ext4/ext4_jbd2.c index 05e5946ed9b3..9a8c225f2753 100644 --- a/fs/ext4/ext4_jbd2.c +++ b/fs/ext4/ext4_jbd2.c @@ -390,7 +390,8 @@ int __ext4_handle_dirty_metadata(const char *where, unsigned int line, } } else { if (inode) - mark_buffer_dirty_inode(bh, inode); + mmb_mark_buffer_dirty(bh, + &EXT4_I(inode)->i_metadata_bhs); else mark_buffer_dirty(bh); if (inode && inode_needs_sync(inode)) { diff --git a/fs/ext4/fsync.c b/fs/ext4/fsync.c index bd8f230fa507..924726dcc85f 100644 --- a/fs/ext4/fsync.c +++ b/fs/ext4/fsync.c @@ -68,7 +68,7 @@ static int ext4_sync_parent(struct inode *inode) * through ext4_evict_inode()) and so we are safe to flush * metadata blocks and the inode. */ - ret = sync_mapping_buffers(inode->i_mapping); + ret = mmb_sync(&EXT4_I(inode)->i_metadata_bhs); if (ret) break; ret = sync_inode_metadata(inode, 1); @@ -89,7 +89,8 @@ static int ext4_fsync_nojournal(struct file *file, loff_t start, loff_t end, }; int ret; - ret = generic_buffers_fsync_noflush(file, start, end, datasync); + ret = mmb_fsync_noflush(file, &EXT4_I(inode)->i_metadata_bhs, + start, end, datasync); if (ret) return ret; diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 01679d96cd0f..f78cf5f23835 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -195,7 +195,9 @@ void ext4_evict_inode(struct inode *inode) ext4_warning_inode(inode, "data will be lost"); truncate_inode_pages_final(&inode->i_data); - + /* Avoid mballoc special inode which has no proper iops */ + if (!EXT4_SB(inode->i_sb)->s_journal) + mmb_sync(&EXT4_I(inode)->i_metadata_bhs); goto no_delete; } @@ -1430,9 +1432,6 @@ static int write_end_fn(handle_t *handle, struct inode *inode, /* * We need to pick up the new inode size which generic_commit_write gave us * `iocb` can be NULL - eg, when called from page_symlink(). - * - * ext4 never places buffers on inode->i_mapping->i_private_list. metadata - * buffers are managed internally. */ static int ext4_write_end(const struct kiocb *iocb, struct address_space *mapping, @@ -3447,7 +3446,7 @@ static bool ext4_inode_datasync_dirty(struct inode *inode) } /* Any metadata buffers to write? */ - if (!list_empty(&inode->i_mapping->i_private_list)) + if (mmb_has_buffers(&EXT4_I(inode)->i_metadata_bhs)) return true; return inode_state_read_once(inode) & I_DIRTY_DATASYNC; } diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 8ca399c15970..578508eb4f1a 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -1424,6 +1424,7 @@ static struct inode *ext4_alloc_inode(struct super_block *sb) INIT_WORK(&ei->i_rsv_conversion_work, ext4_end_io_rsv_work); ext4_fc_init_inode(&ei->vfs_inode); spin_lock_init(&ei->i_fc_lock); + mmb_init(&ei->i_metadata_bhs, &ei->vfs_inode.i_data); return &ei->vfs_inode; } @@ -1520,7 +1521,8 @@ static void destroy_inodecache(void) void ext4_clear_inode(struct inode *inode) { ext4_fc_del(inode); - invalidate_inode_buffers(inode); + if (!EXT4_SB(inode->i_sb)->s_journal) + mmb_invalidate(&EXT4_I(inode)->i_metadata_bhs); clear_inode(inode); ext4_discard_preallocations(inode); /* |
