public inbox for linux-unionfs@vger.kernel.org
 help / color / mirror / Atom feed
From: Vivek Goyal <vgoyal@redhat.com>
To: Amir Goldstein <amir73il@gmail.com>
Cc: overlayfs <linux-unionfs@vger.kernel.org>,
	Miklos Szeredi <miklos@szeredi.hu>
Subject: Re: [PATCH v13 20/28] ovl: Do not set dentry type ORIGIN for broken hardlinks
Date: Wed, 11 Apr 2018 09:31:07 -0400	[thread overview]
Message-ID: <20180411133107.GA4568@redhat.com> (raw)
In-Reply-To: <CAOQ4uxip6BJ5ZmXY8b_1gsnXp8fujHGvnK7kjYQ6e24SzovB9A@mail.gmail.com>

On Wed, Apr 11, 2018 at 11:58:54AM +0300, Amir Goldstein wrote:
> On Tue, Apr 10, 2018 at 11:51 PM, Vivek Goyal <vgoyal@redhat.com> wrote:
> > On Tue, Apr 10, 2018 at 10:20:43PM +0300, Amir Goldstein wrote:
> >> On Tue, Apr 10, 2018 at 5:00 PM, Vivek Goyal <vgoyal@redhat.com> wrote:
> >> > On Fri, Mar 30, 2018 at 12:54:14PM +0300, Amir Goldstein wrote:
> >> >> On Thu, Mar 29, 2018 at 10:38 PM, Vivek Goyal <vgoyal@redhat.com> wrote:
> >> >> > If a dentry has copy up origin, we set flag OVL_PATH_ORIGIN. So far
> >> >> > this decision was easy that we had to check only for oe->numlower
> >> >> > and if it is non-zero, we knew there is copy up origin. (For non-dir
> >> >> > we installed origin dentry in lowerstack[0]).
> >> >> >
> >> >> > But we don't create ORGIN xattr for broken hardlinks (index=off). And
> >> >> > with metacopy feature it is possible that we will still install
> >> >> > lowerstack[0]. But that's lower data dentry of metacopy upper of broken
> >> >> > hardlink and not ORIGIN XATTR is not set.
> >> >> >
> >> >> > So two differentiate between two cases, do not set OVL_PATH_ORIGIN if
> >> >> > we have a broken hardlink.
> >> >> >
> >> >> > Signed-off-by: Vivek Goyal <vgoyal@redhat.com>
> >> >> > ---
> >> >> >  fs/overlayfs/util.c | 9 ++++++++-
> >> >> >  1 file changed, 8 insertions(+), 1 deletion(-)
> >> >> >
> >> >> > diff --git a/fs/overlayfs/util.c b/fs/overlayfs/util.c
> >> >> > index 29f7336ade88..961d65bd25c9 100644
> >> >> > --- a/fs/overlayfs/util.c
> >> >> > +++ b/fs/overlayfs/util.c
> >> >> > @@ -117,7 +117,14 @@ enum ovl_path_type ovl_path_type(struct dentry *dentry)
> >> >> >                  * Non-dir dentry can hold lower dentry of its copy up origin.
> >> >>
> >> >> This comment needs updating with metacopy.
> >> >>
> >> >> >                  */
> >> >> >                 if (oe->numlower) {
> >> >> > -                       type |= __OVL_PATH_ORIGIN;
> >> >> > +                       /*
> >> >> > +                        * ORIGIN is created for everyting except broken
> >> >> > +                        * hardlinks
> >> >> > +                        */
> >> >> > +                       if (!(d_inode(dentry)->i_nlink > 1 &&
> >> >> > +                           !ovl_test_flag(OVL_INDEX, d_inode(dentry))))
> >> >> > +                               type |= __OVL_PATH_ORIGIN;
> >> >> > +
> >> >>
> >> >> I don't like relying on overlay nlink. it is not reliable.
> >> >> And I think you missed the directory case.
> >> >
> >> > Directory should be fine because for directories ->i_nlink == 1 and this
> >> > condition will become true.
> >> >
> >> >> The information you need was available during lookup
> >> >> and we did not keep it (was lower verified by origin fh).
> >> >> Most likely what we need to do it store OVL_ORIGIN inode flag
> >> >> during lookup and then use ovl_test_flag(OVL_ORIGIN)
> >> >> in place of OVL_TYPE_ORIGIN(type).
> >> >>
> >> >> If I am not mistaken, you could set flag OVL_ORIGIN in
> >> >> ovl_get_inode() IFF (upperdentry && bylower), but to be honest
> >> >> the rules became so complicated that I can't say for sure.
> >> >> At least I concentrated all the rules in one helper ovl_hash_bylower(),
> >> >> so I hope that helps.
> >> >
> >> > Ok, I can put another ovl-inode flag say OVL_ORIGIN. But that also means
> >> > that I need to set the flag during copy up. And that means it brings
> >> > back ordering requirements for lockless access. For example, in
> >> > ovl_getattr(), if we replace OVL_TYPE_ORIGIN() with ovl_test_flag(ORIGIN),
> >> > without explicit barriers, what's the guarantee a user will see OVL_ORIGIN
> >> > flag yet. In fact it can happen that user might see upperdentry but not
> >> > OVL_ORIGIN.
> >>
> >> OK, so instead set OVL_BYLOWER in ovl_get_inode() IFF (bylower).
> >> that property doesn't change on copy up.
> >> and set __OVL_PATH_ORIGIN in ovl_path_type() if upper AND numlower
> >> AND OVL_BYLOWER.
> >
> > Ok, so at the time of lookup, we know if hardlink will be broken or
> > not and that property does not change over copy up. So yes that should
> > solve the issue.
> >
> > Having said that, OVL_BYLOWER is very broad in my opinion. Setting
> > OVL_ORIGIN in inode appeals more to me. This means this inode either
> > has copy up origin or will have copy up origin when copy up
> > happens.
> >
> > What do you think?
> 
> I think its better to choose a good flag name than to add complexity.
> How about OVL_CONST_INO?

OVL_CONST_INO sounds better in terms of naming. So it will translate
to ORIGIN.

OVL_ORIGIN = (upperdentry && OVL_CONST_INO)

> 
> >
> > I have another proposal. All these problems seem to stem from the
> > fact that copy up changes some of the fields in ovl_inode and we
> > don't have any strict ordering for the updates.
> >
> > I am wondering can we replace data dependency barrier
> > (smp_read_barrier_depends) with a full smp_read() and use that
> > for ovl_dentry_upper(). And do all the flag updates before
> > ovl_inode_update(). This should make sure that if caller sees
> > upperdentry, then not only upper dentry is table, at the same
> > time any updates to OVL_INDEX, OVL_ORIGIN and any other flags
> > have been done.
> >
> > So in copy up path, we will first update OVL_INDEX, OVL_ORIGIN etc
> > and then call ovl_inode_update(). And on read side fetch upperdentry
> > first and put smp_rmb() after that. And if upperdentry is visible,
> > that means INDEX and ORIGIN update must be visible as well.
> >
> > Copy up side
> > -----------
> >         store OVL_INDEX
> >         store OVL_ORIGIN
> >         store any other relevant flag
> >         smp_wmb()
> >         store ovl_inode->__upperdentry
> >
> > Read side (ovl_getxattr and other users)
> > -----------------------------------------
> >         load ovl_inode->__upperdentry
> >         smp_rmb()
> >         load OVL_INDEX
> >         load OVL_ORIGIN
> >
> > Now if ovl_inode->__upperdentry is set, that means not only upper dentry
> > is stable, it should also mean that ovl_inode->flags are stable too.
> >
> > If this theory of barrier operations is correct, I feel this is a better
> > solution. It is easy to understand at the same time it allows for
> > easy code extension in future.
> >
> > Right now, these lockless assumptions are so difficult to understand
> > and so error prone, that all the new users will invariably end up
> > introducing races.
> >
> 
> I see the value in your proposal, but:
> 1. I do not know how to measure the performance impact of this change.
> 2. patch 20/28 introduces another smp_wmb() in ovl_copy_up_locked()
> and it is not conditional to metacopy being enabled. Is that right?
> Can your proposal make that any better?

I am thinking that for now I will leave it as it is because OVL_CONST_INO
probably will solve the immediate issue. I will probably take up this
proposal in a separate patch series once we are done merging a basic
metacopy patch series.

Thanks
Vivek

> 
> >>
> >> >
> >> > 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.
> >
> > I will need to spend some time to better understand it. I feel that
> > changing barrier semantics around __upperdentry, will solve this
> > issue with existing code as well.
> >
> 
> Its a simple bug not related to barriers semantics.
> I will post a fix patch.
> 
> Thanks,
> Amir.

  reply	other threads:[~2018-04-11 13:31 UTC|newest]

Thread overview: 91+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-03-29 19:38 [PATCH v13 00/28] overlayfs: Delayed copy up of data Vivek Goyal
2018-03-29 19:38 ` [PATCH v13 01/28] ovl: Set OVL_INDEX flag in ovl_get_inode() Vivek Goyal
2018-03-30  4:59   ` Amir Goldstein
2018-03-29 19:38 ` [PATCH v13 02/28] ovl: Initialize ovl_inode->redirect " Vivek Goyal
2018-03-30  4:57   ` Amir Goldstein
2018-03-29 19:38 ` [PATCH v13 03/28] ovl: Rename local variable locked to new_locked Vivek Goyal
2018-03-30  4:58   ` Amir Goldstein
2018-03-29 19:38 ` [PATCH v13 04/28] ovl: Provide a mount option metacopy=on/off for metadata copyup Vivek Goyal
2018-03-30  4:52   ` Amir Goldstein
2018-04-02 13:56     ` Vivek Goyal
2018-04-05 20:16       ` Amir Goldstein
2018-04-06 13:51         ` Vivek Goyal
2018-03-29 19:38 ` [PATCH v13 05/28] ovl: During copy up, first copy up metadata and then data Vivek Goyal
2018-03-29 19:38 ` [PATCH v13 06/28] ovl: Move the copy up helpers to copy_up.c Vivek Goyal
2018-03-29 19:38 ` [PATCH v13 07/28] ovl: Copy up only metadata during copy up where it makes sense Vivek Goyal
2018-03-29 19:38 ` [PATCH v13 08/28] ovl: Add helper ovl_already_copied_up() Vivek Goyal
2018-03-29 19:38 ` [PATCH v13 09/28] ovl: A new xattr OVL_XATTR_METACOPY for file on upper Vivek Goyal
2018-04-11 15:10   ` Amir Goldstein
2018-04-11 15:53     ` Vivek Goyal
2018-03-29 19:38 ` [PATCH v13 10/28] ovl: Modify ovl_lookup() and friends to lookup metacopy dentry Vivek Goyal
2018-03-30  5:49   ` Amir Goldstein
2018-03-30  9:12     ` Amir Goldstein
2018-04-02 19:45       ` Vivek Goyal
2018-04-02 20:07         ` Amir Goldstein
2018-04-02 15:06     ` Vivek Goyal
2018-03-29 19:38 ` [PATCH v13 11/28] ovl: Copy up meta inode data from lowest data inode Vivek Goyal
2018-03-29 19:38 ` [PATCH v13 12/28] ovl: Fix ovl_getattr() to get number of blocks from lower Vivek Goyal
2018-03-30  9:24   ` Amir Goldstein
2018-04-02 20:11     ` Vivek Goyal
2018-04-02 20:27       ` Amir Goldstein
2018-03-29 19:38 ` [PATCH v13 13/28] ovl: Add helper ovl_dentry_lowerdata() to get lower data dentry Vivek Goyal
2018-03-30  6:01   ` Amir Goldstein
2018-04-02 15:08     ` Vivek Goyal
2018-03-29 19:38 ` [PATCH v13 14/28] ovl: Do not expose metacopy only dentry from d_real() Vivek Goyal
2018-03-29 19:38 ` [PATCH v13 15/28] ovl: Move some of ovl_nlink_start() functionality in ovl_nlink_prep() Vivek Goyal
2018-03-30  6:23   ` Amir Goldstein
2018-03-29 19:38 ` [PATCH v13 16/28] ovl: Create locked version of ovl_nlink_start() and ovl_nlink_end() Vivek Goyal
2018-03-30  6:28   ` Amir Goldstein
2018-03-29 19:38 ` [PATCH v13 17/28] ovl: During rename lock both source and target ovl_inode Vivek Goyal
2018-03-30  6:50   ` Amir Goldstein
2018-04-02 17:34     ` Vivek Goyal
2018-03-29 19:38 ` [PATCH v13 18/28] ovl: Check redirects for metacopy files Vivek Goyal
2018-03-30 10:02   ` Amir Goldstein
2018-04-02 20:29     ` Vivek Goyal
2018-04-03  5:44       ` Amir Goldstein
2018-04-03 12:31         ` Vivek Goyal
2018-03-29 19:38 ` [PATCH v13 19/28] ovl: Treat metacopy dentries as type OVL_PATH_MERGE Vivek Goyal
2018-03-30  6:52   ` Amir Goldstein
2018-03-29 19:38 ` [PATCH v13 20/28] ovl: Do not set dentry type ORIGIN for broken hardlinks Vivek Goyal
2018-03-30  9:54   ` Amir Goldstein
2018-04-10 14:00     ` Vivek Goyal
2018-04-10 19:20       ` Amir Goldstein
2018-04-10 19:29         ` Amir Goldstein
2018-04-10 20:59           ` Vivek Goyal
2018-04-10 20:51         ` Vivek Goyal
2018-04-11  8:58           ` Amir Goldstein
2018-04-11 13:31             ` Vivek Goyal [this message]
2018-03-29 19:38 ` [PATCH v13 21/28] ovl: Set redirect on metacopy files upon rename Vivek Goyal
2018-03-30  7:31   ` Amir Goldstein
2018-04-11 15:12     ` Vivek Goyal
2018-04-11 17:01       ` Amir Goldstein
2018-03-29 19:38 ` [PATCH v13 22/28] ovl: Set redirect on upper inode when it is linked Vivek Goyal
2018-03-30  7:04   ` Amir Goldstein
2018-04-11 15:59     ` Vivek Goyal
2018-03-29 19:38 ` [PATCH v13 23/28] ovl: Remove redirect when data of a metacopy file is copied up Vivek Goyal
2018-03-29 19:38 ` [PATCH v13 24/28] ovl: Do not error if REDIRECT XATTR is missing Vivek Goyal
2018-03-30  7:41   ` Amir Goldstein
2018-03-29 19:38 ` [PATCH v13 25/28] ovl: Use out_err insteada of out_nomem Vivek Goyal
2018-03-30  7:35   ` Amir Goldstein
2018-03-29 19:38 ` [PATCH v13 26/28] ovl: Re-check redirect xattr during inode initialization Vivek Goyal
2018-03-30  8:56   ` Amir Goldstein
2018-04-02 19:35     ` Vivek Goyal
2018-04-02 20:25       ` Amir Goldstein
2018-03-29 19:38 ` [PATCH v13 27/28] ovl: Verify a data dentry has been found for metacopy inode Vivek Goyal
2018-03-30 10:53   ` Amir Goldstein
2018-04-02 12:39     ` Vivek Goyal
2018-04-04 12:29     ` Vivek Goyal
2018-04-04 12:51       ` Amir Goldstein
2018-04-04 13:21         ` Vivek Goyal
2018-04-04 15:51           ` Amir Goldstein
2018-04-05 14:37             ` Vivek Goyal
2018-04-05 18:22               ` Vivek Goyal
2018-04-05 19:58                 ` Amir Goldstein
2018-04-05 20:45                   ` Vivek Goyal
2018-04-06  9:46                     ` Amir Goldstein
2018-04-06 15:37                       ` Vivek Goyal
2018-04-06 16:21                         ` Amir Goldstein
2018-04-06 17:32                           ` Vivek Goyal
2018-04-06 20:10                             ` Amir Goldstein
2018-04-09 12:18                               ` Vivek Goyal
2018-03-29 19:38 ` [PATCH v13 28/28] ovl: Enable metadata only feature Vivek Goyal

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180411133107.GA4568@redhat.com \
    --to=vgoyal@redhat.com \
    --cc=amir73il@gmail.com \
    --cc=linux-unionfs@vger.kernel.org \
    --cc=miklos@szeredi.hu \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox