X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=fs%2Fproc%2Finode.c;h=5b0367f6845a365c7e54c4ce36cd238e205bfdbe;hb=refs%2Fheads%2Fvserver;hp=b4d3e54809c27843e1a9008f4dd215a82176ce6c;hpb=c7b5ebbddf7bcd3651947760f423e3783bbe6573;p=linux-2.6.git diff --git a/fs/proc/inode.c b/fs/proc/inode.c index b4d3e5480..5b0367f68 100644 --- a/fs/proc/inode.c +++ b/fs/proc/inode.c @@ -14,13 +14,12 @@ #include #include #include -#include #include #include #include -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) { @@ -59,12 +58,11 @@ static void de_put(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; @@ -83,18 +81,18 @@ static void proc_read_inode(struct inode * inode) 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; @@ -107,7 +105,7 @@ static void proc_destroy_inode(struct inode *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; @@ -120,7 +118,8 @@ int __init proc_init_inodecache(void) { 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; @@ -143,51 +142,6 @@ static struct super_operations proc_sops = { .remount_fs = proc_remount, }; -enum { - Opt_uid, Opt_gid, Opt_err -}; - -static match_table_t tokens = { - {Opt_uid, "uid=%u"}, - {Opt_gid, "gid=%u"}, - {Opt_err, NULL} -}; - -static int parse_options(char *options,uid_t *uid,gid_t *gid) -{ - char *p; - int option; - - *uid = current->uid; - *gid = current->gid; - if (!options) - return 1; - - while ((p = strsep(&options, ",")) != NULL) { - substring_t args[MAX_OPT_ARGS]; - int token; - if (!*p) - continue; - - token = match_token(p, tokens, args); - switch (token) { - case Opt_uid: - if (match_int(args, &option)) - return 0; - *uid = option; - break; - case Opt_gid: - if (match_int(args, &option)) - return 0; - *gid = option; - break; - default: - return 0; - } - } - return 1; -} - struct inode *proc_get_inode(struct super_block *sb, unsigned int ino, struct proc_dir_entry *de) { @@ -200,10 +154,13 @@ struct inode *proc_get_inode(struct super_block *sb, unsigned int ino, 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) { @@ -217,43 +174,41 @@ struct inode *proc_get_inode(struct super_block *sb, unsigned int ino, 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; s->s_op = &proc_sops; + s->s_time_gran = 1; 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); if (!s->s_root) goto out_no_root; - parse_options(data, &root_inode->i_uid, &root_inode->i_gid); return 0; out_no_root: