On Tue, Apr 10, 2018 at 10:20 PM, Amir Goldstein <amir73il@xxxxxxxxx> wrote: > On Tue, Apr 10, 2018 at 5:00 PM, Vivek Goyal <vgoyal@xxxxxxxxxx> wrote: [...] >> >> In fact I see OVL_INDEX being used in ovl_getattr(). If a parallel copy >> up took place it is possible that ovl_getattr() saw upperdentry but not >> the OVL_INDEX. And then nlink count will be off. IOW, what barrier/lock >> guarantees that this does not happen. >> > > Yes. and that is not the only problem I see with ovl_getattr(). > > stat->dev could be set to ovl_get_pseudo_dev(dentry), even > if stat->ino is not set to lowerstat.ino; that is not good. > > If I am not mistaken, all the special conditions in ovl_getattr() > to use lower st_ino are already encoded in ovl_hash_bylower(), > so you may completely remove those extra tests if > OVL_TYPE_ORIGIN(type) already checks the OVL_BYLOWER > flag. > > It may be hard to see my claim above is true, because, for > example, sb->s_export_op in ovl_hash_bylower() is equivalent > to ovl_verify_lower(dentry->d_sb) in ovl_getattr(). > > Please double check my claims, and if you agree, you can submit a > patch that Fixes: ("a0c5ad307ac0 ovl: relax same fs constraint for > constant st_ino"), which already does the right thing for metacopy. > On second thought, it would be better to submit the simple fix patch first, so it could be applied to stable kernels that don't have ovl_hash_bylower() and only then submit the patch that adds OVL_BYLOWER and removes the extra tests in ovl_getattr(). Something like this (untested) should do. Let me know if you would like me to submit the fix patch. Thanks, Amir. diff --git a/fs/overlayfs/inode.c b/fs/overlayfs/inode.c index 3b1bd469accd..34fe86dedd3b 100644 --- a/fs/overlayfs/inode.c +++ b/fs/overlayfs/inode.c @@ -118,13 +118,10 @@ int ovl_getattr(const struct path *path, struct kstat *stat, */ if (ovl_test_flag(OVL_INDEX, d_inode(dentry)) || (!ovl_verify_lower(dentry->d_sb) && - (is_dir || lowerstat.nlink == 1))) + (is_dir || lowerstat.nlink == 1))) { stat->ino = lowerstat.ino; - - if (samefs) - WARN_ON_ONCE(stat->dev != lowerstat.dev); - else stat->dev = ovl_get_pseudo_dev(dentry); + } } if (samefs) { /* -- To unsubscribe from this list: send the line "unsubscribe linux-unionfs" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html