Re: [OpenWrt-Devel] [PATCH] [kernel] upstream fix: mount overlayfs r/o if workdir cannot be created
* Christian Mehlis [21.05.2015 12:49]: > Can you give me a hint to make it work with 3.18? can you please try to apply the appended patch with git am <$file make target/linux/clean make bye, bastian >From f5d917da8665f1a3c79e5beb34acea7daf019ff5 Mon Sep 17 00:00:00 2001 From: Bastian Bittorf Date: Thu, 21 May 2015 13:55:00 +0200 Subject: [PATCH] [kernel] upstream fix: mount overlayfs r/o if workdir cannot be created see: https://www.mail-archive.com/linux-unionfs@vger.kernel.org/msg00246.html runtime tested on ar71xx with kernel 3.18.11 and r45705 this paritially fixes #19564 Signed-off-by: Bastian Bittorf --- ...-overlayfs-fallback-to-readonly-when-full.patch | 109 1 file changed, 109 insertions(+) create mode 100644 target/linux/ar71xx/patches-3.18/910-overlayfs-fallback-to-readonly-when-full.patch diff --git a/target/linux/ar71xx/patches-3.18/910-overlayfs-fallback-to-readonly-when-full.patch b/target/linux/ar71xx/patches-3.18/910-overlayfs-fallback-to-readonly-when-full.patch new file mode 100644 index 000..3433cbc --- /dev/null +++ b/target/linux/ar71xx/patches-3.18/910-overlayfs-fallback-to-readonly-when-full.patch @@ -0,0 +1,109 @@ +[linux-unionfs added to Cc] + +On Tue, May 19, 2015 at 09:51:20AM +0200, Bastian Bittorf wrote: +> Hi Miklos, +> +> sorry for writing directly to you, feel free to forward +> this to the appropriate mailinglist. +> +> we have a problem with mainline overlay filesystem on kernel 3.18: +> https://dev.openwrt.org/ticket/19564 +> +> 2 things are odd: +> when the working filesystem is full, overlays fails with: +> +> overlayfs: failed to create directory /overlay/work/work +> +> what is strange, that we call it with: +> +> mount(overlay, "/mnt", "overlay", MS_NOATIME, lowerdir) +> +> see here: +> http://nbd.name/gitweb.cgi?p=fstools.git;a=blob;f=libfstools/mount.c;h=81176ce399b4cd8e2d347c0008c13dec92407f55;hb=e6004000ff15d7bd32cf5663e8690fc94d7ec747#l125 +> +> do you have an idea whats wrong? +> 1) is it really needed, that we need space for creating dir "/overlay/work"? +> 2) why does overlay need "/overlay/work/work"? + +The work directory is needed for atomic copy-up and similar. It is not actually +necessary to mount a read-only overlay. Post 4.0 it is possible to mount the +overlay without workdir (but even then it won't happen automatically in case the +upper fs is full, so this should be fixed in the latest kernel too). + +Could you please try the following patch? If the workdir can't be created it +will fall back to mounting the overlay read-only. + +Thanks, +Miklos + +--- + fs/overlayfs/copy_up.c |3 +++ + fs/overlayfs/dir.c |9 + + fs/overlayfs/super.c | 12 +--- + 3 files changed, 21 insertions(+), 3 deletions(-) + +--- a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c +@@ -300,6 +300,9 @@ int ovl_copy_up_one(struct dentry *paren + struct cred *override_cred; + char *link = NULL; + ++ if (WARN_ON(!workdir)) ++ return -EROFS; ++ + ovl_path_upper(parent, &parentpath); + upperdir = parentpath.dentry; + +--- a/fs/overlayfs/dir.c b/fs/overlayfs/dir.c +@@ -222,6 +222,9 @@ static struct dentry *ovl_clear_empty(st + struct kstat stat; + int err; + ++ if (WARN_ON(!workdir)) ++ return ERR_PTR(-EROFS); ++ + err = ovl_lock_rename_workdir(workdir, upperdir); + if (err) + goto out; +@@ -322,6 +325,9 @@ static int ovl_create_over_whiteout(stru + struct dentry *newdentry; + int err; + ++ if (WARN_ON(!workdir)) ++ return -EROFS; ++ + err = ovl_lock_rename_workdir(workdir, upperdir); + if (err) + goto out; +@@ -506,6 +512,9 @@ static int ovl_remove_and_whiteout(struc + struct dentry *opaquedir = NULL; + int err; + ++ if (WARN_ON(!workdir)) ++ return -EROFS; ++ + if (is_dir) { + opaquedir = ovl_check_empty_and_clear(dentry); + err = PTR_ERR(opaquedir); +--- a/fs/overlayfs/super.c b/fs/overlayfs/super.c +@@ -740,9 +740,15 @@ static int ovl_fill_super(struct super_b + ufs->workdir = ovl_workdir_create(ufs->upper_mnt, workpath.dentry); + err = PTR_ERR(ufs->workdir); + if (IS_ERR(ufs->workdir)) { +- pr_err("overlayfs: failed to create directory %s/%s\n", +- ufs->config.workdir, OVL_WORKDIR_NAME); +- goto out_put_lower_mnt; ++ if (err == -ENOSPC || err == -EROFS) { ++ pr_warning("overlayfs: failed to work directory (%s), mounting read-only\n", err == ENOSPC ? "ENOSPC" : "EROFS"); ++ sb->s_flags |= MS_RDONLY; ++ ufs->workdir = NULL; ++ } else { ++ pr_err("overlayfs: failed to create directory %s/%s\n", ++ ufs->config.workdir, OVL_WORKDIR_NAME); ++ goto out_put_lower_mnt; ++ } + } + + /* -- 1.7.10.4 ___ openwrt-devel mailing list openwrt-devel@lists.openwrt.org https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel
Re: [OpenWrt-Devel] [PATCH] [kernel] upstream fix: mount overlayfs r/o if workdir cannot be created
* Christian Mehlis [21.05.2015 12:49]: > >+--- a/fs/overlayfs/super.c > > b/fs/overlayfs/super.c > >+@@ -529,7 +529,7 @@ static int ovl_remount(struct super_block *sb, int > >*flags, char *data) > > this function was added with linux 4.0, so your patch for 3.18 does > not apply. > > Can you give me a hint to make it work with 3.18? i will investigate - it applied locally here with 3.18 - will check why... bye, bastian ___ openwrt-devel mailing list openwrt-devel@lists.openwrt.org https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel
Re: [OpenWrt-Devel] [PATCH] [kernel] upstream fix: mount overlayfs r/o if workdir cannot be created
Am 19.05.2015 um 16:17 schrieb Bastian Bittorf: +diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c +index 5f0d199..bf8537c 100644 +--- a/fs/overlayfs/super.c b/fs/overlayfs/super.c +@@ -529,7 +529,7 @@ static int ovl_remount(struct super_block *sb, int *flags, char *data) this function was added with linux 4.0, so your patch for 3.18 does not apply. Can you give me a hint to make it work with 3.18? Best Christian ___ openwrt-devel mailing list openwrt-devel@lists.openwrt.org https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel
[OpenWrt-Devel] [PATCH] [kernel] upstream fix: mount overlayfs r/o if workdir cannot be created
runtime tested on ar71xx with kernel 3.18.11 this paritially fixes #19564 Signed-off-by: Bastian Bittorf --- ...unt-read-only-if-workdir-can-t-be-created.patch | 114 1 file changed, 114 insertions(+) create mode 100644 target/linux/ar71xx/patches-3.18/910-overlayfs-mount-read-only-if-workdir-can-t-be-created.patch diff --git a/target/linux/ar71xx/patches-3.18/910-overlayfs-mount-read-only-if-workdir-can-t-be-created.patch b/target/linux/ar71xx/patches-3.18/910-overlayfs-mount-read-only-if-workdir-can-t-be-created.patch new file mode 100644 index 000..e563398 --- /dev/null +++ b/target/linux/ar71xx/patches-3.18/910-overlayfs-mount-read-only-if-workdir-can-t-be-created.patch @@ -0,0 +1,114 @@ +From cc6f67bcafcb62d1be1603dcd95125a52800 Mon Sep 17 00:00:00 2001 +From: Miklos Szeredi +Date: Tue, 19 May 2015 14:30:12 +0200 +Subject: [PATCH] ovl: mount read-only if workdir can't be created + +OpenWRT folks reported that overlayfs fails to mount if upper fs is full, +because workdir can't be created. Wordir creation can fail for various +other reasons too. + +There's no reason that the mount itself should fail, overlayfs can work +fine without a workdir, as long as the overlay isn't modified. + +So mount it read-only and don't allow remounting read-write. + +Add a couple of WARN_ON()s for the impossible case of workdir being used +despite being read-only. + +Reported-by: Bastian Bittorf +Signed-off-by: Miklos Szeredi +Cc: # v3.18+ +Signed-off-by: Bastian Bittorf + +--- + fs/overlayfs/copy_up.c |3 +++ + fs/overlayfs/dir.c |9 + + fs/overlayfs/super.c | 10 +- + 3 files changed, 17 insertions(+), 5 deletions(-) + +diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c +index 24f6404..84d693d 100644 +--- a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c +@@ -299,6 +299,9 @@ int ovl_copy_up_one(struct dentry *parent, struct dentry *dentry, + struct cred *override_cred; + char *link = NULL; + ++ if (WARN_ON(!workdir)) ++ return -EROFS; ++ + ovl_path_upper(parent, &parentpath); + upperdir = parentpath.dentry; + +diff --git a/fs/overlayfs/dir.c b/fs/overlayfs/dir.c +index 2578a0c..692ceda 100644 +--- a/fs/overlayfs/dir.c b/fs/overlayfs/dir.c +@@ -222,6 +222,9 @@ static struct dentry *ovl_clear_empty(struct dentry *dentry, + struct kstat stat; + int err; + ++ if (WARN_ON(!workdir)) ++ return ERR_PTR(-EROFS); ++ + err = ovl_lock_rename_workdir(workdir, upperdir); + if (err) + goto out; +@@ -322,6 +325,9 @@ static int ovl_create_over_whiteout(struct dentry *dentry, struct inode *inode, + struct dentry *newdentry; + int err; + ++ if (WARN_ON(!workdir)) ++ return -EROFS; ++ + err = ovl_lock_rename_workdir(workdir, upperdir); + if (err) + goto out; +@@ -506,6 +512,9 @@ static int ovl_remove_and_whiteout(struct dentry *dentry, bool is_dir) + struct dentry *opaquedir = NULL; + int err; + ++ if (WARN_ON(!workdir)) ++ return -EROFS; ++ + if (is_dir) { + if (OVL_TYPE_MERGE_OR_LOWER(ovl_path_type(dentry))) { + opaquedir = ovl_check_empty_and_clear(dentry); +diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c +index 5f0d199..bf8537c 100644 +--- a/fs/overlayfs/super.c b/fs/overlayfs/super.c +@@ -529,7 +529,7 @@ static int ovl_remount(struct super_block *sb, int *flags, char *data) + { + struct ovl_fs *ufs = sb->s_fs_info; + +- if (!(*flags & MS_RDONLY) && !ufs->upper_mnt) ++ if (!(*flags & MS_RDONLY) && (!ufs->upper_mnt || !ufs->workdir)) + return -EROFS; + + return 0; +@@ -925,9 +925,10 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent) + ufs->workdir = ovl_workdir_create(ufs->upper_mnt, workpath.dentry); + err = PTR_ERR(ufs->workdir); + if (IS_ERR(ufs->workdir)) { +- pr_err("overlayfs: failed to create directory %s/%s\n", +- ufs->config.workdir, OVL_WORKDIR_NAME); +- goto out_put_upper_mnt; ++ pr_warn("overlayfs: failed to create directory %s/%s (errno: %i); mounting read-only\n", ++ ufs->config.workdir, OVL_WORKDIR_NAME, -err); ++ sb->s_flags |= MS_RDONLY; ++ ufs->workdir = NULL; + } + } + +@@ -997,7 +998,6 @@ out_put_lower_mnt: + kfree(ufs->lower_mnt); + out_put_workdir: + dput(ufs->workdir); +-out_put_upper_mnt: + mntput(ufs->upper_mnt); + out_put_lowerpath: + for (i = 0; i < numlower; i++) +-- +1.7.10.4 + -- 1.7.10.4 ___ openwrt-devel mailing list openwrt-devel@lists.openwrt.org https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-deve