diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2016-04-14 19:33:34 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2016-05-02 19:47:26 -0400 |
commit | 1936386ea96591c27ae4b70caef9591c41e6290f (patch) | |
tree | 1cb793a9f7621bff82219d64c7f9813a23ebee69 /fs/namei.c | |
parent | d2caaa0a7745eed3a827e919a37470d34b8fc20d (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.c | 23 |
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 | ||