[PATCH] nilfs2: fix link count underflow when removing corrupted directory

From: Ryusuke Konishi

Date: Tue Oct 06 2026 - 05:07:06 EST


When removing an empty directory with a corrupted link count (e.g.,
i_nlink is 1 due to filesystem corruption), nilfs_rmdir() calls
drop_nlink() via nilfs_do_unlink() and then calls drop_nlink() again
on the directory inode. This second call causes an underflow of
i_nlink, triggering a kernel WARNING in drop_nlink().

Fix this issue by using clear_nlink() instead of drop_nlink() to
finalize the link count reset for the target directory in nilfs_rmdir().
Additionally, log a warning message when i_nlink is not 2 before
removing an empty directory to notify about the link count inconsistency.

Reported-by: syzbot+c388db0347b7fc88fa7a@xxxxxxxxxxxxxxxxxxxxxxxxx
Closes: https://syzkaller.appspot.com/bug?extid=c388db0347b7fc88fa7a
Fixes: d25006523d0b ("nilfs2: pathname operations")
Signed-off-by: Ryusuke Konishi <konishi.ryusuke@xxxxxxxxx>
---
Hi Viacheslav,

Please apply this for the next cycle.

This fixes a link count underflow during rmdir on a directory with a
corrupted link count (an issue recently reported by syzbot).

Thanks,
Ryusuke Konishi

fs/nilfs2/namei.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/fs/nilfs2/namei.c b/fs/nilfs2/namei.c
index e037e0c6e31a..d326bb1acb11 100644
--- a/fs/nilfs2/namei.c
+++ b/fs/nilfs2/namei.c
@@ -341,10 +341,16 @@ static int nilfs_rmdir(struct inode *dir, struct dentry *dentry)

err = -ENOTEMPTY;
if (nilfs_empty_dir(inode)) {
+ if (unlikely(inode->i_nlink != 2))
+ nilfs_warn(dir->i_sb,
+ "inconsistent empty directory link count %u (ino=%llu)",
+ inode->i_nlink,
+ (unsigned long long)inode->i_ino);
+
err = nilfs_do_unlink(dir, dentry);
if (!err) {
inode->i_size = 0;
- drop_nlink(inode);
+ clear_nlink(inode);
nilfs_mark_inode_dirty(inode);
drop_nlink(dir);
nilfs_mark_inode_dirty(dir);
--
2.53.0