Skip to content

Commit bad6118

Browse files
Miklos SzerediAl Viro
authored andcommitted
vfs: split __lookup_hash
Split __lookup_hash into two component functions: lookup_dcache - tries cached lookup, returns whether real lookup is needed lookup_real - calls i_op->lookup This eliminates code duplication between d_alloc_and_lookup() and d_inode_lookup(). Signed-off-by: Miklos Szeredi <[email protected]> Signed-off-by: Al Viro <[email protected]>
1 parent 81e6f52 commit bad6118

File tree

1 file changed

+44
-64
lines changed

1 file changed

+44
-64
lines changed

fs/namei.c

Lines changed: 44 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1054,53 +1054,65 @@ static void follow_dotdot(struct nameidata *nd)
10541054
}
10551055

10561056
/*
1057-
* Allocate a dentry with name and parent, and perform a parent
1058-
* directory ->lookup on it. Returns the new dentry, or ERR_PTR
1059-
* on error. parent->d_inode->i_mutex must be held. d_lookup must
1060-
* have verified that no child exists while under i_mutex.
1057+
* This looks up the name in dcache, possibly revalidates the old dentry and
1058+
* allocates a new one if not found or not valid. In the need_lookup argument
1059+
* returns whether i_op->lookup is necessary.
1060+
*
1061+
* dir->d_inode->i_mutex must be held
10611062
*/
1062-
static struct dentry *d_alloc_and_lookup(struct dentry *parent,
1063-
struct qstr *name, struct nameidata *nd)
1063+
static struct dentry *lookup_dcache(struct qstr *name, struct dentry *dir,
1064+
struct nameidata *nd, bool *need_lookup)
10641065
{
1065-
struct inode *inode = parent->d_inode;
10661066
struct dentry *dentry;
1067-
struct dentry *old;
1067+
int error;
10681068

1069-
/* Don't create child dentry for a dead directory. */
1070-
if (unlikely(IS_DEADDIR(inode)))
1071-
return ERR_PTR(-ENOENT);
1069+
*need_lookup = false;
1070+
dentry = d_lookup(dir, name);
1071+
if (dentry) {
1072+
if (d_need_lookup(dentry)) {
1073+
*need_lookup = true;
1074+
} else if (dentry->d_flags & DCACHE_OP_REVALIDATE) {
1075+
error = d_revalidate(dentry, nd);
1076+
if (unlikely(error <= 0)) {
1077+
if (error < 0) {
1078+
dput(dentry);
1079+
return ERR_PTR(error);
1080+
} else if (!d_invalidate(dentry)) {
1081+
dput(dentry);
1082+
dentry = NULL;
1083+
}
1084+
}
1085+
}
1086+
}
10721087

1073-
dentry = d_alloc(parent, name);
1074-
if (unlikely(!dentry))
1075-
return ERR_PTR(-ENOMEM);
1088+
if (!dentry) {
1089+
dentry = d_alloc(dir, name);
1090+
if (unlikely(!dentry))
1091+
return ERR_PTR(-ENOMEM);
10761092

1077-
old = inode->i_op->lookup(inode, dentry, nd);
1078-
if (unlikely(old)) {
1079-
dput(dentry);
1080-
dentry = old;
1093+
*need_lookup = true;
10811094
}
10821095
return dentry;
10831096
}
10841097

10851098
/*
1086-
* We already have a dentry, but require a lookup to be performed on the parent
1087-
* directory to fill in d_inode. Returns the new dentry, or ERR_PTR on error.
1088-
* parent->d_inode->i_mutex must be held. d_lookup must have verified that no
1089-
* child exists while under i_mutex.
1099+
* Call i_op->lookup on the dentry. The dentry must be negative but may be
1100+
* hashed if it was pouplated with DCACHE_NEED_LOOKUP.
1101+
*
1102+
* dir->d_inode->i_mutex must be held
10901103
*/
1091-
static struct dentry *d_inode_lookup(struct dentry *parent, struct dentry *dentry,
1092-
struct nameidata *nd)
1104+
static struct dentry *lookup_real(struct inode *dir, struct dentry *dentry,
1105+
struct nameidata *nd)
10931106
{
1094-
struct inode *inode = parent->d_inode;
10951107
struct dentry *old;
10961108

10971109
/* Don't create child dentry for a dead directory. */
1098-
if (unlikely(IS_DEADDIR(inode))) {
1110+
if (unlikely(IS_DEADDIR(dir))) {
10991111
dput(dentry);
11001112
return ERR_PTR(-ENOENT);
11011113
}
11021114

1103-
old = inode->i_op->lookup(inode, dentry, nd);
1115+
old = dir->i_op->lookup(dir, dentry, nd);
11041116
if (unlikely(old)) {
11051117
dput(dentry);
11061118
dentry = old;
@@ -1111,46 +1123,14 @@ static struct dentry *d_inode_lookup(struct dentry *parent, struct dentry *dentr
11111123
static struct dentry *__lookup_hash(struct qstr *name,
11121124
struct dentry *base, struct nameidata *nd)
11131125
{
1126+
bool need_lookup;
11141127
struct dentry *dentry;
11151128

1116-
/*
1117-
* Don't bother with __d_lookup: callers are for creat as
1118-
* well as unlink, so a lot of the time it would cost
1119-
* a double lookup.
1120-
*/
1121-
dentry = d_lookup(base, name);
1129+
dentry = lookup_dcache(name, base, nd, &need_lookup);
1130+
if (!need_lookup)
1131+
return dentry;
11221132

1123-
if (dentry && d_need_lookup(dentry)) {
1124-
/*
1125-
* __lookup_hash is called with the parent dir's i_mutex already
1126-
* held, so we are good to go here.
1127-
*/
1128-
return d_inode_lookup(base, dentry, nd);
1129-
}
1130-
1131-
if (dentry && (dentry->d_flags & DCACHE_OP_REVALIDATE)) {
1132-
int status = d_revalidate(dentry, nd);
1133-
if (unlikely(status <= 0)) {
1134-
/*
1135-
* The dentry failed validation.
1136-
* If d_revalidate returned 0 attempt to invalidate
1137-
* the dentry otherwise d_revalidate is asking us
1138-
* to return a fail status.
1139-
*/
1140-
if (status < 0) {
1141-
dput(dentry);
1142-
return ERR_PTR(status);
1143-
} else if (!d_invalidate(dentry)) {
1144-
dput(dentry);
1145-
dentry = NULL;
1146-
}
1147-
}
1148-
}
1149-
1150-
if (!dentry)
1151-
dentry = d_alloc_and_lookup(base, name, nd);
1152-
1153-
return dentry;
1133+
return lookup_real(base->d_inode, dentry, nd);
11541134
}
11551135

11561136
/*

0 commit comments

Comments
 (0)