提交 4d2a073c 编写于 作者: L Linus Torvalds

Merge branch 'work.lookup' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs

Pull vfs lookup() updates from Al Viro:
 "More conversions of ->lookup() to d_splice_alias().

  Should be reasonably complete now - the only leftovers are in ceph"

* 'work.lookup' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
  afs_try_auto_mntpt(): return NULL instead of ERR_PTR(-ENOENT)
  afs_lookup(): switch to d_splice_alias()
  afs: switch dynroot lookups to d_splice_alias()
  hpfs: fix an inode leak in lookup, switch to d_splice_alias()
  hostfs_lookup: switch to d_splice_alias()
...@@ -822,6 +822,7 @@ static struct dentry *afs_lookup(struct inode *dir, struct dentry *dentry, ...@@ -822,6 +822,7 @@ static struct dentry *afs_lookup(struct inode *dir, struct dentry *dentry,
{ {
struct afs_vnode *dvnode = AFS_FS_I(dir); struct afs_vnode *dvnode = AFS_FS_I(dir);
struct inode *inode; struct inode *inode;
struct dentry *d;
struct key *key; struct key *key;
int ret; int ret;
...@@ -862,43 +863,17 @@ static struct dentry *afs_lookup(struct inode *dir, struct dentry *dentry, ...@@ -862,43 +863,17 @@ static struct dentry *afs_lookup(struct inode *dir, struct dentry *dentry,
afs_stat_v(dvnode, n_lookup); afs_stat_v(dvnode, n_lookup);
inode = afs_do_lookup(dir, dentry, key); inode = afs_do_lookup(dir, dentry, key);
if (IS_ERR(inode)) {
ret = PTR_ERR(inode);
if (ret == -ENOENT) {
inode = afs_try_auto_mntpt(dentry, dir);
if (!IS_ERR(inode)) {
key_put(key);
goto success;
}
ret = PTR_ERR(inode);
}
key_put(key);
if (ret == -ENOENT) {
d_add(dentry, NULL);
_leave(" = NULL [negative]");
return NULL;
}
_leave(" = %d [do]", ret);
return ERR_PTR(ret);
}
dentry->d_fsdata = (void *)(unsigned long)dvnode->status.data_version;
/* instantiate the dentry */
key_put(key); key_put(key);
if (IS_ERR(inode)) { if (inode == ERR_PTR(-ENOENT)) {
_leave(" = %ld", PTR_ERR(inode)); inode = afs_try_auto_mntpt(dentry, dir);
return ERR_CAST(inode); } else {
dentry->d_fsdata =
(void *)(unsigned long)dvnode->status.data_version;
} }
d = d_splice_alias(inode, dentry);
success: if (!IS_ERR_OR_NULL(d))
d_add(dentry, inode); d->d_fsdata = dentry->d_fsdata;
_leave(" = 0 { ino=%lu v=%u }", return d;
d_inode(dentry)->i_ino,
d_inode(dentry)->i_generation);
return NULL;
} }
/* /*
......
...@@ -83,7 +83,7 @@ struct inode *afs_try_auto_mntpt(struct dentry *dentry, struct inode *dir) ...@@ -83,7 +83,7 @@ struct inode *afs_try_auto_mntpt(struct dentry *dentry, struct inode *dir)
out: out:
_leave("= %d", ret); _leave("= %d", ret);
return ERR_PTR(ret); return ret == -ENOENT ? NULL : ERR_PTR(ret);
} }
/* /*
...@@ -141,12 +141,6 @@ static struct dentry *afs_lookup_atcell(struct dentry *dentry) ...@@ -141,12 +141,6 @@ static struct dentry *afs_lookup_atcell(struct dentry *dentry)
static struct dentry *afs_dynroot_lookup(struct inode *dir, struct dentry *dentry, static struct dentry *afs_dynroot_lookup(struct inode *dir, struct dentry *dentry,
unsigned int flags) unsigned int flags)
{ {
struct afs_vnode *vnode;
struct inode *inode;
int ret;
vnode = AFS_FS_I(dir);
_enter("%pd", dentry); _enter("%pd", dentry);
ASSERTCMP(d_inode(dentry), ==, NULL); ASSERTCMP(d_inode(dentry), ==, NULL);
...@@ -160,22 +154,7 @@ static struct dentry *afs_dynroot_lookup(struct inode *dir, struct dentry *dentr ...@@ -160,22 +154,7 @@ static struct dentry *afs_dynroot_lookup(struct inode *dir, struct dentry *dentr
memcmp(dentry->d_name.name, "@cell", 5) == 0) memcmp(dentry->d_name.name, "@cell", 5) == 0)
return afs_lookup_atcell(dentry); return afs_lookup_atcell(dentry);
inode = afs_try_auto_mntpt(dentry, dir); return d_splice_alias(afs_try_auto_mntpt(dentry, dir), dentry);
if (IS_ERR(inode)) {
ret = PTR_ERR(inode);
if (ret == -ENOENT) {
d_add(dentry, NULL);
_leave(" = NULL [negative]");
return NULL;
}
_leave(" = %d [do]", ret);
return ERR_PTR(ret);
}
d_add(dentry, inode);
_leave(" = 0 { ino=%lu v=%u }",
d_inode(dentry)->i_ino, d_inode(dentry)->i_generation);
return NULL;
} }
const struct inode_operations afs_dynroot_inode_operations = { const struct inode_operations afs_dynroot_inode_operations = {
......
...@@ -610,33 +610,21 @@ static struct dentry *hostfs_lookup(struct inode *ino, struct dentry *dentry, ...@@ -610,33 +610,21 @@ static struct dentry *hostfs_lookup(struct inode *ino, struct dentry *dentry,
int err; int err;
inode = hostfs_iget(ino->i_sb); inode = hostfs_iget(ino->i_sb);
if (IS_ERR(inode)) { if (IS_ERR(inode))
err = PTR_ERR(inode);
goto out; goto out;
}
err = -ENOMEM; err = -ENOMEM;
name = dentry_name(dentry); name = dentry_name(dentry);
if (name == NULL) if (name) {
goto out_put; err = read_name(inode, name);
__putname(name);
err = read_name(inode, name); }
if (err) {
__putname(name);
if (err == -ENOENT) {
iput(inode); iput(inode);
inode = NULL; inode = (err == -ENOENT) ? NULL : ERR_PTR(err);
} }
else if (err)
goto out_put;
d_add(dentry, inode);
return NULL;
out_put:
iput(inode);
out: out:
return ERR_PTR(err); return d_splice_alias(inode, dentry);
} }
static int hostfs_link(struct dentry *to, struct inode *ino, static int hostfs_link(struct dentry *to, struct inode *ino,
......
...@@ -244,6 +244,7 @@ struct dentry *hpfs_lookup(struct inode *dir, struct dentry *dentry, unsigned in ...@@ -244,6 +244,7 @@ struct dentry *hpfs_lookup(struct inode *dir, struct dentry *dentry, unsigned in
result = iget_locked(dir->i_sb, ino); result = iget_locked(dir->i_sb, ino);
if (!result) { if (!result) {
hpfs_error(dir->i_sb, "hpfs_lookup: can't get inode"); hpfs_error(dir->i_sb, "hpfs_lookup: can't get inode");
result = ERR_PTR(-ENOMEM);
goto bail1; goto bail1;
} }
if (result->i_state & I_NEW) { if (result->i_state & I_NEW) {
...@@ -266,6 +267,8 @@ struct dentry *hpfs_lookup(struct inode *dir, struct dentry *dentry, unsigned in ...@@ -266,6 +267,8 @@ struct dentry *hpfs_lookup(struct inode *dir, struct dentry *dentry, unsigned in
if (de->has_acl || de->has_xtd_perm) if (!sb_rdonly(dir->i_sb)) { if (de->has_acl || de->has_xtd_perm) if (!sb_rdonly(dir->i_sb)) {
hpfs_error(result->i_sb, "ACLs or XPERM found. This is probably HPFS386. This driver doesn't support it now. Send me some info on these structures"); hpfs_error(result->i_sb, "ACLs or XPERM found. This is probably HPFS386. This driver doesn't support it now. Send me some info on these structures");
iput(result);
result = ERR_PTR(-EINVAL);
goto bail1; goto bail1;
} }
...@@ -301,29 +304,17 @@ struct dentry *hpfs_lookup(struct inode *dir, struct dentry *dentry, unsigned in ...@@ -301,29 +304,17 @@ struct dentry *hpfs_lookup(struct inode *dir, struct dentry *dentry, unsigned in
} }
} }
bail1:
hpfs_brelse4(&qbh); hpfs_brelse4(&qbh);
/* /*
* Made it. * Made it.
*/ */
end: end:
end_add: end_add:
hpfs_unlock(dir->i_sb); hpfs_unlock(dir->i_sb);
d_add(dentry, result); return d_splice_alias(result, dentry);
return NULL;
/*
* Didn't.
*/
bail1:
hpfs_brelse4(&qbh);
/*bail:*/
hpfs_unlock(dir->i_sb);
return ERR_PTR(-ENOENT);
} }
const struct file_operations hpfs_dir_ops = const struct file_operations hpfs_dir_ops =
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册