|
@@ -429,7 +429,7 @@ struct dentry *proc_lookup_de(struct proc_dir_entry *de, struct inode *dir,
|
|
unsigned int ino;
|
|
unsigned int ino;
|
|
|
|
|
|
ino = de->low_ino;
|
|
ino = de->low_ino;
|
|
- de_get(de);
|
|
|
|
|
|
+ pde_get(de);
|
|
spin_unlock(&proc_subdir_lock);
|
|
spin_unlock(&proc_subdir_lock);
|
|
error = -EINVAL;
|
|
error = -EINVAL;
|
|
inode = proc_get_inode(dir->i_sb, ino, de);
|
|
inode = proc_get_inode(dir->i_sb, ino, de);
|
|
@@ -445,7 +445,7 @@ out_unlock:
|
|
return NULL;
|
|
return NULL;
|
|
}
|
|
}
|
|
if (de)
|
|
if (de)
|
|
- de_put(de);
|
|
|
|
|
|
+ pde_put(de);
|
|
return ERR_PTR(error);
|
|
return ERR_PTR(error);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -509,17 +509,17 @@ int proc_readdir_de(struct proc_dir_entry *de, struct file *filp, void *dirent,
|
|
struct proc_dir_entry *next;
|
|
struct proc_dir_entry *next;
|
|
|
|
|
|
/* filldir passes info to user space */
|
|
/* filldir passes info to user space */
|
|
- de_get(de);
|
|
|
|
|
|
+ pde_get(de);
|
|
spin_unlock(&proc_subdir_lock);
|
|
spin_unlock(&proc_subdir_lock);
|
|
if (filldir(dirent, de->name, de->namelen, filp->f_pos,
|
|
if (filldir(dirent, de->name, de->namelen, filp->f_pos,
|
|
de->low_ino, de->mode >> 12) < 0) {
|
|
de->low_ino, de->mode >> 12) < 0) {
|
|
- de_put(de);
|
|
|
|
|
|
+ pde_put(de);
|
|
goto out;
|
|
goto out;
|
|
}
|
|
}
|
|
spin_lock(&proc_subdir_lock);
|
|
spin_lock(&proc_subdir_lock);
|
|
filp->f_pos++;
|
|
filp->f_pos++;
|
|
next = de->next;
|
|
next = de->next;
|
|
- de_put(de);
|
|
|
|
|
|
+ pde_put(de);
|
|
de = next;
|
|
de = next;
|
|
} while (de);
|
|
} while (de);
|
|
spin_unlock(&proc_subdir_lock);
|
|
spin_unlock(&proc_subdir_lock);
|
|
@@ -763,7 +763,7 @@ out:
|
|
return NULL;
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
|
|
-void free_proc_entry(struct proc_dir_entry *de)
|
|
|
|
|
|
+static void free_proc_entry(struct proc_dir_entry *de)
|
|
{
|
|
{
|
|
unsigned int ino = de->low_ino;
|
|
unsigned int ino = de->low_ino;
|
|
|
|
|
|
@@ -777,6 +777,12 @@ void free_proc_entry(struct proc_dir_entry *de)
|
|
kfree(de);
|
|
kfree(de);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+void pde_put(struct proc_dir_entry *pde)
|
|
|
|
+{
|
|
|
|
+ if (atomic_dec_and_test(&pde->count))
|
|
|
|
+ free_proc_entry(pde);
|
|
|
|
+}
|
|
|
|
+
|
|
/*
|
|
/*
|
|
* Remove a /proc entry and free it if it's not currently in use.
|
|
* Remove a /proc entry and free it if it's not currently in use.
|
|
*/
|
|
*/
|
|
@@ -845,6 +851,5 @@ continue_removing:
|
|
WARN(de->subdir, KERN_WARNING "%s: removing non-empty directory "
|
|
WARN(de->subdir, KERN_WARNING "%s: removing non-empty directory "
|
|
"'%s/%s', leaking at least '%s'\n", __func__,
|
|
"'%s/%s', leaking at least '%s'\n", __func__,
|
|
de->parent->name, de->name, de->subdir->name);
|
|
de->parent->name, de->name, de->subdir->name);
|
|
- if (atomic_dec_and_test(&de->count))
|
|
|
|
- free_proc_entry(de);
|
|
|
|
|
|
+ pde_put(de);
|
|
}
|
|
}
|