[PATCH] ovl: fix copy up opaque directory

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



When a copy up of a directory occurs which has the opaque xattr set, the
xattr remains in the upper directory. The immediate behavior with overlayfs
is that the upper directory is not treated as opaque, however after a
remount the opaque flag is used and upper directory is treated as opaque.
This causes files created in the lower layer to be hidden when using
multiple lower directories. This change fixes the behavior to remove the
opaque flag when an opaque directory is copied up.

Script to reproduce and verify
#!/bin/sh
cd $(mktemp -d)
mkdir -p lower1/lib
touch lower1/lib/hidden
mkdir -p lower2/lib
touch lower2/lib/not-hidden
setfattr -n trusted.overlay.opaque -v y lower2/lib
mkdir upper
mkdir work
mkdir merged
mount -t overlay overlay -o lowerdir=lower2:lower1,upperdir=upper,workdir=work merged
ls merged/lib # shows only "not-hidden"
touch merged/lib/newfile
ls merged/lib # shows both "not-hidden" and "newfile"
getfattr -n trusted.overlay.opaque upper/lib # should not be set
umount merged
mount -t overlay overlay -o lowerdir=lower2:lower1,upperdir=upper,workdir=work merged
ls merged/lib # should show not-hidden" and "newfile"
umount merged

Signed-off-by: Derek McGowan <dmcg@xxxxxxxxx>
Link: https://bugzilla.kernel.org/show_bug.cgi?id=151291
---
 fs/overlayfs/copy_up.c   | 3 +++
 fs/overlayfs/dir.c       | 2 +-
 fs/overlayfs/overlayfs.h | 4 ++++
 fs/overlayfs/super.c     | 2 +-
 4 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c
index cc514da..1baab7b 100644
--- a/fs/overlayfs/copy_up.c
+++ b/fs/overlayfs/copy_up.c
@@ -281,6 +281,9 @@ static int ovl_copy_up_locked(struct dentry *workdir, struct dentry *upperdir,
 	if (err)
 		goto out_cleanup;
 
+	if (ovl_is_opaquedir(newdentry))
+		ovl_remove_opaque(newdentry);
+
 	inode_lock(newdentry->d_inode);
 	err = ovl_set_attr(newdentry, stat);
 	inode_unlock(newdentry->d_inode);
diff --git a/fs/overlayfs/dir.c b/fs/overlayfs/dir.c
index b3fc0a3..02b20ad 100644
--- a/fs/overlayfs/dir.c
+++ b/fs/overlayfs/dir.c
@@ -121,7 +121,7 @@ static int ovl_set_opaque(struct dentry *upperdentry)
 	return ovl_do_setxattr(upperdentry, OVL_XATTR_OPAQUE, "y", 1, 0);
 }
 
-static void ovl_remove_opaque(struct dentry *upperdentry)
+void ovl_remove_opaque(struct dentry *upperdentry)
 {
 	int err;
 
diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h
index 6a7090f..6e53acb 100644
--- a/fs/overlayfs/overlayfs.h
+++ b/fs/overlayfs/overlayfs.h
@@ -194,6 +194,7 @@ int ovl_create_real(struct inode *dir, struct dentry *newdentry,
 		    struct kstat *stat, const char *link,
 		    struct dentry *hardlink, bool debug);
 void ovl_cleanup(struct inode *dir, struct dentry *dentry);
+void ovl_remove_opaque(struct dentry *upperdentry);
 
 /* copy_up.c */
 int ovl_copy_up(struct dentry *dentry);
@@ -201,3 +202,6 @@ int ovl_copy_up_one(struct dentry *parent, struct dentry *dentry,
 		    struct path *lowerpath, struct kstat *stat);
 int ovl_copy_xattr(struct dentry *old, struct dentry *new);
 int ovl_set_attr(struct dentry *upper, struct kstat *stat);
+
+/* super.c */
+bool ovl_is_opaquedir(struct dentry *dentry);
diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c
index 791235e..1f3d907 100644
--- a/fs/overlayfs/super.c
+++ b/fs/overlayfs/super.c
@@ -265,7 +265,7 @@ bool ovl_is_whiteout(struct dentry *dentry)
 	return inode && IS_WHITEOUT(inode);
 }
 
-static bool ovl_is_opaquedir(struct dentry *dentry)
+bool ovl_is_opaquedir(struct dentry *dentry)
 {
 	int res;
 	char val;
-- 
2.5.5

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



[Index of Archives]     [Linux Filesystems Devel]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux