From: John Crispin Date: Sat, 30 May 2015 13:16:23 +0000 (+0000) Subject: kernel: upstream fix: mount overlayfs r/o if workdir cannot be created X-Git-Url: http://git.lede-project.org./?a=commitdiff_plain;h=50da78705a4f5364fce802ed4d3f70d72f7f5138;p=openwrt%2Fstaging%2Fnbd.git kernel: upstream fix: mount overlayfs r/o if workdir cannot be created move the patch to the proper folder Signed-off-by: John Crispin SVN-Revision: 45848 --- 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 deleted file mode 100644 index 53d9e516fc..0000000000 --- a/target/linux/ar71xx/patches-3.18/910-overlayfs-fallback-to-readonly-when-full.patch +++ /dev/null @@ -1,109 +0,0 @@ -[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 create 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; -+ } - } - - /* diff --git a/target/linux/generic/patches-3.18/090-overlayfs-fallback-to-readonly-when-full.patch b/target/linux/generic/patches-3.18/090-overlayfs-fallback-to-readonly-when-full.patch new file mode 100644 index 0000000000..53d9e516fc --- /dev/null +++ b/target/linux/generic/patches-3.18/090-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 create 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; ++ } + } + + /*