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

From: Viacheslav Dubeyko

Date: Tue Oct 06 2026 - 13:05:12 EST


On Tue, 2026-10-06 at 17:48 +0900, Ryusuke Konishi wrote:
> 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);

Applied.

Thanks,
Slava.