Re: [PATCH v2 0/6] kernfs: proposed locking and concurrency improvement

From: Ian Kent
Date: Sat Dec 19 2020 - 18:53:29 EST


On Sat, 2020-12-19 at 11:23 -0500, Tejun Heo wrote:
> Hello,
>
> On Sat, Dec 19, 2020 at 03:08:13PM +0800, Ian Kent wrote:
> > And looking further I see there's a race that kernfs can't do
> > anything
> > about between kernfs_refresh_inode() and fs/inode.c:update_times().
>
> Do kernfs files end up calling into that path tho? Doesn't look like
> it to
> me but if so yeah we'd need to override the update_time for kernfs.

Sorry, the below was very hastily done and not what I would actually
propose.

The main point of it was the question

+ /* Which kernfs node attributes should be updated from
+ * time?
+ */

but looking at it again this morning I think the node iattr fields
that might need to be updated would be atime, ctime and mtime only,
maybe not ctime ... not sure.

What do you think?

Also, if kn->attr == NULL it should fall back to what the VFS
currently does.

The update_times() function is one of the few places where the
VFS updates the inode times.

The idea is that the reason kernfs needs to overwrite the inode
attributes is to reset what the VFS might have done but if kernfs
has this inode operation they won't need to be overwritten since
they won't have changed.

There may be other places where the attributes (or an attribute)
are set by the VFS, I haven't finished checking that yet so my
suggestion might not be entirely valid.

What I need to do is work out what kernfs node attributes, if any,
should be updated by .update_times(). If I go by what
kernfs_refresh_inode() does now then that would be none but shouldn't
atime at least be updated in the node iattr.

> > +static int kernfs_iop_update_time(struct inode *inode, struct
> > timespec64 *time, int flags)
> > {
> > - struct inode *inode = d_inode(path->dentry);
> > struct kernfs_node *kn = inode->i_private;
> > + struct kernfs_iattrs *attrs;
> >
> > mutex_lock(&kernfs_mutex);
> > + attrs = kernfs_iattrs(kn);
> > + if (!attrs) {
> > + mutex_unlock(&kernfs_mutex);
> > + return -ENOMEM;
> > + }
> > +
> > + /* Which kernfs node attributes should be updated from
> > + * time?
> > + */
> > +
> > kernfs_refresh_inode(kn, inode);
> > mutex_unlock(&kernfs_mutex);
>
> I don't see how this would reflect the changes from kernfs_setattr()
> into
> the attached inode. This would actually make the attr updates
> obviously racy
> - the userland visible attrs would be stale until the inode gets
> reclaimed
> and then when it gets reinstantiated it'd show the latest
> information.

Right, I will have to think about that, but as I say above this
isn't really what I would propose.

If .update_times() sticks strictly to what kernfs_refresh_inode()
does now then it would set the inode attributes from the node iattr
only.

>
> That said, if you wanna take the direction where attr updates are
> reflected
> to the associated inode when the change occurs, which makes sense,
> the right
> thing to do would be making kernfs_setattr() update the associated
> inode if
> existent.

Mmm, that's a good point but it looks like the inode isn't available
there.

Ian