Skip to content

Commit ad5a035

Browse files
neilbrownbrauner
authored andcommitted
VFS: change try_lookup_noperm() to skip revalidation
The recent change from using d_hash_and_lookup() to using try_lookup_noperm() inadvertently introduce a d_revalidate() call when the lookup was successful. Steven French reports that this resulted in worse than halving of performance in some cases. Prior to the offending patch the only caller of try_lookup_noperm() was autofs which does not need the d_revalidate(). So it is safe to remove the d_revalidate() call providing we stop using try_lookup_noperm() to implement lookup_noperm(). The "try_" in the name is strongly suggestive that the caller isn't expecting much effort, so it seems reasonable to avoid the effort of d_revalidate(). Fixes: 06c5674 ("Use try_lookup_noperm() instead of d_hash_and_lookup() outside of VFS") Reported-by: Steve French <[email protected]> Link: https://lore.kernel.org/all/CAH2r5mu5SfBrdc2CFHwzft8=n9koPMk+Jzwpy-oUMx-wCRCesQ@mail.gmail.com/ Signed-off-by: NeilBrown <[email protected]> Link: https://lore.kernel.org/[email protected] Tested-by: Steve French <[email protected]> Signed-off-by: Christian Brauner <[email protected]>
1 parent 6bdd3a0 commit ad5a035

File tree

1 file changed

+13
-4
lines changed

1 file changed

+13
-4
lines changed

fs/namei.c

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2917,7 +2917,8 @@ static int lookup_one_common(struct mnt_idmap *idmap,
29172917
* @base: base directory to lookup from
29182918
*
29192919
* Look up a dentry by name in the dcache, returning NULL if it does not
2920-
* currently exist. The function does not try to create a dentry.
2920+
* currently exist. The function does not try to create a dentry and if one
2921+
* is found it doesn't try to revalidate it.
29212922
*
29222923
* Note that this routine is purely a helper for filesystem usage and should
29232924
* not be called by generic code. It does no permission checking.
@@ -2933,7 +2934,7 @@ struct dentry *try_lookup_noperm(struct qstr *name, struct dentry *base)
29332934
if (err)
29342935
return ERR_PTR(err);
29352936

2936-
return lookup_dcache(name, base, 0);
2937+
return d_lookup(base, name);
29372938
}
29382939
EXPORT_SYMBOL(try_lookup_noperm);
29392940

@@ -3057,14 +3058,22 @@ EXPORT_SYMBOL(lookup_one_positive_unlocked);
30573058
* Note that this routine is purely a helper for filesystem usage and should
30583059
* not be called by generic code. It does no permission checking.
30593060
*
3060-
* Unlike lookup_noperm, it should be called without the parent
3061+
* Unlike lookup_noperm(), it should be called without the parent
30613062
* i_rwsem held, and will take the i_rwsem itself if necessary.
3063+
*
3064+
* Unlike try_lookup_noperm() it *does* revalidate the dentry if it already
3065+
* existed.
30623066
*/
30633067
struct dentry *lookup_noperm_unlocked(struct qstr *name, struct dentry *base)
30643068
{
30653069
struct dentry *ret;
3070+
int err;
30663071

3067-
ret = try_lookup_noperm(name, base);
3072+
err = lookup_noperm_common(name, base);
3073+
if (err)
3074+
return ERR_PTR(err);
3075+
3076+
ret = lookup_dcache(name, base, 0);
30683077
if (!ret)
30693078
ret = lookup_slow(name, base, 0);
30703079
return ret;

0 commit comments

Comments
 (0)