aboutsummaryrefslogtreecommitdiffstats
path: root/fs/overlayfs/inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/overlayfs/inode.c')
-rw-r--r--fs/overlayfs/inode.c20
1 files changed, 16 insertions, 4 deletions
diff --git a/fs/overlayfs/inode.c b/fs/overlayfs/inode.c
index a619addecafc..321511ed8c42 100644
--- a/fs/overlayfs/inode.c
+++ b/fs/overlayfs/inode.c
@@ -598,18 +598,30 @@ static bool ovl_verify_inode(struct inode *inode, struct dentry *lowerdentry,
598 return true; 598 return true;
599} 599}
600 600
601struct inode *ovl_get_inode(struct dentry *dentry, struct dentry *upperdentry) 601struct inode *ovl_get_inode(struct dentry *dentry, struct dentry *upperdentry,
602 struct dentry *index)
602{ 603{
603 struct dentry *lowerdentry = ovl_dentry_lower(dentry); 604 struct dentry *lowerdentry = ovl_dentry_lower(dentry);
604 struct inode *realinode = upperdentry ? d_inode(upperdentry) : NULL; 605 struct inode *realinode = upperdentry ? d_inode(upperdentry) : NULL;
605 struct inode *inode; 606 struct inode *inode;
607 /* Already indexed or could be indexed on copy up? */
608 bool indexed = (index || (ovl_indexdir(dentry->d_sb) && !upperdentry));
609
610 if (WARN_ON(upperdentry && indexed && !lowerdentry))
611 return ERR_PTR(-EIO);
606 612
607 if (!realinode) 613 if (!realinode)
608 realinode = d_inode(lowerdentry); 614 realinode = d_inode(lowerdentry);
609 615
610 if (!S_ISDIR(realinode->i_mode) && 616 /*
611 (upperdentry || (lowerdentry && ovl_indexdir(dentry->d_sb)))) { 617 * Copy up origin (lower) may exist for non-indexed upper, but we must
612 struct inode *key = d_inode(lowerdentry ?: upperdentry); 618 * not use lower as hash key in that case.
619 * Hash inodes that are or could be indexed by origin inode and
620 * non-indexed upper inodes that could be hard linked by upper inode.
621 */
622 if (!S_ISDIR(realinode->i_mode) && (upperdentry || indexed)) {
623 struct inode *key = d_inode(indexed ? lowerdentry :
624 upperdentry);
613 unsigned int nlink; 625 unsigned int nlink;
614 626
615 inode = iget5_locked(dentry->d_sb, (unsigned long) key, 627 inode = iget5_locked(dentry->d_sb, (unsigned long) key,