All of lore.kernel.org
 help / color / mirror / Atom feed
From: Amir Goldstein <amir73il@gmail.com>
To: Vivek Goyal <vgoyal@redhat.com>
Cc: overlayfs <linux-unionfs@vger.kernel.org>,
	Miklos Szeredi <miklos@szeredi.hu>,
	"Eric W. Biederman" <ebiederm@xmission.com>
Subject: Re: [PATCH 7/9] ovl: Introduce read/write barriers around metacopy flag update
Date: Tue, 10 Oct 2017 20:12:00 +0300	[thread overview]
Message-ID: <CAOQ4uxisKjK+kH_kEMb7JPUHn+Gaoa7YNvQsS9W=REUPuywy+A@mail.gmail.com> (raw)
In-Reply-To: <1507649544-4539-8-git-send-email-vgoyal@redhat.com>

On Tue, Oct 10, 2017 at 6:32 PM, Vivek Goyal <vgoyal@redhat.com> wrote:
> We can access and check metacopy flag outside ovl_inode->lock. IOW, say
> a file was meta copied up in the past and it has metacopy flag set. Now
> a data copy up operation in progress. Say another thread reads state of
> this flag and if flag clearing is visible before file has been fully
> copied up, that can cause problems.
>
>         CPU1                            CPU2
> ovl_copy_up_flags()                     acquire(oi->lock)
>  ovl_dentry_needs_data_copy_up()          ovl_copy_up_data_inode()
>    ovl_test_metacopy_flag()                 ovl_copy_up_data()
>                                             ovl_clear_metacopy_flag()
>                                         release(oi->lock)
>
> Say CPU2 is copying up data and in the end clears metacopy flag. But if
> CPU1 perceives clearing of metacopy before actual data copy up operation
> being finished, that can become a problem. We want this clearing of flag
> to be visible only if all previous write operations have finished.
>
> Hence this patch introduces smp_wmb() on metacopy flag set/clear operation
> and smp_rmb() on metacopy flag test operation.
>
> May be some other lock or barrier is already covering it. But I am not sure
> what that is and is it obvious enough that we will not break it in future.
>
> So hence trying to be safe here and introducing barriers explicitly for
> metacopy bit.

Please revisit your changes after addressing my comment on patch 5.
IIUC the flow you describe above should be addressed by testing
metacopy flag again under ovl inode lock.

The only subtle part imo is making metacopy flag visible
Before making upper dentry visible.
Clearing metacopy flag should not be a problem imo,
As it comes after fsync, but didn't look closely.

>
> Signed-off-by: Vivek Goyal <vgoyal@redhat.com>
> ---
>  fs/overlayfs/copy_up.c   |  9 +++------
>  fs/overlayfs/overlayfs.h |  3 +++
>  fs/overlayfs/util.c      | 23 ++++++++++++++++++++++-
>  3 files changed, 28 insertions(+), 7 deletions(-)
>
> diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c
> index 682852a78163..b10269b80803 100644
> --- a/fs/overlayfs/copy_up.c
> +++ b/fs/overlayfs/copy_up.c
> @@ -465,8 +465,7 @@ static int ovl_copy_up_data_inode(struct ovl_copy_up_ctx *c)
>         if (err)
>                 return err;
>
> -       smp_wmb();
> -       ovl_clear_flag(OVL_METACOPY, d_inode(c->dentry));
> +       ovl_clear_metacopy_flag(d_inode(c->dentry));
>         return err;
>  }
>
> @@ -564,10 +563,8 @@ static int ovl_copy_up_locked(struct ovl_copy_up_ctx *c)
>                 goto out_cleanup;
>
>         ovl_inode_update(d_inode(c->dentry), newdentry);
> -       if (c->metadata_only) {
> -               smp_wmb();
> -               ovl_set_flag(OVL_METACOPY, d_inode(c->dentry));
> -       }
> +       if (c->metadata_only)
> +               ovl_set_metacopy_flag(d_inode(c->dentry));
>  out:
>         dput(temp);
>         return err;
> diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h
> index 773f5ad75729..df3f513de3cc 100644
> --- a/fs/overlayfs/overlayfs.h
> +++ b/fs/overlayfs/overlayfs.h
> @@ -234,6 +234,9 @@ int ovl_set_impure(struct dentry *dentry, struct dentry *upperdentry);
>  void ovl_set_flag(unsigned long flag, struct inode *inode);
>  void ovl_clear_flag(unsigned long flag, struct inode *inode);
>  bool ovl_test_flag(unsigned long flag, struct inode *inode);
> +void ovl_set_metacopy_flag(struct inode *inode);
> +void ovl_clear_metacopy_flag(struct inode *inode);
> +bool ovl_test_metacopy_flag(struct inode *inode);
>  bool ovl_inuse_trylock(struct dentry *dentry);
>  void ovl_inuse_unlock(struct dentry *dentry);
>  int ovl_nlink_start(struct dentry *dentry, bool *locked);
> diff --git a/fs/overlayfs/util.c b/fs/overlayfs/util.c
> index 91c542d1a39d..000f78b92a72 100644
> --- a/fs/overlayfs/util.c
> +++ b/fs/overlayfs/util.c
> @@ -227,6 +227,27 @@ void ovl_dentry_set_upper_alias(struct dentry *dentry)
>         oe->has_upper = true;
>  }
>
> +bool ovl_test_metacopy_flag(struct inode *inode)
> +{
> +       /* Pairs with smp_wmb() in ovl_set_metacopy_flag() */
> +       smp_rmb();
> +       return ovl_test_flag(OVL_METACOPY, inode);
> +}
> +
> +void ovl_set_metacopy_flag(struct inode *inode)
> +{
> +       /* Pairs with smp_rmb() in ovl_test_metacopy_flag() */
> +       smp_wmb();
> +       ovl_set_flag(OVL_METACOPY, inode);
> +}
> +
> +void ovl_clear_metacopy_flag(struct inode *inode)
> +{
> +       /* Pairs with smp_rmb() in ovl_test_metacopy_flag() */
> +       smp_wmb();
> +       ovl_clear_flag(OVL_METACOPY, inode);
> +}
> +
>  bool ovl_dentry_needs_data_copy_up(struct dentry *dentry, int flags) {
>         if (!S_ISREG(d_inode(dentry)->i_mode))
>                 return false;
> @@ -237,7 +258,7 @@ bool ovl_dentry_needs_data_copy_up(struct dentry *dentry, int flags) {
>         if (!(OPEN_FMODE(flags) & FMODE_WRITE))
>                 return false;
>
> -       if (!ovl_test_flag(OVL_METACOPY, d_inode(dentry)))
> +       if (!ovl_test_metacopy_flag(d_inode(dentry)))
>                 return false;
>
>         return true;
> --
> 2.13.5
>

  reply	other threads:[~2017-10-10 17:12 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-10-10 15:32 [RFC PATCH 0/9][V3] overlayfs: Delayed copy up of data Vivek Goyal
2017-10-10 15:32 ` [PATCH 1/9] ovl: ovl_check_setxattr() get rid of redundant -EOPNOTSUPP check Vivek Goyal
2017-10-10 15:32 ` [PATCH 2/9] ovl: During copy up, first copy up metadata and then data Vivek Goyal
2017-10-10 15:32 ` [PATCH 3/9] ovl: Provide a mount option metacopy=on/off for metadata copyup Vivek Goyal
2017-10-11  1:36   ` Amir Goldstein
2017-10-11 13:57     ` Vivek Goyal
2017-10-11 16:29       ` Amir Goldstein
2017-10-11 16:53         ` Vivek Goyal
2017-10-11 17:36           ` Amir Goldstein
2017-10-11 18:34             ` Vivek Goyal
2017-10-11 20:29               ` Amir Goldstein
2017-10-12 13:23                 ` Vivek Goyal
2017-10-12 13:39                   ` Amir Goldstein
2017-10-10 15:32 ` [PATCH 4/9] ovl: Copy up only metadata during copy up where it makes sense Vivek Goyal
2017-10-10 15:32 ` [PATCH 5/9] ovl: Set xattr OVL_XATTR_METACOPY on upper file Vivek Goyal
2017-10-10 17:03   ` Amir Goldstein
2017-10-11 20:16     ` Vivek Goyal
2017-10-11 20:44       ` Amir Goldstein
2017-10-10 15:32 ` [PATCH 6/9] ovl: Fix ovl_getattr() to get number of blocks from lower Vivek Goyal
2017-10-10 15:32 ` [PATCH 7/9] ovl: Introduce read/write barriers around metacopy flag update Vivek Goyal
2017-10-10 17:12   ` Amir Goldstein [this message]
2017-10-11 20:27     ` Vivek Goyal
2017-10-11 21:08       ` Amir Goldstein
2017-10-13 18:27         ` Vivek Goyal
2017-10-14  6:05           ` Amir Goldstein
2017-10-14  7:00             ` Amir Goldstein
2017-10-16 13:24               ` Vivek Goyal
2017-10-16 13:24             ` Vivek Goyal
2017-10-16 13:31               ` Amir Goldstein
2017-10-10 15:32 ` [PATCH 8/9] ovl: Set OVL_METACOPY flag during ovl_lookup() Vivek Goyal
2017-10-10 15:32 ` [PATCH 9/9] ovl: Return lower dentry if only metadata copy up took place 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='CAOQ4uxisKjK+kH_kEMb7JPUHn+Gaoa7YNvQsS9W=REUPuywy+A@mail.gmail.com' \
    --to=amir73il@gmail.com \
    --cc=ebiederm@xmission.com \
    --cc=linux-unionfs@vger.kernel.org \
    --cc=miklos@szeredi.hu \
    --cc=vgoyal@redhat.com \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.