From: Ojaswin Mujoo <ojaswin@linux.ibm.com>
To: linux-ext4@vger.kernel.org, "Theodore Ts'o" <tytso@mit.edu>
Cc: Jan Kara <jack@suse.cz>, Baokun Li <libaokun1@huawei.com>,
Ritesh Harjani <ritesh.list@gmail.com>,
linux-kernel@vger.kernel.org
Subject: [PATCH] ext4: cache es->s_journal_inum in ext4_sb_info
Date: Fri, 14 Mar 2025 17:11:43 +0530 [thread overview]
Message-ID: <d1a9328a41029f6210a1924b192a59afcd3c5cee.1741952406.git.ojaswin@linux.ibm.com> (raw)
Currently, we access journal ino through sbi->s_es->s_journal_inum,
which directly reads from the ext4 sb buffer head. If someone modifies
this underneath us then the s_journal_inum field might get corrupted.
Although direct block device modifications can be expected to cause
issues in the FS, let's cache s_journal_inum in sbi->s_journal_ino so
our checks can be more resillient.
Suggested-by: Baokun Li <libaokun1@huawei.com>
Signed-off-by: Ojaswin Mujoo <ojaswin@linux.ibm.com>
---
fs/ext4/block_validity.c | 23 ++++++++++++++++-------
fs/ext4/ext4.h | 1 +
fs/ext4/inode.c | 19 +++++++++++++++----
fs/ext4/super.c | 5 ++++-
4 files changed, 36 insertions(+), 12 deletions(-)
diff --git a/fs/ext4/block_validity.c b/fs/ext4/block_validity.c
index 87ee3a17bd29..54e6f3499263 100644
--- a/fs/ext4/block_validity.c
+++ b/fs/ext4/block_validity.c
@@ -247,9 +247,9 @@ int ext4_setup_system_zone(struct super_block *sb)
if (ret)
goto err;
}
- if (ext4_has_feature_journal(sb) && sbi->s_es->s_journal_inum) {
+ if (ext4_has_feature_journal(sb) && sbi->s_journal_ino) {
ret = ext4_protect_reserved_inode(sb, system_blks,
- le32_to_cpu(sbi->s_es->s_journal_inum));
+ sbi->s_journal_ino);
if (ret)
goto err;
}
@@ -351,11 +351,20 @@ int ext4_check_blockref(const char *function, unsigned int line,
{
__le32 *bref = p;
unsigned int blk;
-
- if (ext4_has_feature_journal(inode->i_sb) &&
- (inode->i_ino ==
- le32_to_cpu(EXT4_SB(inode->i_sb)->s_es->s_journal_inum)))
- return 0;
+ struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
+
+ if (ext4_has_feature_journal(inode->i_sb)) {
+ /* If we are called from journal init path then
+ * sbi->s_journal_ino would be 0
+ */
+ u32 journal_ino = sbi->s_journal_ino ?
+ sbi->s_journal_ino :
+ sbi->s_es->s_journal_inum;
+ WARN_ON_ONCE(journal_ino == 0);
+
+ if (inode->i_ino == journal_ino)
+ return 0;
+ }
while (bref < p+max) {
blk = le32_to_cpu(*bref++);
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index 2b7d781bfcad..648b0459e9fd 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -1556,6 +1556,7 @@ struct ext4_sb_info {
u32 s_max_batch_time;
u32 s_min_batch_time;
struct file *s_journal_bdev_file;
+ u32 s_journal_ino;
#ifdef CONFIG_QUOTA
/* Names of quota files with journalled quota */
char __rcu *s_qf_names[EXT4_MAXQUOTAS];
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 365d31004bd0..50961bc0c94d 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -384,10 +384,21 @@ static int __check_block_validity(struct inode *inode, const char *func,
unsigned int line,
struct ext4_map_blocks *map)
{
- if (ext4_has_feature_journal(inode->i_sb) &&
- (inode->i_ino ==
- le32_to_cpu(EXT4_SB(inode->i_sb)->s_es->s_journal_inum)))
- return 0;
+ struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
+
+ if (ext4_has_feature_journal(inode->i_sb)) {
+ /*
+ * If we are called from journal init path then
+ * sbi->s_journal_ino would be 0
+ */
+ u32 journal_ino = sbi->s_journal_ino ?
+ sbi->s_journal_ino :
+ sbi->s_es->s_journal_inum;
+ WARN_ON_ONCE(journal_ino == 0);
+
+ if (inode->i_ino == journal_ino)
+ return 0;
+ }
if (!ext4_inode_block_valid(inode, map->m_pblk, map->m_len)) {
ext4_error_inode(inode, func, line, map->m_pblk,
"lblock %lu mapped to illegal pblock %llu "
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index a963ffda692a..44e79db7f12a 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -4162,7 +4162,8 @@ int ext4_calculate_overhead(struct super_block *sb)
struct ext4_sb_info *sbi = EXT4_SB(sb);
struct ext4_super_block *es = sbi->s_es;
struct inode *j_inode;
- unsigned int j_blocks, j_inum = le32_to_cpu(es->s_journal_inum);
+ unsigned int j_blocks;
+ u32 j_inum = sbi->s_journal_ino;
ext4_group_t i, ngroups = ext4_get_groups_count(sb);
ext4_fsblk_t overhead = 0;
char *buf = (char *) get_zeroed_page(GFP_NOFS);
@@ -6091,6 +6092,8 @@ static int ext4_load_journal(struct super_block *sb,
ext4_commit_super(sb);
}
+ EXT4_SB(sb)->s_journal_ino = le32_to_cpu(es->s_journal_inum);
+
return 0;
err_out:
--
2.48.1
next reply other threads:[~2025-03-14 11:42 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-03-14 11:41 Ojaswin Mujoo [this message]
2025-03-15 7:19 ` Zhang Yi
2025-03-16 1:41 ` Theodore Ts'o
2025-03-17 3:54 ` Baokun Li
2025-03-18 8:12 ` Ojaswin Mujoo
2025-03-19 2:31 ` Theodore Ts'o
2025-03-25 17:57 ` Ojaswin Mujoo
2025-03-26 2:16 ` Baokun Li
2025-03-26 4:01 ` Zhang Yi
2025-03-26 6:39 ` Ojaswin Mujoo
2025-03-26 8:33 ` Zhang Yi
2025-03-26 9:26 ` Baokun Li
2025-03-27 6:20 ` Ojaswin Mujoo
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=d1a9328a41029f6210a1924b192a59afcd3c5cee.1741952406.git.ojaswin@linux.ibm.com \
--to=ojaswin@linux.ibm.com \
--cc=jack@suse.cz \
--cc=libaokun1@huawei.com \
--cc=linux-ext4@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=ritesh.list@gmail.com \
--cc=tytso@mit.edu \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®