* [PATCH] ext4: fix iloc.bh leak in ext4_fc_replay_inode() error paths
@ 2026-03-23 6:08 Baokun Li
2026-03-23 10:08 ` Jan Kara
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Baokun Li @ 2026-03-23 6:08 UTC (permalink / raw)
To: linux-ext4
Cc: tytso, adilger.kernel, jack, yi.zhang, ojaswin, ritesh.list,
libaokun, Joseph Qi
During code review, Joseph found that ext4_fc_replay_inode() calls
ext4_get_fc_inode_loc() to get the inode location, which holds a
reference to iloc.bh that must be released via brelse().
However, several error paths jump to the 'out' label without
releasing iloc.bh:
- ext4_handle_dirty_metadata() failure
- sync_dirty_buffer() failure
- ext4_mark_inode_used() failure
- ext4_iget() failure
Fix this by introducing an 'out_brelse' label placed just before
the existing 'out' label to ensure iloc.bh is always released.
Additionally, make ext4_fc_replay_inode() propagate errors
properly instead of always returning 0.
Reported-by: Joseph Qi <joseph.qi@linux.alibaba.com>
Fixes: 8016e29f4362 ("ext4: fast commit recovery path")
Signed-off-by: Baokun Li <libaokun@linux.alibaba.com>
---
fs/ext4/fast_commit.c | 13 ++++++++-----
1 file changed, 8 insertions(+), 5 deletions(-)
diff --git a/fs/ext4/fast_commit.c b/fs/ext4/fast_commit.c
index f575751f1cae..f1df5581fa96 100644
--- a/fs/ext4/fast_commit.c
+++ b/fs/ext4/fast_commit.c
@@ -1613,19 +1613,21 @@ static int ext4_fc_replay_inode(struct super_block *sb,
/* Immediately update the inode on disk. */
ret = ext4_handle_dirty_metadata(NULL, NULL, iloc.bh);
if (ret)
- goto out;
+ goto out_brelse;
ret = sync_dirty_buffer(iloc.bh);
if (ret)
- goto out;
+ goto out_brelse;
ret = ext4_mark_inode_used(sb, ino);
if (ret)
- goto out;
+ goto out_brelse;
/* Given that we just wrote the inode on disk, this SHOULD succeed. */
inode = ext4_iget(sb, ino, EXT4_IGET_NORMAL);
if (IS_ERR(inode)) {
ext4_debug("Inode not found.");
- return -EFSCORRUPTED;
+ inode = NULL;
+ ret = -EFSCORRUPTED;
+ goto out_brelse;
}
/*
@@ -1642,13 +1644,14 @@ static int ext4_fc_replay_inode(struct super_block *sb,
ext4_inode_csum_set(inode, ext4_raw_inode(&iloc), EXT4_I(inode));
ret = ext4_handle_dirty_metadata(NULL, NULL, iloc.bh);
sync_dirty_buffer(iloc.bh);
+out_brelse:
brelse(iloc.bh);
out:
iput(inode);
if (!ret)
blkdev_issue_flush(sb->s_bdev);
- return 0;
+ return ret;
}
/*
--
2.43.7
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH] ext4: fix iloc.bh leak in ext4_fc_replay_inode() error paths
2026-03-23 6:08 [PATCH] ext4: fix iloc.bh leak in ext4_fc_replay_inode() error paths Baokun Li
@ 2026-03-23 10:08 ` Jan Kara
2026-03-23 11:05 ` Zhang Yi
2026-03-28 5:31 ` Theodore Ts'o
2 siblings, 0 replies; 4+ messages in thread
From: Jan Kara @ 2026-03-23 10:08 UTC (permalink / raw)
To: Baokun Li
Cc: linux-ext4, tytso, adilger.kernel, jack, yi.zhang, ojaswin,
ritesh.list, Joseph Qi
On Mon 23-03-26 14:08:36, Baokun Li wrote:
> During code review, Joseph found that ext4_fc_replay_inode() calls
> ext4_get_fc_inode_loc() to get the inode location, which holds a
> reference to iloc.bh that must be released via brelse().
>
> However, several error paths jump to the 'out' label without
> releasing iloc.bh:
>
> - ext4_handle_dirty_metadata() failure
> - sync_dirty_buffer() failure
> - ext4_mark_inode_used() failure
> - ext4_iget() failure
>
> Fix this by introducing an 'out_brelse' label placed just before
> the existing 'out' label to ensure iloc.bh is always released.
>
> Additionally, make ext4_fc_replay_inode() propagate errors
> properly instead of always returning 0.
>
> Reported-by: Joseph Qi <joseph.qi@linux.alibaba.com>
> Fixes: 8016e29f4362 ("ext4: fast commit recovery path")
> Signed-off-by: Baokun Li <libaokun@linux.alibaba.com>
Looks good. Feel free to add:
Reviewed-by: Jan Kara <jack@suse.cz>
Honza
> ---
> fs/ext4/fast_commit.c | 13 ++++++++-----
> 1 file changed, 8 insertions(+), 5 deletions(-)
>
> diff --git a/fs/ext4/fast_commit.c b/fs/ext4/fast_commit.c
> index f575751f1cae..f1df5581fa96 100644
> --- a/fs/ext4/fast_commit.c
> +++ b/fs/ext4/fast_commit.c
> @@ -1613,19 +1613,21 @@ static int ext4_fc_replay_inode(struct super_block *sb,
> /* Immediately update the inode on disk. */
> ret = ext4_handle_dirty_metadata(NULL, NULL, iloc.bh);
> if (ret)
> - goto out;
> + goto out_brelse;
> ret = sync_dirty_buffer(iloc.bh);
> if (ret)
> - goto out;
> + goto out_brelse;
> ret = ext4_mark_inode_used(sb, ino);
> if (ret)
> - goto out;
> + goto out_brelse;
>
> /* Given that we just wrote the inode on disk, this SHOULD succeed. */
> inode = ext4_iget(sb, ino, EXT4_IGET_NORMAL);
> if (IS_ERR(inode)) {
> ext4_debug("Inode not found.");
> - return -EFSCORRUPTED;
> + inode = NULL;
> + ret = -EFSCORRUPTED;
> + goto out_brelse;
> }
>
> /*
> @@ -1642,13 +1644,14 @@ static int ext4_fc_replay_inode(struct super_block *sb,
> ext4_inode_csum_set(inode, ext4_raw_inode(&iloc), EXT4_I(inode));
> ret = ext4_handle_dirty_metadata(NULL, NULL, iloc.bh);
> sync_dirty_buffer(iloc.bh);
> +out_brelse:
> brelse(iloc.bh);
> out:
> iput(inode);
> if (!ret)
> blkdev_issue_flush(sb->s_bdev);
>
> - return 0;
> + return ret;
> }
>
> /*
> --
> 2.43.7
>
--
Jan Kara <jack@suse.com>
SUSE Labs, CR
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] ext4: fix iloc.bh leak in ext4_fc_replay_inode() error paths
2026-03-23 6:08 [PATCH] ext4: fix iloc.bh leak in ext4_fc_replay_inode() error paths Baokun Li
2026-03-23 10:08 ` Jan Kara
@ 2026-03-23 11:05 ` Zhang Yi
2026-03-28 5:31 ` Theodore Ts'o
2 siblings, 0 replies; 4+ messages in thread
From: Zhang Yi @ 2026-03-23 11:05 UTC (permalink / raw)
To: Baokun Li, linux-ext4
Cc: tytso, adilger.kernel, jack, ojaswin, ritesh.list, Joseph Qi
On 3/23/2026 2:08 PM, Baokun Li wrote:
> During code review, Joseph found that ext4_fc_replay_inode() calls
> ext4_get_fc_inode_loc() to get the inode location, which holds a
> reference to iloc.bh that must be released via brelse().
>
> However, several error paths jump to the 'out' label without
> releasing iloc.bh:
>
> - ext4_handle_dirty_metadata() failure
> - sync_dirty_buffer() failure
> - ext4_mark_inode_used() failure
> - ext4_iget() failure
>
> Fix this by introducing an 'out_brelse' label placed just before
> the existing 'out' label to ensure iloc.bh is always released.
>
> Additionally, make ext4_fc_replay_inode() propagate errors
> properly instead of always returning 0.
>
> Reported-by: Joseph Qi <joseph.qi@linux.alibaba.com>
> Fixes: 8016e29f4362 ("ext4: fast commit recovery path")
> Signed-off-by: Baokun Li <libaokun@linux.alibaba.com>
Looks good to me.
Reviewed-by: Zhang Yi <yi.zhang@huawei.com>
> ---
> fs/ext4/fast_commit.c | 13 ++++++++-----
> 1 file changed, 8 insertions(+), 5 deletions(-)
>
> diff --git a/fs/ext4/fast_commit.c b/fs/ext4/fast_commit.c
> index f575751f1cae..f1df5581fa96 100644
> --- a/fs/ext4/fast_commit.c
> +++ b/fs/ext4/fast_commit.c
> @@ -1613,19 +1613,21 @@ static int ext4_fc_replay_inode(struct super_block *sb,
> /* Immediately update the inode on disk. */
> ret = ext4_handle_dirty_metadata(NULL, NULL, iloc.bh);
> if (ret)
> - goto out;
> + goto out_brelse;
> ret = sync_dirty_buffer(iloc.bh);
> if (ret)
> - goto out;
> + goto out_brelse;
> ret = ext4_mark_inode_used(sb, ino);
> if (ret)
> - goto out;
> + goto out_brelse;
>
> /* Given that we just wrote the inode on disk, this SHOULD succeed. */
> inode = ext4_iget(sb, ino, EXT4_IGET_NORMAL);
> if (IS_ERR(inode)) {
> ext4_debug("Inode not found.");
> - return -EFSCORRUPTED;
> + inode = NULL;
> + ret = -EFSCORRUPTED;
> + goto out_brelse;
> }
>
> /*
> @@ -1642,13 +1644,14 @@ static int ext4_fc_replay_inode(struct super_block *sb,
> ext4_inode_csum_set(inode, ext4_raw_inode(&iloc), EXT4_I(inode));
> ret = ext4_handle_dirty_metadata(NULL, NULL, iloc.bh);
> sync_dirty_buffer(iloc.bh);
> +out_brelse:
> brelse(iloc.bh);
> out:
> iput(inode);
> if (!ret)
> blkdev_issue_flush(sb->s_bdev);
>
> - return 0;
> + return ret;
> }
>
> /*
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] ext4: fix iloc.bh leak in ext4_fc_replay_inode() error paths
2026-03-23 6:08 [PATCH] ext4: fix iloc.bh leak in ext4_fc_replay_inode() error paths Baokun Li
2026-03-23 10:08 ` Jan Kara
2026-03-23 11:05 ` Zhang Yi
@ 2026-03-28 5:31 ` Theodore Ts'o
2 siblings, 0 replies; 4+ messages in thread
From: Theodore Ts'o @ 2026-03-28 5:31 UTC (permalink / raw)
To: linux-ext4, Baokun Li
Cc: Theodore Ts'o, adilger.kernel, jack, yi.zhang, ojaswin,
ritesh.list, Joseph Qi
On Mon, 23 Mar 2026 14:08:36 +0800, Baokun Li wrote:
> During code review, Joseph found that ext4_fc_replay_inode() calls
> ext4_get_fc_inode_loc() to get the inode location, which holds a
> reference to iloc.bh that must be released via brelse().
>
> However, several error paths jump to the 'out' label without
> releasing iloc.bh:
>
> [...]
Applied, thanks!
[1/1] ext4: fix iloc.bh leak in ext4_fc_replay_inode() error paths
commit: ec0a7500d8eace5b4f305fa0c594dd148f0e8d29
Best regards,
--
Theodore Ts'o <tytso@mit.edu>
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-03-28 5:33 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-23 6:08 [PATCH] ext4: fix iloc.bh leak in ext4_fc_replay_inode() error paths Baokun Li
2026-03-23 10:08 ` Jan Kara
2026-03-23 11:05 ` Zhang Yi
2026-03-28 5:31 ` Theodore Ts'o
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox