Skip to contentSkip to conversation

linux / overlay / OpenWrt / problems with full working dir

DISCUSSION Miklos Szeredi 3 participants 4 messages May 19, 2015 1 message not in the archive Overlay filesystem

lore
Share & tools
lore

A message that is not in the archive (sent off-list or not yet received): [email protected]

Miklos Szeredi

author maintainer
#1 lore raw

[linux-unionfs added to Cc]

Quoted 15 lines · Bastian Bittorf

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:

Quoted 8 lines

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(-)
fs/overlayfs/copy_up.c +3 -0
@@ -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;
 
fs/overlayfs/dir.c +9 -0
@@ -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);
fs/overlayfs/super.c +9 -3
@@ -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;
+		}
 	}
 
 	/*
#2 lore raw

Hi Miklos,

Quoted 10 lines · Miklos Szeredi
---
 fs/overlayfs/copy_up.c |    3 +++
 fs/overlayfs/dir.c     |    9 +++++++++
 fs/overlayfs/super.c   |   12 +++++++++---
 3 files changed, 21 insertions(+), 3 deletions(-)

fs/overlayfs/copy_up.c int ovl_copy_up_one(struct dentry *paren · line 305

Quoted 6 lines
fs/overlayfs/copy_up.c +3 -0
@@ -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;
+

When will this condition occur?

Quoted 38 lines
fs/overlayfs/copy_up.c +0 -0
 	ovl_path_upper(parent, &parentpath);
 	upperdir = parentpath.dentry;
 
fs/overlayfs/dir.c +9 -0
@@ -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);

fs/overlayfs/super.c static int ovl_fill_super(struct super_b · line 743

Quoted 7 lines
fs/overlayfs/super.c +1 -3
@@ -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) {

Since upper fs should not be R/O after commit 71cbad7e694ee81, could the return value here be -EROFS?

Quoted 18 lines
fs/overlayfs/super.c +8 -1
+			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;
+		}
 	}
 
 	/*
--

To unsubscribe from this list: send the line "unsubscribe linux-unionfs" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

.

#3 lore raw
In reply to Miklos Szeredi
Quoted 7 lines · Miklos Szeredi

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.

Thank you!
I applied it on top of 3.18 and it works.
Here some output with full 'work-dir'/jffs2:

...

[    8.800000] jffs2: notice: (323) jffs2_build_xattr_subsystem: complete building xattr subsystem, 2 of xdatum (2 unc hecked, 0 orphan) and 2 of xref (0 dead, 0 orphan) found.
[    8.820000] mount_root: switching to jffs2 overlay
[    9.030000] overlayfs: failed to work directory (EROFS), mounting read-only

...

root@box:~ df -h
Filesystem Size Used Available Use% Mounted on
rootfs 576.0K 532.0K 44.0K 92% /
/dev/root 2.3M 2.3M 0 100% /rom

tmpfs                    14.0M      1.2M     12.8M   8% /tmp
/dev/mtdblock3          576.0K    532.0K     44.0K  92% /overlay
overlayfs:/overlay      576.0K    532.0K     44.0K  92% /

tmpfs 512.0K 0 512.0K 0% /dev

root@box:~ mount
rootfs on / type rootfs (rw)
/dev/root on /rom type squashfs (ro,relatime)
proc on /proc type proc (rw,noatime)
sysfs on /sys type sysfs (rw,noatime)
tmpfs on /tmp type tmpfs (rw,nosuid,nodev,noatime)
/dev/mtdblock3 on /overlay type jffs2 (rw,noatime)
overlayfs:/overlay on / type overlay (ro,noatime,lowerdir=/,upperdir=/overlay/upper,workdir=/overlay/work) tmpfs on /dev type tmpfs (rw,relatime,size=512k,mode=755)
devpts on /dev/pts type devpts (rw,relatime,mode=600)
debugfs on /sys/kernel/debug type debugfs (rw,noatime)

please apply it on your git, and we will cherrypick/backport it for OpenWrt. (and close ticket https://dev.openwrt.org/ticket/19564)

bye, bastian

author maintainer
#4 lore raw
Quoted 2 lines · Bastian Bittorf

please apply it on your git, and we will cherrypick/backport it for OpenWrt. (and close ticket https://dev.openwrt.org/ticket/19564)

Pushed to:

git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/vfs.git
overlayfs-current

Thanks,
Miklos