mirror of https://gitee.com/openkylin/linux.git
saner proc_get_inode() calling conventions
Make it drop the pde in *all* cases when no new reference to it is put into an inode - both when an inode had already been set up (as we were already doing) and when inode allocation has failed. Makes for simpler logics in callers... Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
parent
87e0aab37f
commit
d3d009cb96
|
@ -412,8 +412,7 @@ static const struct dentry_operations proc_dentry_operations =
|
||||||
struct dentry *proc_lookup_de(struct proc_dir_entry *de, struct inode *dir,
|
struct dentry *proc_lookup_de(struct proc_dir_entry *de, struct inode *dir,
|
||||||
struct dentry *dentry)
|
struct dentry *dentry)
|
||||||
{
|
{
|
||||||
struct inode *inode = NULL;
|
struct inode *inode;
|
||||||
int error = -ENOENT;
|
|
||||||
|
|
||||||
spin_lock(&proc_subdir_lock);
|
spin_lock(&proc_subdir_lock);
|
||||||
for (de = de->subdir; de ; de = de->next) {
|
for (de = de->subdir; de ; de = de->next) {
|
||||||
|
@ -422,22 +421,16 @@ struct dentry *proc_lookup_de(struct proc_dir_entry *de, struct inode *dir,
|
||||||
if (!memcmp(dentry->d_name.name, de->name, de->namelen)) {
|
if (!memcmp(dentry->d_name.name, de->name, de->namelen)) {
|
||||||
pde_get(de);
|
pde_get(de);
|
||||||
spin_unlock(&proc_subdir_lock);
|
spin_unlock(&proc_subdir_lock);
|
||||||
error = -ENOMEM;
|
|
||||||
inode = proc_get_inode(dir->i_sb, de);
|
inode = proc_get_inode(dir->i_sb, de);
|
||||||
goto out_unlock;
|
if (!inode)
|
||||||
|
return ERR_PTR(-ENOMEM);
|
||||||
|
d_set_d_op(dentry, &proc_dentry_operations);
|
||||||
|
d_add(dentry, inode);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
spin_unlock(&proc_subdir_lock);
|
spin_unlock(&proc_subdir_lock);
|
||||||
out_unlock:
|
return ERR_PTR(-ENOENT);
|
||||||
|
|
||||||
if (inode) {
|
|
||||||
d_set_d_op(dentry, &proc_dentry_operations);
|
|
||||||
d_add(dentry, inode);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if (de)
|
|
||||||
pde_put(de);
|
|
||||||
return ERR_PTR(error);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct dentry *proc_lookup(struct inode *dir, struct dentry *dentry,
|
struct dentry *proc_lookup(struct inode *dir, struct dentry *dentry,
|
||||||
|
|
|
@ -445,12 +445,9 @@ static const struct file_operations proc_reg_file_ops_no_compat = {
|
||||||
|
|
||||||
struct inode *proc_get_inode(struct super_block *sb, struct proc_dir_entry *de)
|
struct inode *proc_get_inode(struct super_block *sb, struct proc_dir_entry *de)
|
||||||
{
|
{
|
||||||
struct inode * inode;
|
struct inode *inode = iget_locked(sb, de->low_ino);
|
||||||
|
|
||||||
inode = iget_locked(sb, de->low_ino);
|
if (inode && (inode->i_state & I_NEW)) {
|
||||||
if (!inode)
|
|
||||||
return NULL;
|
|
||||||
if (inode->i_state & I_NEW) {
|
|
||||||
inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
|
inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
|
||||||
PROC_I(inode)->pde = de;
|
PROC_I(inode)->pde = de;
|
||||||
|
|
||||||
|
@ -499,7 +496,6 @@ int proc_fill_super(struct super_block *s)
|
||||||
root_inode = proc_get_inode(s, &proc_root);
|
root_inode = proc_get_inode(s, &proc_root);
|
||||||
if (!root_inode) {
|
if (!root_inode) {
|
||||||
printk(KERN_ERR "proc_fill_super: get root inode failed\n");
|
printk(KERN_ERR "proc_fill_super: get root inode failed\n");
|
||||||
pde_put(&proc_root);
|
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue