diff options
Diffstat (limited to 'fs/aufs/cpup.c')
-rw-r--r-- | fs/aufs/cpup.c | 66 |
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) |