In preparation for hashing all overlay inodes, modify the helper ovl_inode_init() to hash a new non-dir upper overlay inode. Use this helper for initializing new upper inode in ovl_instantiate() instead of ovl_inode_update(), because the implementations for new inode case and copy up case are going to diverge. Also move ovl_copyattr() into ovl_inode_init() and ovl_inode_get(), so attributes will be copied only for new inode. Signed-off-by: Amir Goldstein <amir73il@xxxxxxxxx> --- fs/overlayfs/dir.c | 3 +-- fs/overlayfs/inode.c | 1 + fs/overlayfs/namei.c | 1 - fs/overlayfs/util.c | 11 ++++++++++- 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/fs/overlayfs/dir.c b/fs/overlayfs/dir.c index a63a71656e9b..f87cef27741f 100644 --- a/fs/overlayfs/dir.c +++ b/fs/overlayfs/dir.c @@ -156,8 +156,7 @@ static void ovl_instantiate(struct dentry *dentry, struct inode *inode, ovl_dentry_version_inc(dentry->d_parent); ovl_dentry_update(dentry, newdentry); if (!hardlink) { - ovl_inode_update(inode, d_inode(newdentry)); - ovl_copyattr(newdentry->d_inode, inode); + ovl_inode_init(inode, d_inode(newdentry), true); } else { WARN_ON(ovl_inode_real(inode, NULL) != d_inode(newdentry)); inc_nlink(inode); diff --git a/fs/overlayfs/inode.c b/fs/overlayfs/inode.c index 49492b982726..6f0ec691d8d5 100644 --- a/fs/overlayfs/inode.c +++ b/fs/overlayfs/inode.c @@ -477,6 +477,7 @@ struct inode *ovl_get_inode(struct super_block *sb, struct inode *realinode) if (inode && inode->i_state & I_NEW) { ovl_fill_inode(inode, realinode->i_mode, realinode->i_rdev); set_nlink(inode, realinode->i_nlink); + ovl_copyattr(realinode, inode); unlock_new_inode(inode); } diff --git a/fs/overlayfs/namei.c b/fs/overlayfs/namei.c index fe84e482d926..228b9eaa19f6 100644 --- a/fs/overlayfs/namei.c +++ b/fs/overlayfs/namei.c @@ -623,7 +623,6 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry, } if (!inode) goto out_free_oe; - ovl_copyattr(realdentry->d_inode, inode); } revert_creds(old_cred); diff --git a/fs/overlayfs/util.c b/fs/overlayfs/util.c index 0ce6efd8f19d..9bbcfcb20ec4 100644 --- a/fs/overlayfs/util.c +++ b/fs/overlayfs/util.c @@ -267,6 +267,12 @@ void ovl_dentry_update(struct dentry *dentry, struct dentry *upperdentry) ovl_update_type(dentry, d_is_dir(dentry)); } +static void ovl_insert_inode_hash(struct inode *inode, struct inode *realinode) +{ + WARN_ON(!inode_unhashed(inode)); + __insert_inode_hash(inode, (unsigned long) realinode); +} + void ovl_inode_init(struct inode *inode, struct inode *realinode, bool is_upper) { struct ovl_inode_info *oi = OVL_I_INFO(inode); @@ -274,10 +280,13 @@ void ovl_inode_init(struct inode *inode, struct inode *realinode, bool is_upper) if (is_upper) { oi->__upperinode = realinode; oi->lowerinode = NULL; + if (!S_ISDIR(realinode->i_mode)) + ovl_insert_inode_hash(inode, realinode); } else { oi->__upperinode = NULL; oi->lowerinode = realinode; } + ovl_copyattr(realinode, inode); } struct inode *ovl_inode_real(struct inode *inode, bool *is_upper) @@ -300,7 +309,7 @@ void ovl_inode_update(struct inode *inode, struct inode *upperinode) WARN_ON(!inode_unhashed(inode)); WRITE_ONCE(OVL_I_INFO(inode)->__upperinode, upperinode); if (!S_ISDIR(upperinode->i_mode)) - __insert_inode_hash(inode, (unsigned long) upperinode); + ovl_insert_inode_hash(inode, upperinode); } void ovl_dentry_version_inc(struct dentry *dentry) -- 2.7.4 -- To unsubscribe from this list: send the line "unsubscribe linux-unionfs" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html