在 2021/8/8 0:37, Amir Goldstein 写道:
I remembered some more details...
I think the main complication discussed w.r.t decoding a metacopy
inode was for the case where ovl_inode_lowerdata() differs from
ovl_inode_lower().
If we had a weaker variant of metacopy (e.g. metacopy=upper) that
only allows creating and following metacopy inodes in the upper layer,
it would have been simpler to implement ovl_obtain_alias().
Specifically, when ofs->numlayer == 2 (single lower layer), there can
be no valid metacopy inodes in the lower layer, so that configuration
should also be rather easy to support.
Basically, for ovl_obtain_alias():
- 'lowerpath' must not have metadata xattr
- 'upper_alias' must not have metadata xattr
- If 'index' has metacopy xattr, OVL_UPPERDATA flag
should not be set on ovl inode
But there are bigger complications w.r.t disconnected dentry.
Overlayfs knows how to decode, work with and copy up
disconnected dentries (parent is unknown), but in ovl_link(old, ...),
Can we get a disconnected non-dir dentry in normal process, or how to
produce a disconnected dentry?
If I understand correctly, metacopy only inode will be processed in
ovl_lower_fh_to_d():
706 /* First lookup overlay inode in inode cache by origin fh */
707 err = ovl_check_origin_fh(ofs, fh, false, NULL, &stack);
708 if (err)
709 return ERR_PTR(err);
710
711 if (!d_is_dir(origin.dentry) ||
712 !(origin.dentry->d_flags & DCACHE_DISCONNECTED)) {
713 inode = ovl_lookup_inode(sb, origin.dentry, false);
714 err = PTR_ERR(inode);
715 if (IS_ERR(inode))
716 goto out_err;
717 if (inode) {
718 dentry =
d_find_any_alias(inode); // A NULL dentry found
here? How did it happen?
719 iput(inode);
720 if (dentry)
721 goto out;
722 }
723 }
[...]
762 /* Get a connected non-upper dir or disconnected non-dir */
763 dentry = ovl_get_dentry(sb, NULL, &origin, index); //
Get disconnected non-dir.
'old' dentry must not be a disconnected metacopy dentry when
calling ovl_set_link_redirect() => ... ovl_get_redirect(), so we will
also need to:
- On copy up of a disconnected lower, do not use metacopy
- Copy up data before ovl_link() when nfs_export is enabled
- In ovl_obtain_alias(), if 'index' has redirect:
-- Verify that it is an absolute path that it is resolved to the
'lowerpath's inode
-- oip.redirect needs to be passed to ovl_get_inode()
-- ovl_verify_inode() needs to verify that oip.redirect matches
redirect that is found on existing ovl inode
And probably other things that I am forgetting...
Thanks,
Amir.
.