summaryrefslogtreecommitdiffstats
path: root/fs/namei.c
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2016-04-14 19:33:34 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2016-05-02 19:47:26 -0400
commit1936386ea96591c27ae4b70caef9591c41e6290f (patch)
tree1cb793a9f7621bff82219d64c7f9813a23ebee69 /fs/namei.c
parentd2caaa0a7745eed3a827e919a37470d34b8fc20d (diff)
lookup_slow(): bugger off on IS_DEADDIR() from the very beginning
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/namei.c')
-rw-r--r--fs/namei.c23
1 files changed, 17 insertions, 6 deletions
diff --git a/fs/namei.c b/fs/namei.c
index bdcea8a018b8..c275635c4b9e 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -1603,8 +1603,15 @@ static struct dentry *lookup_slow(const struct qstr *name,
1603 struct dentry *dir, 1603 struct dentry *dir,
1604 unsigned int flags) 1604 unsigned int flags)
1605{ 1605{
1606 struct dentry *dentry; 1606 struct dentry *dentry, *old;
1607 inode_lock(dir->d_inode); 1607 struct inode *inode = dir->d_inode;
1608
1609 inode_lock(inode);
1610 /* Don't go there if it's already dead */
1611 if (unlikely(IS_DEADDIR(inode))) {
1612 inode_unlock(inode);
1613 return ERR_PTR(-ENOENT);
1614 }
1608 dentry = d_lookup(dir, name); 1615 dentry = d_lookup(dir, name);
1609 if (unlikely(dentry)) { 1616 if (unlikely(dentry)) {
1610 if ((dentry->d_flags & DCACHE_OP_REVALIDATE) && 1617 if ((dentry->d_flags & DCACHE_OP_REVALIDATE) &&
@@ -1618,17 +1625,21 @@ static struct dentry *lookup_slow(const struct qstr *name,
1618 } 1625 }
1619 } 1626 }
1620 if (dentry) { 1627 if (dentry) {
1621 inode_unlock(dir->d_inode); 1628 inode_unlock(inode);
1622 return dentry; 1629 return dentry;
1623 } 1630 }
1624 } 1631 }
1625 dentry = d_alloc(dir, name); 1632 dentry = d_alloc(dir, name);
1626 if (unlikely(!dentry)) { 1633 if (unlikely(!dentry)) {
1627 inode_unlock(dir->d_inode); 1634 inode_unlock(inode);
1628 return ERR_PTR(-ENOMEM); 1635 return ERR_PTR(-ENOMEM);
1629 } 1636 }
1630 dentry = lookup_real(dir->d_inode, dentry, flags); 1637 old = inode->i_op->lookup(inode, dentry, flags);
1631 inode_unlock(dir->d_inode); 1638 if (unlikely(old)) {
1639 dput(dentry);
1640 dentry = old;
1641 }
1642 inode_unlock(inode);
1632 return dentry; 1643 return dentry;
1633} 1644}
1634 1645