From: "Lv Fei(吕飞)" <feilv@asrmicro.com>
To: Amir Goldstein <amir73il@gmail.com>
Cc: "miklos@szeredi.hu" <miklos@szeredi.hu>,
overlayfs <linux-unionfs@vger.kernel.org>
Subject: 答复: overlayfs issue: dir permission lost during overlayfs copy-up
Date: Tue, 16 Jul 2024 02:51:15 +0000 [thread overview]
Message-ID: <47d8bf2202a943e5967454499ee61248@exch01.asrmicro.com> (raw)
In-Reply-To: <CAOQ4uxhJET3v7+7+Cw-wnsRbpPa6ufRDFYaGYWD9RYLgfUxRZA@mail.gmail.com>
> -----邮件原件-----
> 发件人: Amir Goldstein [mailto:amir73il@gmail.com]
> 发送时间: 2024年7月15日 18:08
> 收件人: Lv Fei(吕飞) <feilv@asrmicro.com>
> 抄送: miklos@szeredi.hu; overlayfs <linux-unionfs@vger.kernel.org>
> 主题: Re: overlayfs issue: dir permission lost during overlayfs copy-up
>
> On Mon, Jul 15, 2024 at 9:07 AM Lv Fei(吕飞) <feilv@asrmicro.com> wrote:
> >
> >
> >
> > > -----邮件原件-----
> > > 发件人: Amir Goldstein [mailto:amir73il@gmail.com]
> > > 发送时间: 2024年7月12日 17:41
> > > 收件人: Lv Fei(吕飞) <feilv@asrmicro.com>
> > > 抄送: miklos@szeredi.hu; overlayfs <linux-unionfs@vger.kernel.org>
> > > 主题: Re: overlayfs issue: dir permission lost during overlayfs
> > > copy-up
> > >
> > > On Fri, Jul 12, 2024 at 7:18 AM Lv Fei(吕飞) <feilv@asrmicro.com> wrote:
> > > >
> > > >
> > > >
> > > > Dear Amir,
> > > >
> > > >
> > > >
> > > > Seems issue disappeared with below changes, can you help review below patch?
> > > >
> > > >
> > > >
> > > > Thank you!
> > > >
> > > >
> > > >
> > > > diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c
> > > >
> > > > index 48bca5817f..e543b5563d 100644
> > > >
> > > > --- a/fs/overlayfs/copy_up.c
> > > >
> > > > +++ b/fs/overlayfs/copy_up.c
> > > >
> > > > @@ -851,9 +851,11 @@ static int ovl_copy_up_one(struct dentry
> > > > *parent, struct dentry *dentry,
> > > >
> > > >
> > > >
> > > > int ovl_copy_up_flags(struct dentry *dentry, int flags)
> > > >
> > > > {
> > > >
> > > > + struct super_block *sb = dentry->d_sb;
> > > >
> > > > int err = 0;
> > > >
> > > > const struct cred *old_cred;
> > > >
> > > > bool disconnected = (dentry->d_flags &
> > > > DCACHE_DISCONNECTED);
> > > >
> > > > + unsigned int copies = 0;
> > > >
> > > >
> > > >
> > > > /*
> > > >
> > > > * With NFS export, copy up can get called for a disconnected non-dir.
> > > >
> > > > @@ -887,9 +889,14 @@ int ovl_copy_up_flags(struct dentry *dentry,
> > > > int
> > > > flags)
> > > >
> > > >
> > > >
> > > > dput(parent);
> > > >
> > > > dput(next);
> > > >
> > > > +
> > > >
> > > > + copies++;
> > > >
> > > > }
> > > >
> > > > ovl_revert_creds(dentry->d_sb, old_cred);
> > > >
> > > >
> > > >
> > > > + if (copies && d_is_dir(dentry) && sb->s_op->sync_fs)
> > > >
> > > > + sb->s_op->sync_fs(sb, 1);
> > > >
> > > > +
> > > >
> > >
> > > I am not sure if it is acceptable to add sync to parent dir copy up although this should be > relatively rare so maybe its fine??
> > > but if you do add sync you should be using fsync on the copied up parent directory - not ->sync_fs.
> > >
> > > Anyway, this check is wrong.
> > > You should not be checking for d_is_dir(dentry), you should be
> > > checking if any *parents* were copied > up,
> > >
> > > See more about this below...
> > >
> > > >
> > > >
> > > >
> > > > 发件人: Lv Fei(吕飞)
> > > > 发送时间: 2024年7月12日 11:35
> > > > 收件人: 'amir73il@gmail.com' <amir73il@gmail.com>
> > > > 主题: overlayfs issue: dir permission lost during overlayfs copy-up
> > > >
> > > >
> > > >
> > > >
> > > >
> > > > Dear Amir,
> > > >
> > > >
> > > >
> > > > Sorry to bother you.
> > > >
> > > >
> > > >
> > > > Recently, we had a problem with overlayfs dir copy-up flow.
> > > >
> > > >
> > > >
> > > > Description:
> > > >
> > > > If a dir eyelyn/ exist in low layer, not exist in upper layer, after creating a new file(e.g. > eyelyn/ eyelyn.log) in this dir from overlayfs, permission of eyelyn/ may be abnormal after > power-cut.
> > > >
> > > > If add a sync after creating a new file, permission of eyelyn/ is always correct.
> > > >
> > > >
> > > >
> > > > Kernel Version:
> > > >
> > > > Linux OpenWrt 5.4.276+ #25 PREEMPT Fri Jul 12 02:21:17 UTC 2024
> > > > armv7l GNU/Linux
> > > >
> > > >
> > > >
> > > > Test Step:
> > > >
> > > > 1. mount –t squashfs /dev/mtdblock19 /system/etc
> > > >
> > > > root@OpenWrt:/system/etc# ls -l
> > > >
> > > > drwxr-xr-x 2 root root 3 Jul 11 2024 eyelyn/
> > > >
> > > >
> > > >
> > > > 2. mount –t ubifs ubi0:etc /overlay/etc
> > > >
> > > > root@OpenWrt:/overlay/etc# ls -l
> > > >
> > > > drwxr-xr-x 8 root root 1360 Jan 1 08:01 root/
> > > >
> > > > drwxr-xr-x 3 root root 224 Jan 1 08:00 work/
> > > >
> > > > root@OpenWrt:/overlay/etc# ls -al root/
> > > >
> > > > drwxr-xr-x 8 root root 1360 Jan 1 08:01 ./
> > > >
> > > > drwxr-xr-x 4 root root 288 Jan 1 08:00 ../
> > > >
> > > >
> > > >
> > > > 3. mount –t overlay /system/etc -o
> > > > noatime,lowerdir=/system/etc,upperdir=/overlay/etc/root,workdir=/o
> > > > verl
> > > > ay/etc/work
> > > >
> > > >
> > > >
> > > > 4. echo system > /system/etc /eyelyn/eyelyn.log
> > > >
> > > >
> > > >
> > > > 5. power cut
> > > >
> > > >
> > > >
> > > > 6. after next power on, sometimes dir eyelyn/ has wrong permission
> > > > (d---------)
> > > >
> > > >
> > > >
> > > > mount –t ubifs ubi0:etc /overlay/etc
> > > >
> > > > root@OpenWrt:/overlay/etc# ls -l root/
> > > >
> > > > d--------- 1 root root 232 Jan 1 08:00 eyelyn
> > > >
> > > > root@OpenWrt:/overlay/etc# ls –l system/etc/eyelyn/eyelyn.log
> > > >
> > > > -rw-r--r-- 1 root root 0 Jan 1 08:00 /system/etc/eyelyn/eyelyn.log
> > > >
> > > >
> > > >
> > > > if we add sync to step 4, that is “echo system > /system/etc /eyelyn/eyelyn.log && sync”, then > everything is right.
> > > >
> > > >
> > > >
> > > > Do you have any suggestions?
> > > >
> > > >
> > >
> > >
> > > Overlayfs creates the upper dir in work directory, sets its metadata and only then moves it into > place, so the above is an "issue" with ubifs.
> > >
> > > The thing about this "issue" is that the behavior that after move the old permissions cannot be > observed is not defined by POSIX, but it is the facto the behavior of most of the modern filesystems > (xfs, ext4 and most probably btrfs).
> > >
> > > If you want to add a feature that adds fsync to copied up parent directories for filesystems like > ubifs that are not "strictly ordered metadata" then I think this needs to be an opt-in feature.
> > >
> > > I must admit that this requirement from the upper fs is not documented and cannot be automatically > tested by overlayfs (fs do not advertise "strictly ordered metadata" property). It just happens to > be true for most of the common fs used as upper fs.
> > >
> > > I wish we had called the mount option "volatile" "sync=none" and then we could have added > "sync=strict" for this and "sync=data" as the default.
> > > We can still do that and have "volatile" be an alias for "sync=none".
> > >
> > > Thanks,
> > > Amir.
> >
> > Very glad to receive your reply, Thank you for explanation.
> > As you suggested, I try to add mount option "sync=strict", change to use fsync for parent dir. Please help have a look.
> >
>
> Ok, but if you want to submit this change please follow https://www.kernel.org/doc/html/latest/process/submitting-patches.html
Thanks, I will learn the submit flow and have a try.
> See comments below
>
> > diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c index
> > 48bca5817f..4258b8da8d 100644
> > --- a/fs/overlayfs/copy_up.c
> > +++ b/fs/overlayfs/copy_up.c
> > @@ -851,6 +851,7 @@ static int ovl_copy_up_one(struct dentry *parent,
> > struct dentry *dentry,
> >
> > int ovl_copy_up_flags(struct dentry *dentry, int flags) {
> > + struct ovl_fs *ofs = dentry->d_sb->s_fs_info;
>
> ofs = OVL_FS(dentry->d_sb);
>
> > int err = 0;
> > const struct cred *old_cred;
> > bool disconnected = (dentry->d_flags & DCACHE_DISCONNECTED);
> > @@ -884,6 +885,24 @@ int ovl_copy_up_flags(struct dentry *dentry, int flags)
> > }
> >
> > err = ovl_copy_up_one(parent, next, flags);
> > + if (ofs->config.volatile_sync && d_is_dir(next)) {
> > + struct path upperpath;
> > + struct file *new_file;
> > +
> > + ovl_path_upper(next, &upperpath);
> > +
> > + new_file = ovl_path_open(&upperpath,
> > + O_LARGEFILE | O_WRONLY);
> > + if (!IS_ERR(new_file)) {
> > + if (ofs->config.volatile_sync ==
> > + OVL_VOLATILE_SYNC_DATA)
> > + vfs_fsync(new_file, 1);
>
> Not needed already done in ovl_copy_up_file()
>
> > + else
> > + vfs_fsync(new_file, 0);
> > +
> > + fput(new_file);
> > + }
> > + }
>
> Not the right place for fsync.
> This should be at the end of ovl_copy_up_metadata() similar to fsync at the end of ovl_copy_up_file().
> The check for sync mode should be abstracted by the helper like ovl_should_sync(), maybe ovl_should_sync_strict()
>
> >
> > dput(parent);
> > dput(next);
> > diff --git a/fs/overlayfs/ovl_entry.h b/fs/overlayfs/ovl_entry.h index
> > 2daba08f78..873d997fb9 100644
> > --- a/fs/overlayfs/ovl_entry.h
> > +++ b/fs/overlayfs/ovl_entry.h
> > @@ -5,6 +5,12 @@
> > * Copyright (C) 2016 Red Hat, Inc.
> > */
> >
> > +enum {
> > + OVL_VOLATILE_SYNC_NONE,
> > + OVL_VOLATILE_SYNC_DATA,
> > + OVL_VOLATILE_SYNC_STRICT,
> > +};
> > +
> > struct ovl_config {
> > char *lowerdir;
> > char *upperdir;
> > @@ -18,6 +24,7 @@ struct ovl_config {
> > int xino;
> > bool metacopy;
> > bool override_creds;
> > + int volatile_sync;
>
> This word volatile_ is unneeded and wrong. "volatile" means "no sync"
> Please *replace the config ovl_volatile with sync_mode, don't keep both and grep for all access to ovl_volatile to replace them with adjusted sync_mode code.
>
> > };
> >
> > struct ovl_sb {
> > diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c index
> > 093af1dcbd..68dee1850b 100644
> > --- a/fs/overlayfs/super.c
> > +++ b/fs/overlayfs/super.c
> > @@ -416,6 +416,9 @@ enum {
> > OPT_METACOPY_OFF,
> > OPT_OVERRIDE_CREDS_ON,
> > OPT_OVERRIDE_CREDS_OFF,
> > + OPT_VOLATILE_SYNC_NONE,
> > + OPT_VOLATILE_SYNC_DATA,
> > + OPT_VOLATILE_SYNC_STRICT,
>
> This word _VOLATILE_ is unneeded and wrong. "volatile" means "no sync"
> Which version are you basing your patch on?
> You should be developing on top of current upstream kernel, where this parsing code is at params.c.
>
> You should follow the example of ovl_parameter_verity() which accepts enum values {off, on, require} which is quite the same as what you want for sync mode.
Sorry, kernel version I am working on is 5.4.276. Seems there is much difference.
>
> > OPT_ERR,
> > };
> >
> > @@ -436,6 +439,9 @@ static const match_table_t ovl_tokens = {
> > {OPT_METACOPY_OFF, "metacopy=off"},
> > {OPT_OVERRIDE_CREDS_ON, "override_creds=on"},
> > {OPT_OVERRIDE_CREDS_OFF, "override_creds=off"},
> > + {OPT_VOLATILE_SYNC_NONE, "sync=none"},
> > + {OPT_VOLATILE_SYNC_DATA, "sync=data"},
> > + {OPT_VOLATILE_SYNC_STRICT, "sync=strict"},
>
> Note that you need to add the new sync option AND keep the legacy "volatile" mount option.
>
> > {OPT_ERR, NULL}
> > };
> >
> > @@ -495,6 +501,7 @@ static int ovl_parse_opt(char *opt, struct ovl_config *config)
> > if (!config->redirect_mode)
> > return -ENOMEM;
> > config->override_creds = ovl_override_creds_def;
> > + config->volatile_sync = OVL_VOLATILE_SYNC_ DATA;
> >
> > while ((p = ovl_next_opt(&opt)) != NULL) {
> > int token;
> > @@ -583,6 +590,18 @@ static int ovl_parse_opt(char *opt, struct ovl_config *config)
> > config->override_creds = false;
> > break;
> >
> > + case OPT_VOLATILE_SYNC_NONE:
> > + config->volatile_sync = OVL_VOLATILE_SYNC_NONE;
> > + break;
> > +
> > + case OPT_VOLATILE_SYNC_DATA:
> > + config->volatile_sync = OVL_VOLATILE_SYNC_DATA;
> > + break;
> > +
> > + case OPT_VOLATILE_SYNC_STRICT:
> > + config->volatile_sync = OVL_VOLATILE_SYNC_STRICT;
> > + break;
> > +
>
>
> And effectively the two mount options to do the same, i.e.:
>
> case Opt_sync:
> config->sync_mode = result.uint_32;
> break;
> case Opt_volatile:
> config->sync_mode = OVL_SYNC_OFF;
> break;
>
> > default:
> > pr_err("overlayfs: unrecognized mount option \"%s\" or missing value\n", p);
> > return -EINVAL;
> >
>
> Also need to display the mode in ovl_show_options().
>
> Thanks,
> Amir,
After reading latest code, found the mount option "volatile", now I understand what you mean
by "sync=none"/"sync=data"/"sync=strict", "sync=data" is default mount option.
what I need to do is extending the meaning of config->ovl_volatile(used to control data sync), using config->sync_mode instead.
And for version 5.4.276, I need to add fsync at the end of ovl_copy_up_inode (correspond to latest function ovl_copy_up_metadata), right?
Thank you for your patience!
Fei
next prev parent reply other threads:[~2024-07-16 2:51 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <a2391c78f3974c5d92aa53574bde4eca@exch01.asrmicro.com>
2024-07-12 9:40 ` overlayfs issue: dir permission lost during overlayfs copy-up Amir Goldstein
2024-07-15 6:06 ` 答复: " Lv Fei(吕飞)
2024-07-15 10:07 ` Amir Goldstein
2024-07-16 2:51 ` Lv Fei(吕飞) [this message]
2024-07-16 8:19 ` Amir Goldstein
2024-07-17 12:41 ` 答复: " Lv Fei(吕飞)
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=47d8bf2202a943e5967454499ee61248@exch01.asrmicro.com \
--to=feilv@asrmicro.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