summaryrefslogtreecommitdiffstats
path: root/fs/overlayfs/super.c
diff options
context:
space:
mode:
authorVivek Goyal2018-05-11 17:49:30 +0200
committerMiklos Szeredi2018-07-20 09:56:11 +0200
commit2664bd0897c2889258472a1ee922ef9d4c5fa58f (patch)
tree4451f757dc52c00751c3158c24dc1bb004a6bc59 /fs/overlayfs/super.c
parentovl: Fix ovl_getattr() to get number of blocks from lower (diff)
downloadkernel-qcow2-linux-2664bd0897c2889258472a1ee922ef9d4c5fa58f.tar.gz
kernel-qcow2-linux-2664bd0897c2889258472a1ee922ef9d4c5fa58f.tar.xz
kernel-qcow2-linux-2664bd0897c2889258472a1ee922ef9d4c5fa58f.zip
ovl: Store lower data inode in ovl_inode
Right now ovl_inode stores inode pointer for lower inode. This helps with quickly getting lower inode given overlay inode (ovl_inode_lower()). Now with metadata only copy-up, we can have metacopy inode in middle layer as well and inode containing data can be different from ->lower. I need to be able to open the real file in ovl_open_realfile() and for that I need to quickly find the lower data inode. Hence store lower data inode also in ovl_inode. Also provide an helper ovl_inode_lowerdata() to access this field. Signed-off-by: Vivek Goyal <vgoyal@redhat.com> Reviewed-by: Amir Goldstein <amir73il@gmail.com> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
Diffstat (limited to 'fs/overlayfs/super.c')
-rw-r--r--fs/overlayfs/super.c8
1 files changed, 6 insertions, 2 deletions
diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c
index ab0039161f85..6d22bbd5f27f 100644
--- a/fs/overlayfs/super.c
+++ b/fs/overlayfs/super.c
@@ -181,6 +181,7 @@ static struct inode *ovl_alloc_inode(struct super_block *sb)
oi->flags = 0;
oi->__upperdentry = NULL;
oi->lower = NULL;
+ oi->lowerdata = NULL;
mutex_init(&oi->lock);
return &oi->vfs_inode;
@@ -199,8 +200,11 @@ static void ovl_destroy_inode(struct inode *inode)
dput(oi->__upperdentry);
iput(oi->lower);
+ if (S_ISDIR(inode->i_mode))
+ ovl_dir_cache_free(inode);
+ else
+ iput(oi->lowerdata);
kfree(oi->redirect);
- ovl_dir_cache_free(inode);
mutex_destroy(&oi->lock);
call_rcu(&inode->i_rcu, ovl_i_callback);
@@ -1487,7 +1491,7 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent)
ovl_dentry_set_flag(OVL_E_CONNECTED, root_dentry);
ovl_set_upperdata(d_inode(root_dentry));
ovl_inode_init(d_inode(root_dentry), upperpath.dentry,
- ovl_dentry_lower(root_dentry));
+ ovl_dentry_lower(root_dentry), NULL);
sb->s_root = root_dentry;