[RFC][overlayfs] do we still need d_instantiate_anon() and export of d_alloc_anon()?

Al Viro
2023-11-11T08:04:06Z

AFAICS, the main reason for exposing those used to be the need
to store ovl_entry in allocated dentry; we needed to do that before it
gets attached to inode, so the guts of d_obtain_alias() had to be
exposed.

These days overlayfs is stashing ovl_entry in the inode, so
we are left with this:
dentry = d_find_any_alias(inode);
if (dentry)
goto out_iput;

dentry = d_alloc_anon(inode->i_sb);
if (unlikely(!dentry))
goto nomem;

if (upper_alias)
ovl_dentry_set_upper_alias(dentry);

ovl_dentry_init_reval(dentry, upper, OVL_I_E(inode));

return d_instantiate_anon(dentry, inode);

ovl_dentry_init_reval() can bloody well be skipped, AFAICS - all it does
is potentially clearing DCACHE_OP_{,WEAK_}REVALIDATE. That's also done
in ovl_lookup(), and in case we have d_splice_alias() return a non-NULL
dentry we can simply copy it there. Sure, somebody might race with
us, pick dentry from hash and call ->d_revalidate() before we notice that
DCACHE_OP_REVALIDATE could be cleaned. So what? That call of ->d_revalidate()
will find nothing to do and return 1. Which is the effect of having
DCACHE_OP_REVALIDATE cleared, except for pointless method call. Anyone
who finds that dentry after the flag is cleared will skip the call.
IOW, that race is harmless.

And as for the ovl_dentry_set_upper_alias()... that information used to
live in ovl_entry until the need to trim the thing down. These days
it's in a bit in dentry->d_fsdata.

How painful would it be to switch to storing that in LSB of ovl_entry::__numlower,
turning ovl_numlower() into
return oe ? oe->__numlower>>1 : 0
and ovl_lowerdata() into
return lowerstack ? &lowerstack[(oe->__numlower>>1) - 1] : NULL
with obvious adjustment to ovl_alloc_entry().

An entry is coallocated with an array of struct ovl_path, with
numlower elements. More than 2G layers doesn't seem to be plausible -
there are fat 64bit boxen, but 32Gb (kmalloc'ed, at that) just in
the root ovl_entry alone feels somewhat over the top ;-)

So stealing that bit shouldn't be a problem. Is there anything I'm
missing?