[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <yobncpbrbe6ctjdtkpiff6u2uiq5fmoov6lhcyj5nvhawengny@5j5r2alelmug>
Date: Wed, 1 Oct 2025 17:11:33 +0200
From: Jan Kara <jack@...e.cz>
To: Mateusz Guzik <mjguzik@...il.com>
Cc: Jan Kara <jack@...e.cz>, brauner@...nel.org, viro@...iv.linux.org.uk,
linux-kernel@...r.kernel.org, linux-fsdevel@...r.kernel.org
Subject: Re: [PATCH] fs: assert on ->i_count in iput_final()
On Wed 01-10-25 16:28:15, Mateusz Guzik wrote:
> On Wed, Oct 1, 2025 at 3:08 PM Jan Kara <jack@...e.cz> wrote:
> >
> > On Wed 01-10-25 14:12:13, Mateusz Guzik wrote:
> > > On Wed, Oct 1, 2025 at 2:07 PM Jan Kara <jack@...e.cz> wrote:
> > > > > diff --git a/fs/inode.c b/fs/inode.c
> > > > > index ec9339024ac3..fa82cb810af4 100644
> > > > > --- a/fs/inode.c
> > > > > +++ b/fs/inode.c
> > > > > @@ -1879,6 +1879,7 @@ static void iput_final(struct inode *inode)
> > > > > int drop;
> > > > >
> > > > > WARN_ON(inode->i_state & I_NEW);
> > > > > + VFS_BUG_ON_INODE(atomic_read(&inode->i_count) != 0, inode);
> > > >
> > > > This seems pointless given when iput_final() is called...
> > > >
> > >
> > > This and the other check explicitly "wrap" the ->drop_inode call.
> >
> > I understand but given iput() has just decremented i_count to 0 before
> > calling iput_final() this beginning of the "wrap" looks pretty pointless to
> > me.
> >
>
> To my understanding you are not NAKing the patch, are merely not
> particularly fond of it. ;)
Yes, it isn't annoying me enough to nak it but I couldn't resist
complaining :)
> Given that these asserts don't show up in production kernels, the
> layer should be moving towards always spelling out all assumptions at
> the entry point. Worst case does not hurt in production anyway, best
> case it will catch something.
Well, I think that when we get too many asserts, the code is harder to
read.
> For iput_final specifically, at the moment there is only one consumer
> so this indeed may look overzealous.
>
> But for the sake of argument suppose someone noticed that
> dentry_unlink_inode() performs:
> spin_unlock(&inode->i_lock);
> if (!inode->i_nlink)
> fsnotify_inoderemove(inode);
> if (dentry->d_op && dentry->d_op->d_iput)
> dentry->d_op->d_iput(dentry, inode);
> else
> iput(inode);
>
> ... and that with some minor rototoiling the inode lock can survive
> both fsnotify and custom d_iput in the common case. Should that
> happen, iput_locked() could be added to shave off a lock trip in the
> common case of whacking the inode. But then there is 2 consumers of
> iput_final. etc.
Right. And when we grow second iput_final() caller, I'd withdraw my
complaint about pointless assert ;).
Honza
--
Jan Kara <jack@...e.com>
SUSE Labs, CR
Powered by blists - more mailing lists