summaryrefslogtreecommitdiff
path: root/fs/ext2
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2026-04-13 12:46:42 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2026-04-13 12:46:42 -0700
commitfc825e513cd494cfcbeb47acf5738fe64f3a9051 (patch)
tree3f3fde91e0f50331d8558bb66fd3213272bf4818 /fs/ext2
parent2802f9407299c8e17bb8e1311e2ea7816f550649 (diff)
parent6e22726900ea54d72cbc6f053c0fa581de023de6 (diff)
downloadlwn-fc825e513cd494cfcbeb47acf5738fe64f3a9051.tar.gz
lwn-fc825e513cd494cfcbeb47acf5738fe64f3a9051.zip
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/ext2')
-rw-r--r--fs/ext2/ext2.h1
-rw-r--r--fs/ext2/file.c6
-rw-r--r--fs/ext2/inode.c17
-rw-r--r--fs/ext2/super.c1
4 files changed, 16 insertions, 9 deletions
diff --git a/fs/ext2/ext2.h b/fs/ext2/ext2.h
index 5e0c6c5fcb6c..3eb1f342645c 100644
--- a/fs/ext2/ext2.h
+++ b/fs/ext2/ext2.h
@@ -676,6 +676,7 @@ struct ext2_inode_info {
#ifdef CONFIG_QUOTA
struct dquot __rcu *i_dquot[MAXQUOTAS];
#endif
+ struct mapping_metadata_bhs i_metadata_bhs;
};
/*
diff --git a/fs/ext2/file.c b/fs/ext2/file.c
index ebe356a38b18..d9b1eb34694a 100644
--- a/fs/ext2/file.c
+++ b/fs/ext2/file.c
@@ -156,9 +156,11 @@ static int ext2_release_file (struct inode * inode, struct file * filp)
int ext2_fsync(struct file *file, loff_t start, loff_t end, int datasync)
{
int ret;
- struct super_block *sb = file->f_mapping->host->i_sb;
+ struct inode *inode = file->f_mapping->host;
+ struct super_block *sb = inode->i_sb;
- ret = generic_buffers_fsync(file, start, end, datasync);
+ ret = mmb_fsync(file, &EXT2_I(inode)->i_metadata_bhs,
+ start, end, datasync);
if (ret == -EIO)
/* We don't really know where the IO error happened... */
ext2_error(sb, __func__,
diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c
index 45286c0c3b6b..6443c298c105 100644
--- a/fs/ext2/inode.c
+++ b/fs/ext2/inode.c
@@ -94,9 +94,10 @@ void ext2_evict_inode(struct inode * inode)
if (inode->i_blocks)
ext2_truncate_blocks(inode, 0);
ext2_xattr_delete_inode(inode);
+ } else {
+ mmb_sync(&EXT2_I(inode)->i_metadata_bhs);
}
-
- invalidate_inode_buffers(inode);
+ mmb_invalidate(&EXT2_I(inode)->i_metadata_bhs);
clear_inode(inode);
ext2_discard_reservation(inode);
@@ -526,7 +527,7 @@ static int ext2_alloc_branch(struct inode *inode,
}
set_buffer_uptodate(bh);
unlock_buffer(bh);
- mark_buffer_dirty_inode(bh, inode);
+ mmb_mark_buffer_dirty(bh, &EXT2_I(inode)->i_metadata_bhs);
/* We used to sync bh here if IS_SYNC(inode).
* But we now rely upon generic_write_sync()
* and b_inode_buffers. But not for directories.
@@ -597,7 +598,7 @@ static void ext2_splice_branch(struct inode *inode,
/* had we spliced it onto indirect block? */
if (where->bh)
- mark_buffer_dirty_inode(where->bh, inode);
+ mmb_mark_buffer_dirty(where->bh, &EXT2_I(inode)->i_metadata_bhs);
inode_set_ctime_current(inode);
mark_inode_dirty(inode);
@@ -1210,7 +1211,8 @@ static void __ext2_truncate_blocks(struct inode *inode, loff_t offset)
if (partial == chain)
mark_inode_dirty(inode);
else
- mark_buffer_dirty_inode(partial->bh, inode);
+ mmb_mark_buffer_dirty(partial->bh,
+ &EXT2_I(inode)->i_metadata_bhs);
ext2_free_branches(inode, &nr, &nr+1, (chain+n-1) - partial);
}
/* Clear the ends of indirect blocks on the shared branch */
@@ -1219,7 +1221,8 @@ static void __ext2_truncate_blocks(struct inode *inode, loff_t offset)
partial->p + 1,
(__le32*)partial->bh->b_data+addr_per_block,
(chain+n-1) - partial);
- mark_buffer_dirty_inode(partial->bh, inode);
+ mmb_mark_buffer_dirty(partial->bh,
+ &EXT2_I(inode)->i_metadata_bhs);
brelse (partial->bh);
partial--;
}
@@ -1302,7 +1305,7 @@ static int ext2_setsize(struct inode *inode, loff_t newsize)
inode_set_mtime_to_ts(inode, inode_set_ctime_current(inode));
if (inode_needs_sync(inode)) {
- sync_mapping_buffers(inode->i_mapping);
+ mmb_sync(&EXT2_I(inode)->i_metadata_bhs);
sync_inode_metadata(inode, 1);
} else {
mark_inode_dirty(inode);
diff --git a/fs/ext2/super.c b/fs/ext2/super.c
index 603f2641fe10..4118a3a1f620 100644
--- a/fs/ext2/super.c
+++ b/fs/ext2/super.c
@@ -215,6 +215,7 @@ static struct inode *ext2_alloc_inode(struct super_block *sb)
#ifdef CONFIG_QUOTA
memset(&ei->i_dquot, 0, sizeof(ei->i_dquot));
#endif
+ mmb_init(&ei->i_metadata_bhs, &ei->vfs_inode.i_data);
return &ei->vfs_inode;
}