All of lore.kernel.org
 help / color / mirror / Atom feed
From: Amir Goldstein <amir73il@gmail.com>
To: "zhangyi (F)" <yi.zhang@huawei.com>
Cc: Miklos Szeredi <miklos@szeredi.hu>,
	overlayfs <linux-unionfs@vger.kernel.org>,
	Miao Xie <miaoxie@huawei.com>
Subject: Re: [PATCH 2/3] ovl: set origin xattr for merge dir on lookup
Date: Wed, 8 Nov 2017 10:27:03 +0200	[thread overview]
Message-ID: <CAOQ4uxjfE+vO9TDwHsuCD5Zwj9-7ZF9km-PibnTooK61ShKQJw@mail.gmail.com> (raw)
In-Reply-To: <03198975-d870-d49e-f807-01f3d805d001@huawei.com>

On Wed, Nov 8, 2017 at 8:59 AM, zhangyi (F) <yi.zhang@huawei.com> wrote:
> On 2017/11/8 5:38, Amir Goldstein Wrote:
>> For old existing merge dirs whose "origin" xattr was not set at copy up
>> time, we amend the situation on lookup.
>>
>> If no origin fh is stored in upper of a merge dir, store fh of upper most
>> lower dir or 'null' fh if lower does not support file handles. We do this
>> so we can filter out whiteouts in case lower dir is removed offline and
>> then upper dir becomes a pure upper in a future mount.
>>
>> Signed-off-by: Amir Goldstein <amir73il@gmail.com>
>> ---
>>  fs/overlayfs/namei.c     | 61 ++++++++++++++++++++++++++++++++++++++++--------
>>  fs/overlayfs/overlayfs.h |  2 +-
>>  fs/overlayfs/super.c     |  4 ++--
>>  3 files changed, 54 insertions(+), 13 deletions(-)
>>
>> diff --git a/fs/overlayfs/namei.c b/fs/overlayfs/namei.c
>> index 322c6214114f..65606a0a124c 100644
>> --- a/fs/overlayfs/namei.c
>> +++ b/fs/overlayfs/namei.c
>> @@ -87,6 +87,8 @@ static int ovl_acceptable(void *ctx, struct dentry *dentry)
>>       return 1;
>>  }
>>
>> +static struct ovl_fh ovl_null_fh;
>> +
>>  static struct ovl_fh *ovl_get_origin_fh(struct dentry *dentry)
>>  {
>>       int res;
>> @@ -100,7 +102,7 @@ static struct ovl_fh *ovl_get_origin_fh(struct dentry *dentry)
>>       }
>>       /* Zero size value means "copied up but origin unknown" */
>>       if (res == 0)
>> -             return NULL;
>> +             goto null_fh;
>>
>>       fh  = kzalloc(res, GFP_KERNEL);
>>       if (!fh)
>> @@ -118,12 +120,12 @@ static struct ovl_fh *ovl_get_origin_fh(struct dentry *dentry)
>>
>>       /* Treat larger version and unknown flags as "origin unknown" */
>>       if (fh->version > OVL_FH_VERSION || fh->flags & ~OVL_FH_FLAG_ALL)
>> -             goto out;
>> +             goto null_fh;
>>
>>       /* Treat endianness mismatch as "origin unknown" */
>>       if (!(fh->flags & OVL_FH_FLAG_ANY_ENDIAN) &&
>>           (fh->flags & OVL_FH_FLAG_BIG_ENDIAN) != OVL_FH_FLAG_CPU_ENDIAN)
>> -             goto out;
>> +             goto null_fh;
>>
>>       return fh;
>>
>> @@ -131,6 +133,10 @@ static struct ovl_fh *ovl_get_origin_fh(struct dentry *dentry)
>>       kfree(fh);
>>       return NULL;
>>
>> +null_fh:
>> +     kfree(fh);
>> +     return &ovl_null_fh;
>> +
>>  fail:
>>       pr_warn_ratelimited("overlayfs: failed to get origin (%i)\n", res);
>>       goto out;
>> @@ -149,6 +155,9 @@ static struct dentry *ovl_get_origin(struct dentry *dentry,
>>       if (IS_ERR_OR_NULL(fh))
>>               return (struct dentry *)fh;
>>
>> +     if (fh == &ovl_null_fh)
>> +             return NULL;
>> +
>>       /*
>>        * Make sure that the stored uuid matches the uuid of the lower
>>        * layer where file handle will be decoded.
>> @@ -333,6 +342,10 @@ static int ovl_verify_origin_fh(struct dentry *dentry, const struct ovl_fh *fh)
>>       if (IS_ERR(ofh))
>>               return PTR_ERR(ofh);
>>
>> +     /* NULL fh (no lower fh support) and stored 'null' fh is a match */
>> +     if (ofh == &ovl_null_fh)
>> +             return fh ? -ESTALE : 0;
>> +
>
> Is -ESTALE -> -ENODATA better ?
>

If -ENODATA is returned of null_fh then ovl_verify_origin() will set
xattr (back to null_fh)
on every lookup, so we need to be able to distinguish between the
cases of no origin
(-ENODATA) and null_fh.
To be honest I have mixed feelings about the ovl_null_fh trick.
We should probably just pick an arbitrary error code to use internally
to describe null_fh,
like -ENOENT, but a part of me thought that the ovl_null_fh trick is
clearer to read???


> Consider the case: We set 'null' fh in merged upper dir on a 'file handle' not supported
> base filesystem, then we copy or tar all underlying directories to another base filesystem which is
> 'file handle' supported and mount overlayfs again. I think we can update upperdir's fh instead of
> return fail.
>

In what way does it help us to update fh in that case?
We are not following to lower directory by fh anyway.
And we cannot really trust that the restored origin is correct
in the context of my 'verify_dir' patches.
The only use case I see for doing that is container migration - if tar
of container
will deliberately replace concrete origin fh on all dirs with null_fh
before migration,
knowing that origin fh are going to become stale on migration.
And then after migration, iterate all dirs in overlay to restore origin.
But we can leave that to a separate change. This one is mostly concerned
about setting origin for the purpose of whiteout exposure.

> At the same time, consider the opposite side, all directories move from a base filesystem which 'file
> handle' supported to a not supported one. It will trigger NULL pointer crash in ovl_verify_origin_fh()
> because fh is NULL but ofh was existed. Following change good ?
>
> -       if (!ofh)
> +       if (!ofh || !fh)
>                 return -ENODATA;
>

Thanks for pointing that out, but change is not good because it looses the
information about finding a stored null_fh.
If we do want to stick with ovl_null_fh trick, I could pass in &ovl_null_fh
instead of NULL, in case of !ovl_can_decode_fh(origin->d_sb).
This fixes the NULL pointer crash and I can remove this special case,
because fh->len + memcmp will do the right thing:

        /* NULL fh (no lower fh support) and stored 'null' fh is a match */
        if (ofh == fh)
                return fh ? -ESTALE : 0;

Amir.

  reply	other threads:[~2017-11-08  8:27 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-11-07 21:38 [PATCH 0/3] Overlayfs restoring of origin fh Amir Goldstein
2017-11-07 21:38 ` [PATCH 1/3] ovl: remove unneeded arg from ovl_verify_origin() Amir Goldstein
2017-11-07 21:38 ` [PATCH 2/3] ovl: set origin xattr for merge dir on lookup Amir Goldstein
2017-11-08  6:59   ` zhangyi (F)
2017-11-08  8:27     ` Amir Goldstein [this message]
2017-11-08 13:30       ` Amir Goldstein
2017-11-09  4:20         ` zhangyi (F)
2017-11-07 21:39 ` [PATCH 3/3] ovl: recover from whiteouts in impure dir iteration Amir Goldstein
2017-11-09 10:07 ` [PATCH 0/3] Overlayfs restoring of origin fh Miklos Szeredi
2017-11-09 11:33   ` Amir Goldstein
2017-11-09 11:46   ` zhangyi (F)

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=CAOQ4uxjfE+vO9TDwHsuCD5Zwj9-7ZF9km-PibnTooK61ShKQJw@mail.gmail.com \
    --to=amir73il@gmail.com \
    --cc=linux-unionfs@vger.kernel.org \
    --cc=miaoxie@huawei.com \
    --cc=miklos@szeredi.hu \
    --cc=yi.zhang@huawei.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.