Skip to content

Commit 5d0f49c

Browse files
author
Al Viro
committed
namei: untanlge lookup_fast()
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
1 parent 6c51e51 commit 5d0f49c

File tree

1 file changed

+37
-46
lines changed

1 file changed

+37
-46
lines changed

fs/namei.c

Lines changed: 37 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1512,40 +1512,37 @@ static struct dentry *__lookup_hash(struct qstr *name,
15121512
return lookup_real(base->d_inode, dentry, flags);
15131513
}
15141514

1515-
/*
1516-
* It's more convoluted than I'd like it to be, but... it's still fairly
1517-
* small and for now I'd prefer to have fast path as straight as possible.
1518-
* It _is_ time-critical.
1519-
*/
15201515
static int lookup_fast(struct nameidata *nd,
15211516
struct path *path, struct inode **inode,
15221517
unsigned *seqp)
15231518
{
15241519
struct vfsmount *mnt = nd->path.mnt;
15251520
struct dentry *dentry, *parent = nd->path.dentry;
1526-
int need_reval = 1;
15271521
int status = 1;
15281522
int err;
15291523

15301524
/*
15311525
* Rename seqlock is not required here because in the off chance
1532-
* of a false negative due to a concurrent rename, we're going to
1533-
* do the non-racy lookup, below.
1526+
* of a false negative due to a concurrent rename, the caller is
1527+
* going to fall back to non-racy lookup.
15341528
*/
15351529
if (nd->flags & LOOKUP_RCU) {
15361530
unsigned seq;
15371531
bool negative;
15381532
dentry = __d_lookup_rcu(parent, &nd->last, &seq);
1539-
if (!dentry)
1540-
goto unlazy;
1533+
if (unlikely(!dentry)) {
1534+
if (unlazy_walk(nd, NULL, 0))
1535+
return -ECHILD;
1536+
return 1;
1537+
}
15411538

15421539
/*
15431540
* This sequence count validates that the inode matches
15441541
* the dentry name information from lookup.
15451542
*/
15461543
*inode = d_backing_inode(dentry);
15471544
negative = d_is_negative(dentry);
1548-
if (read_seqcount_retry(&dentry->d_seq, seq))
1545+
if (unlikely(read_seqcount_retry(&dentry->d_seq, seq)))
15491546
return -ECHILD;
15501547

15511548
/*
@@ -1555,63 +1552,57 @@ static int lookup_fast(struct nameidata *nd,
15551552
* The memory barrier in read_seqcount_begin of child is
15561553
* enough, we can use __read_seqcount_retry here.
15571554
*/
1558-
if (__read_seqcount_retry(&parent->d_seq, nd->seq))
1555+
if (unlikely(__read_seqcount_retry(&parent->d_seq, nd->seq)))
15591556
return -ECHILD;
15601557

15611558
*seqp = seq;
1562-
if (unlikely(dentry->d_flags & DCACHE_OP_REVALIDATE)) {
1559+
if (unlikely(dentry->d_flags & DCACHE_OP_REVALIDATE))
15631560
status = d_revalidate(dentry, nd->flags);
1564-
if (unlikely(status <= 0)) {
1565-
if (status != -ECHILD)
1566-
need_reval = 0;
1567-
goto unlazy;
1568-
}
1561+
if (unlikely(status <= 0)) {
1562+
if (unlazy_walk(nd, dentry, seq))
1563+
return -ECHILD;
1564+
if (status == -ECHILD)
1565+
status = d_revalidate(dentry, nd->flags);
1566+
} else {
1567+
/*
1568+
* Note: do negative dentry check after revalidation in
1569+
* case that drops it.
1570+
*/
1571+
if (unlikely(negative))
1572+
return -ENOENT;
1573+
path->mnt = mnt;
1574+
path->dentry = dentry;
1575+
if (likely(__follow_mount_rcu(nd, path, inode, seqp)))
1576+
return 0;
1577+
if (unlazy_walk(nd, dentry, seq))
1578+
return -ECHILD;
15691579
}
1570-
/*
1571-
* Note: do negative dentry check after revalidation in
1572-
* case that drops it.
1573-
*/
1574-
if (negative)
1575-
return -ENOENT;
1576-
path->mnt = mnt;
1577-
path->dentry = dentry;
1578-
if (likely(__follow_mount_rcu(nd, path, inode, seqp)))
1579-
return 0;
1580-
unlazy:
1581-
if (unlazy_walk(nd, dentry, seq))
1582-
return -ECHILD;
15831580
} else {
15841581
dentry = __d_lookup(parent, &nd->last);
1582+
if (unlikely(!dentry))
1583+
return 1;
1584+
if (unlikely(dentry->d_flags & DCACHE_OP_REVALIDATE))
1585+
status = d_revalidate(dentry, nd->flags);
15851586
}
1586-
1587-
if (unlikely(!dentry))
1588-
goto need_lookup;
1589-
1590-
if (unlikely(dentry->d_flags & DCACHE_OP_REVALIDATE) && need_reval)
1591-
status = d_revalidate(dentry, nd->flags);
15921587
if (unlikely(status <= 0)) {
1593-
if (status < 0) {
1594-
dput(dentry);
1595-
return status;
1588+
if (!status) {
1589+
d_invalidate(dentry);
1590+
status = 1;
15961591
}
1597-
d_invalidate(dentry);
15981592
dput(dentry);
1599-
goto need_lookup;
1593+
return status;
16001594
}
1601-
16021595
if (unlikely(d_is_negative(dentry))) {
16031596
dput(dentry);
16041597
return -ENOENT;
16051598
}
1599+
16061600
path->mnt = mnt;
16071601
path->dentry = dentry;
16081602
err = follow_managed(path, nd);
16091603
if (likely(!err))
16101604
*inode = d_backing_inode(path->dentry);
16111605
return err;
1612-
1613-
need_lookup:
1614-
return 1;
16151606
}
16161607

16171608
/* Fast lookup failed, do it the slow way */

0 commit comments

Comments
 (0)