mirror of https://github.com/hak5/openwrt.git
110 lines
3.2 KiB
Diff
110 lines
3.2 KiB
Diff
|
[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;
|
||
|
+ }
|
||
|
}
|
||
|
|
||
|
/*
|