#include <asm/system.h>
#include <asm/uaccess.h>
-extern void free_proc_entry(struct proc_dir_entry *);
+#include "internal.h"
static inline struct proc_dir_entry * de_get(struct proc_dir_entry *de)
{
static void proc_delete_inode(struct inode *inode)
{
struct proc_dir_entry *de;
- struct task_struct *tsk;
- /* Let go of any associated process */
- tsk = PROC_I(inode)->task;
- if (tsk)
- put_task_struct(tsk);
+ truncate_inode_pages(&inode->i_data, 0);
+
+ /* Stop tracking associated processes */
+ put_pid(PROC_I(inode)->pid);
/* Let go of any associated proc directory entry */
de = PROC_I(inode)->pde;
inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
}
-static kmem_cache_t * proc_inode_cachep;
+static struct kmem_cache * proc_inode_cachep;
static struct inode *proc_alloc_inode(struct super_block *sb)
{
struct proc_inode *ei;
struct inode *inode;
- ei = (struct proc_inode *)kmem_cache_alloc(proc_inode_cachep, SLAB_KERNEL);
+ ei = (struct proc_inode *)kmem_cache_alloc(proc_inode_cachep, GFP_KERNEL);
if (!ei)
return NULL;
- ei->task = NULL;
- ei->type = 0;
+ ei->pid = NULL;
+ ei->fd = 0;
ei->op.proc_get_link = NULL;
ei->pde = NULL;
inode = &ei->vfs_inode;
kmem_cache_free(proc_inode_cachep, PROC_I(inode));
}
-static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags)
+static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags)
{
struct proc_inode *ei = (struct proc_inode *) foo;
{
proc_inode_cachep = kmem_cache_create("proc_inode_cache",
sizeof(struct proc_inode),
- 0, SLAB_RECLAIM_ACCOUNT,
+ 0, (SLAB_RECLAIM_ACCOUNT|
+ SLAB_MEM_SPREAD),
init_once, NULL);
if (proc_inode_cachep == NULL)
return -ENOMEM;
WARN_ON(de && de->deleted);
+ if (de != NULL && !try_module_get(de->owner))
+ goto out_mod;
+
inode = iget(sb, ino);
if (!inode)
- goto out_fail;
-
+ goto out_ino;
+
PROC_I(inode)->pde = de;
if (de) {
if (de->mode) {
inode->i_size = de->size;
if (de->nlink)
inode->i_nlink = de->nlink;
- if (!try_module_get(de->owner))
- goto out_fail;
if (de->proc_iops)
inode->i_op = de->proc_iops;
if (de->proc_fops)
inode->i_fop = de->proc_fops;
}
-out:
return inode;
-out_fail:
+out_ino:
+ if (de != NULL)
+ module_put(de->owner);
+out_mod:
de_put(de);
- goto out;
+ return NULL;
}
int proc_fill_super(struct super_block *s, void *data, int silent)
{
struct inode * root_inode;
- s->s_flags |= MS_NODIRATIME;
+ s->s_flags |= MS_NODIRATIME | MS_NOSUID | MS_NOEXEC;
s->s_blocksize = 1024;
s->s_blocksize_bits = 10;
s->s_magic = PROC_SUPER_MAGIC;
root_inode = proc_get_inode(s, PROC_ROOT_INO, &proc_root);
if (!root_inode)
goto out_no_root;
- /*
- * Fixup the root inode's nlink value
- */
- root_inode->i_nlink += nr_processes();
root_inode->i_uid = 0;
root_inode->i_gid = 0;
s->s_root = d_alloc_root(root_inode);