ovl: define ->get_acl() for overlay inodes
authorVivek Goyal <vgoyal@redhat.com>
Fri, 1 Jul 2016 20:34:26 +0000 (16:34 -0400)
committerMiklos Szeredi <mszeredi@redhat.com>
Fri, 29 Jul 2016 10:05:23 +0000 (12:05 +0200)
Now we are planning to do DAC permission checks on overlay inode
itself. And to make it work, we will need to make sure we can get acls from
underlying inode. So define ->get_acl() for overlay inodes and this in turn
calls into underlying filesystem to get acls, if any.

Signed-off-by: Vivek Goyal <vgoyal@redhat.com>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
fs/overlayfs/dir.c
fs/overlayfs/inode.c
fs/overlayfs/overlayfs.h
fs/overlayfs/super.c

index d9cdb4747f6882e38d897d758af3328119e480cb..aa632055719678b5f358efd355cb3a889d2c40f7 100644 (file)
@@ -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,
 };
index 32ae8b49a72c8cc2e3b9bc368860a154f13202ca..a574108f52a8b3a012883bded82620c874bff62a 100644 (file)
@@ -310,6 +310,22 @@ out:
        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 = {
index 0d3f2ad45708ee712ab6896b65d6aeb303855edc..75128c70aa6a626412c744b2d47dcc98ff4b3550 100644 (file)
@@ -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,
index 5341ca57677cad1734f56b485846c8c76406493f..893d6e0ea1c50f989886e92e546b06e624ae1230 100644 (file)
@@ -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;