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

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Sat, Nov 11, 2023 at 10:04 AM Al Viro <viro@xxxxxxxxxxxxxxxxxx> wrote:
>
>         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.

Just a minute.
Do you know that ovl_obtain_alias() is *only* used to obtain a disconnected
non-dir overlayfs dentry?

I think that makes all the analysis regarding race with d_splice_alias()
moot. Right?

Do DCACHE_OP_*REVALIDATE even matter for a disconnected
non-dir dentry?

>
> 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?

You are missing that the OVL_E_UPPER_ALIAS flag is a property of
the overlay dentry, not a property of the inode.

N lower hardlinks, the first copy up created an upper inode
all the rest of the N upper aliases to that upper inode are
created lazily.

However, for obvious reasons, OVL_E_UPPER_ALIAS is not
well defined for a disconnected overlay dentry.
There should not be any code (I hope) that cares about
OVL_E_UPPER_ALIAS for a disconnected overlay dentry,
so I *think* ovl_dentry_set_upper_alias() in this code is moot.

I need to look closer to verify, but please confirm my assumption
regarding the irrelevance of  DCACHE_OP_*REVALIDATE for a
disconnected non-dir dentry.

Thanks,
Amir.




[Index of Archives]     [Linux Filesystems Devel]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux