fs/ext2/namei.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
ext2_unlink() calls inode_dec_link_count() unconditionally, which
invokes drop_nlink(). If the inode was loaded from a corrupted disk
image with i_links_count == 0, drop_nlink()
triggers WARN_ON(inode->i_nlink == 0)
Follow the ext4 pattern from __ext4_unlink(): check i_nlink before
decrementing. If already zero, skip the decrement.
Signed-off-by: Ziyi Guo <n7l8m4@u.northwestern.edu>
---
fs/ext2/namei.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/fs/ext2/namei.c b/fs/ext2/namei.c
index bde617a66cec..c746cf169a4d 100644
--- a/fs/ext2/namei.c
+++ b/fs/ext2/namei.c
@@ -293,7 +293,10 @@ static int ext2_unlink(struct inode *dir, struct dentry *dentry)
goto out;
inode_set_ctime_to_ts(inode, inode_get_ctime(dir));
- inode_dec_link_count(inode);
+
+ if (inode->i_nlink)
+ inode_dec_link_count(inode);
+
err = 0;
out:
return err;
--
2.34.1
On Wed 11-02-26 02:20:52, Ziyi Guo wrote: > ext2_unlink() calls inode_dec_link_count() unconditionally, which > invokes drop_nlink(). If the inode was loaded from a corrupted disk > image with i_links_count == 0, drop_nlink() > triggers WARN_ON(inode->i_nlink == 0) > > Follow the ext4 pattern from __ext4_unlink(): check i_nlink before > decrementing. If already zero, skip the decrement. > > Signed-off-by: Ziyi Guo <n7l8m4@u.northwestern.edu> Thanks! I've merged the patch to my tree now. Honza > --- > fs/ext2/namei.c | 5 ++++- > 1 file changed, 4 insertions(+), 1 deletion(-) > > diff --git a/fs/ext2/namei.c b/fs/ext2/namei.c > index bde617a66cec..c746cf169a4d 100644 > --- a/fs/ext2/namei.c > +++ b/fs/ext2/namei.c > @@ -293,7 +293,10 @@ static int ext2_unlink(struct inode *dir, struct dentry *dentry) > goto out; > > inode_set_ctime_to_ts(inode, inode_get_ctime(dir)); > - inode_dec_link_count(inode); > + > + if (inode->i_nlink) > + inode_dec_link_count(inode); > + > err = 0; > out: > return err; > -- > 2.34.1 > -- Jan Kara <jack@suse.com> SUSE Labs, CR
© 2016 - 2026 Red Hat, Inc.