X-Git-Url: https://bbs.cooldavid.org/git/?a=blobdiff_plain;f=fs%2Fnamei.c;h=11de7c39ff76efb5fed2e09f34f0ac212df58cf0;hb=b04f784e5d19ed58892833dae845738972cea260;hp=b815a4d2e1d6a326d1aefdcfb4ab5e919dd0de19;hpb=2a4419b5b2a77f3f4537c14f7ad7df95770655dd;p=net-next-2.6.git diff --git a/fs/namei.c b/fs/namei.c index b815a4d2e1d..11de7c39ff7 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -735,6 +735,11 @@ static int do_lookup(struct nameidata *nd, struct qstr *name, return err; } + /* + * Rename seqlock is not required here because in the off chance + * of a false negative due to a concurrent rename, we're going to + * do the non-racy lookup, below. + */ dentry = __d_lookup(nd->path.dentry, name); if (!dentry) goto need_lookup; @@ -754,17 +759,13 @@ need_lookup: mutex_lock(&dir->i_mutex); /* * First re-do the cached lookup just in case it was created - * while we waited for the directory semaphore.. - * - * FIXME! This could use version numbering or similar to - * avoid unnecessary cache lookups. - * - * The "dcache_lock" is purely to protect the RCU list walker - * from concurrent renames at this point (we mustn't get false - * negatives from the RCU list walk here, unlike the optimistic - * fast walk). + * while we waited for the directory semaphore, or the first + * lookup failed due to an unrelated rename. * - * so doing d_lookup() (with seqlock), instead of lockfree __d_lookup + * This could use version numbering or similar to avoid unnecessary + * cache lookups, but then we'd have to do the first lookup in the + * non-racy way. However in the common case here, everything should + * be hot in cache, so would it be a big win? */ dentry = d_lookup(parent, name); if (likely(!dentry)) { @@ -1136,13 +1137,12 @@ static struct dentry *__lookup_hash(struct qstr *name, goto out; } - dentry = __d_lookup(base, name); - - /* lockess __d_lookup may fail due to concurrent d_move() - * in some unrelated directory, so try with d_lookup + /* + * Don't bother with __d_lookup: callers are for creat as + * well as unlink, so a lot of the time it would cost + * a double lookup. */ - if (!dentry) - dentry = d_lookup(base, name); + dentry = d_lookup(base, name); if (dentry && dentry->d_op && dentry->d_op->d_revalidate) dentry = do_revalidate(dentry, nd);