diff --git a/fs/overlayfs/dir.c b/fs/overlayfs/dir.c index d9cdb4747f68..aa6320557196 100644 --- a/fs/overlayfs/dir.c +++ b/fs/overlayfs/dir.c @@ -921,4 +921,5 @@ const struct inode_operations ovl_dir_inode_operations = { .getxattr = ovl_getxattr, .listxattr = ovl_listxattr, .removexattr = ovl_removexattr, + .get_acl = ovl_get_acl, }; diff --git a/fs/overlayfs/inode.c b/fs/overlayfs/inode.c index 32ae8b49a72c..a574108f52a8 100644 --- a/fs/overlayfs/inode.c +++ b/fs/overlayfs/inode.c @@ -310,6 +310,22 @@ int ovl_removexattr(struct dentry *dentry, const char *name) return err; } +struct posix_acl *ovl_get_acl(struct inode *inode, int type) +{ + struct inode *realinode = ovl_inode_real(inode); + + if (!realinode) + return ERR_PTR(-ENOENT); + + if (!IS_POSIXACL(realinode)) + return NULL; + + if (!realinode->i_op->get_acl) + return NULL; + + return realinode->i_op->get_acl(realinode, type); +} + static bool ovl_open_need_copy_up(int flags, enum ovl_path_type type, struct dentry *realdentry) { @@ -354,6 +370,7 @@ static const struct inode_operations ovl_file_inode_operations = { .getxattr = ovl_getxattr, .listxattr = ovl_listxattr, .removexattr = ovl_removexattr, + .get_acl = ovl_get_acl, }; static const struct inode_operations ovl_symlink_inode_operations = { diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h index 0d3f2ad45708..75128c70aa6a 100644 --- a/fs/overlayfs/overlayfs.h +++ b/fs/overlayfs/overlayfs.h @@ -142,6 +142,7 @@ struct dentry *ovl_dentry_upper(struct dentry *dentry); struct dentry *ovl_dentry_lower(struct dentry *dentry); struct dentry *ovl_dentry_real(struct dentry *dentry); struct dentry *ovl_entry_real(struct ovl_entry *oe, bool *is_upper); +struct inode *ovl_inode_real(struct inode *inode); struct vfsmount *ovl_entry_mnt_real(struct ovl_entry *oe, struct inode *inode, bool is_upper); struct ovl_dir_cache *ovl_dir_cache(struct dentry *dentry); @@ -179,6 +180,7 @@ ssize_t ovl_getxattr(struct dentry *dentry, struct inode *inode, const char *name, void *value, size_t size); ssize_t ovl_listxattr(struct dentry *dentry, char *list, size_t size); int ovl_removexattr(struct dentry *dentry, const char *name); +struct posix_acl *ovl_get_acl(struct inode *inode, int type); int ovl_open_maybe_copy_up(struct dentry *dentry, unsigned int file_flags); struct inode *ovl_new_inode(struct super_block *sb, umode_t mode, diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c index 5341ca57677c..893d6e0ea1c5 100644 --- a/fs/overlayfs/super.c +++ b/fs/overlayfs/super.c @@ -159,6 +159,13 @@ struct dentry *ovl_entry_real(struct ovl_entry *oe, bool *is_upper) return realdentry; } +struct inode *ovl_inode_real(struct inode *inode) +{ + bool tmp; + + return d_inode(ovl_entry_real(inode->i_private, &tmp)); +} + struct vfsmount *ovl_entry_mnt_real(struct ovl_entry *oe, struct inode *inode, bool is_upper) { @@ -1172,6 +1179,7 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent) sb->s_op = &ovl_super_operations; sb->s_root = root_dentry; sb->s_fs_info = ufs; + sb->s_flags |= MS_POSIXACL; return 0;