summaryrefslogtreecommitdiff
path: root/fs/aufs/cpup.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/aufs/cpup.c')
-rw-r--r--fs/aufs/cpup.c66
1 files changed, 54 insertions, 12 deletions
diff --git a/fs/aufs/cpup.c b/fs/aufs/cpup.c
index a34648874..d34a6d283 100644
--- a/fs/aufs/cpup.c
+++ b/fs/aufs/cpup.c
@@ -512,6 +512,55 @@ out:
return err;
}
+/*
+ * regardless 'acl' option, reset all ACL.
+ * All ACL will be copied up later from the original entry on the lower branch.
+ */
+static int au_reset_acl(struct inode *h_dir, struct path *h_path, umode_t mode)
+{
+ int err;
+ struct dentry *h_dentry;
+ struct inode *h_inode;
+
+ h_dentry = h_path->dentry;
+ h_inode = d_inode(h_dentry);
+ /* forget_all_cached_acls(h_inode)); */
+ err = vfsub_removexattr(h_dentry, XATTR_NAME_POSIX_ACL_ACCESS);
+ AuTraceErr(err);
+ if (!err)
+ err = vfsub_acl_chmod(h_inode, mode);
+
+ AuTraceErr(err);
+ return err;
+}
+
+static int au_do_cpup_dir(struct au_cp_generic *cpg, struct dentry *dst_parent,
+ struct inode *h_dir, struct path *h_path)
+{
+ int err;
+ struct inode *dir, *inode;
+
+ err = vfsub_removexattr(h_path->dentry, XATTR_NAME_POSIX_ACL_DEFAULT);
+ AuTraceErr(err);
+ if (err == -EOPNOTSUPP)
+ err = 0;
+ if (unlikely(err))
+ goto out;
+
+ /*
+ * strange behaviour from the users view,
+ * particularry setattr case
+ */
+ dir = d_inode(dst_parent);
+ if (au_ibstart(dir) == cpg->bdst)
+ au_cpup_attr_nlink(dir, /*force*/1);
+ inode = d_inode(cpg->dentry);
+ au_cpup_attr_nlink(inode, /*force*/1);
+
+out:
+ return err;
+}
+
static noinline_for_stack
int cpup_entry(struct au_cp_generic *cpg, struct dentry *dst_parent,
struct au_cpup_reg_attr *h_src_attr)
@@ -524,7 +573,7 @@ int cpup_entry(struct au_cp_generic *cpg, struct dentry *dst_parent,
struct au_dtime dt;
struct path h_path;
struct dentry *h_src, *h_dst, *h_parent;
- struct inode *h_inode, *h_dir, *dir, *inode;
+ struct inode *h_inode, *h_dir;
struct super_block *sb;
/* bsrc branch can be ro/rw. */
@@ -564,17 +613,8 @@ int cpup_entry(struct au_cp_generic *cpg, struct dentry *dst_parent,
case S_IFDIR:
isdir = 1;
err = vfsub_mkdir(h_dir, &h_path, mode);
- if (!err) {
- /*
- * strange behaviour from the users view,
- * particularry setattr case
- */
- dir = d_inode(dst_parent);
- if (au_ibstart(dir) == cpg->bdst)
- au_cpup_attr_nlink(dir, /*force*/1);
- inode = d_inode(cpg->dentry);
- au_cpup_attr_nlink(inode, /*force*/1);
- }
+ if (!err)
+ err = au_do_cpup_dir(cpg, dst_parent, h_dir, &h_path);
break;
case S_IFLNK:
err = au_do_cpup_symlink(&h_path, h_src, h_dir);
@@ -591,6 +631,8 @@ int cpup_entry(struct au_cp_generic *cpg, struct dentry *dst_parent,
AuIOErr("Unknown inode type 0%o\n", mode);
err = -EIO;
}
+ if (!err)
+ err = au_reset_acl(h_dir, &h_path, mode);
mnt_flags = au_mntflags(sb);
if (!au_opt_test(mnt_flags, UDBA_NONE)