ovl: store lower path in ovl_inode
authorAmir Goldstein <amir73il@gmail.com>
Mon, 4 Apr 2022 10:51:53 +0000 (12:51 +0200)
committerMiklos Szeredi <mszeredi@redhat.com>
Thu, 28 Apr 2022 14:31:12 +0000 (16:31 +0200)
Create some ovl_i_* helpers to get real path from ovl inode. Instead of
just stashing struct inode for the lower layer we stash struct path for
the lower layer. The helpers allow to retrieve a struct path for the
relevant upper or lower layer. This will be used when retrieving
information based on struct inode when copying up inode attributes from
upper or lower inodes to ovl inodes and when checking permissions in
ovl_permission() in following patches. This is needed to support
idmapped base layers with overlay.

Cc: <linux-unionfs@vger.kernel.org>
Tested-by: Giuseppe Scrivano <gscrivan@redhat.com>
Reviewed-by: Christian Brauner (Microsoft) <brauner@kernel.org>
Signed-off-by: Amir Goldstein <amir73il@gmail.com>
Signed-off-by: Christian Brauner (Microsoft) <brauner@kernel.org>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
fs/overlayfs/inode.c
fs/overlayfs/overlayfs.h
fs/overlayfs/ovl_entry.h
fs/overlayfs/super.c
fs/overlayfs/util.c

index 7ed5df9c0fa65b4e9ce3159d5a2bcda6ec37f10e..f29e137e6d6073ea1985a0851f281a1e909c777a 100644 (file)
@@ -779,13 +779,16 @@ void ovl_inode_init(struct inode *inode, struct ovl_inode_params *oip,
                    unsigned long ino, int fsid)
 {
        struct inode *realinode;
+       struct ovl_inode *oi = OVL_I(inode);
 
        if (oip->upperdentry)
-               OVL_I(inode)->__upperdentry = oip->upperdentry;
-       if (oip->lowerpath && oip->lowerpath->dentry)
-               OVL_I(inode)->lower = igrab(d_inode(oip->lowerpath->dentry));
+               oi->__upperdentry = oip->upperdentry;
+       if (oip->lowerpath && oip->lowerpath->dentry) {
+               oi->lowerpath.dentry = dget(oip->lowerpath->dentry);
+               oi->lowerpath.layer = oip->lowerpath->layer;
+       }
        if (oip->lowerdata)
-               OVL_I(inode)->lowerdata = igrab(d_inode(oip->lowerdata));
+               oi->lowerdata = igrab(d_inode(oip->lowerdata));
 
        realinode = ovl_inode_real(inode);
        ovl_copyattr(realinode, inode);
index 6cbb1fd2a4ec278d285dbd86a698498af0c2405e..7b4db563260088b2b3c25c9ba74a7510053d56a7 100644 (file)
@@ -374,11 +374,13 @@ enum ovl_path_type ovl_path_type(struct dentry *dentry);
 void ovl_path_upper(struct dentry *dentry, struct path *path);
 void ovl_path_lower(struct dentry *dentry, struct path *path);
 void ovl_path_lowerdata(struct dentry *dentry, struct path *path);
+void ovl_i_path_real(struct inode *inode, struct path *path);
 enum ovl_path_type ovl_path_real(struct dentry *dentry, struct path *path);
 enum ovl_path_type ovl_path_realdata(struct dentry *dentry, struct path *path);
 struct dentry *ovl_dentry_upper(struct dentry *dentry);
 struct dentry *ovl_dentry_lower(struct dentry *dentry);
 struct dentry *ovl_dentry_lowerdata(struct dentry *dentry);
+const struct ovl_layer *ovl_i_layer_lower(struct inode *inode);
 const struct ovl_layer *ovl_layer_lower(struct dentry *dentry);
 struct dentry *ovl_dentry_real(struct dentry *dentry);
 struct dentry *ovl_i_dentry_upper(struct inode *inode);
index 61b40d1268c89bd4bea15d5f0b8372247426d68c..469162ca9b213f5cb3bf198c28ea98abbc205ba7 100644 (file)
@@ -134,7 +134,7 @@ struct ovl_inode {
        unsigned long flags;
        struct inode vfs_inode;
        struct dentry *__upperdentry;
-       struct inode *lower;
+       struct ovl_path lowerpath;
 
        /* synchronize copy up and more */
        struct mutex lock;
index 2fd2d3e5eaba73b68261458441479031ea5792fe..0123c8086ee96229819eaa278f40954ad4584970 100644 (file)
@@ -184,7 +184,8 @@ static struct inode *ovl_alloc_inode(struct super_block *sb)
        oi->version = 0;
        oi->flags = 0;
        oi->__upperdentry = NULL;
-       oi->lower = NULL;
+       oi->lowerpath.dentry = NULL;
+       oi->lowerpath.layer = NULL;
        oi->lowerdata = NULL;
        mutex_init(&oi->lock);
 
@@ -205,7 +206,7 @@ static void ovl_destroy_inode(struct inode *inode)
        struct ovl_inode *oi = OVL_I(inode);
 
        dput(oi->__upperdentry);
-       iput(oi->lower);
+       dput(oi->lowerpath.dentry);
        if (S_ISDIR(inode->i_mode))
                ovl_dir_cache_free(inode);
        else
index 81585cad055d74a872d00ad59e39a067e4175b4a..5fdaa9408c84877271030f9a73f426ab1489496a 100644 (file)
@@ -250,6 +250,17 @@ struct dentry *ovl_i_dentry_upper(struct inode *inode)
        return ovl_upperdentry_dereference(OVL_I(inode));
 }
 
+void ovl_i_path_real(struct inode *inode, struct path *path)
+{
+       path->dentry = ovl_i_dentry_upper(inode);
+       if (!path->dentry) {
+               path->dentry = OVL_I(inode)->lowerpath.dentry;
+               path->mnt = OVL_I(inode)->lowerpath.layer->mnt;
+       } else {
+               path->mnt = ovl_upper_mnt(OVL_FS(inode->i_sb));
+       }
+}
+
 struct inode *ovl_inode_upper(struct inode *inode)
 {
        struct dentry *upperdentry = ovl_i_dentry_upper(inode);
@@ -259,7 +270,9 @@ struct inode *ovl_inode_upper(struct inode *inode)
 
 struct inode *ovl_inode_lower(struct inode *inode)
 {
-       return OVL_I(inode)->lower;
+       struct dentry *lowerdentry = OVL_I(inode)->lowerpath.dentry;
+
+       return lowerdentry ? d_inode(lowerdentry) : NULL;
 }
 
 struct inode *ovl_inode_real(struct inode *inode)