2 * linux/fs/proc/inode.c
4 * Copyright (C) 1991, 1992 Linus Torvalds
7 #include <linux/sched.h>
8 #include <linux/proc_fs.h>
9 #include <linux/kernel.h>
11 #include <linux/string.h>
12 #include <linux/stat.h>
13 #include <linux/file.h>
14 #include <linux/locks.h>
15 #include <linux/limits.h>
16 #define __NO_VERSION__
17 #include <linux/module.h>
18 #include <linux/smp_lock.h>
20 #include <asm/system.h>
21 #include <asm/uaccess.h>
23 extern void free_proc_entry(struct proc_dir_entry
*);
25 struct proc_dir_entry
* de_get(struct proc_dir_entry
*de
)
28 atomic_inc(&de
->count
);
33 * Decrements the use count and checks for deferred deletion.
35 void de_put(struct proc_dir_entry
*de
)
39 if (!atomic_read(&de
->count
)) {
40 printk("de_put: entry %s already free!\n", de
->name
);
45 if (atomic_dec_and_test(&de
->count
)) {
47 printk("de_put: deferred delete of %s\n",
57 * Decrement the use count of the proc_dir_entry.
59 static void proc_delete_inode(struct inode
*inode
)
61 struct proc_dir_entry
*de
= inode
->u
.generic_ip
;
63 inode
->i_state
= I_CLEAR
;
65 if (PROC_INODE_PROPER(inode
)) {
66 proc_pid_delete_inode(inode
);
71 __MOD_DEC_USE_COUNT(de
->owner
);
76 struct vfsmount
*proc_mnt
;
78 static void proc_read_inode(struct inode
* inode
)
80 inode
->i_mtime
= inode
->i_atime
= inode
->i_ctime
= CURRENT_TIME
;
83 static int proc_statfs(struct super_block
*sb
, struct statfs
*buf
)
85 buf
->f_type
= PROC_SUPER_MAGIC
;
86 buf
->f_bsize
= PAGE_SIZE
/sizeof(long);
90 buf
->f_namelen
= NAME_MAX
;
94 static struct super_operations proc_sops
= {
95 read_inode
: proc_read_inode
,
96 put_inode
: force_delete
,
97 delete_inode
: proc_delete_inode
,
102 static int parse_options(char *options
,uid_t
*uid
,gid_t
*gid
)
104 char *this_char
,*value
;
108 if (!options
) return 1;
109 for (this_char
= strtok(options
,","); this_char
; this_char
= strtok(NULL
,",")) {
110 if ((value
= strchr(this_char
,'=')) != NULL
)
112 if (!strcmp(this_char
,"uid")) {
113 if (!value
|| !*value
)
115 *uid
= simple_strtoul(value
,&value
,0);
119 else if (!strcmp(this_char
,"gid")) {
120 if (!value
|| !*value
)
122 *gid
= simple_strtoul(value
,&value
,0);
131 struct inode
* proc_get_inode(struct super_block
* sb
, int ino
,
132 struct proc_dir_entry
* de
)
134 struct inode
* inode
;
137 * Increment the use count so the dir entry can't disappear.
141 /* shouldn't ever happen */
142 if (de
&& de
->deleted
)
143 printk("proc_iget: using deleted entry %s, count=%d\n", de
->name
, atomic_read(&de
->count
));
146 inode
= iget(sb
, ino
);
150 inode
->u
.generic_ip
= (void *) de
;
153 inode
->i_mode
= de
->mode
;
154 inode
->i_uid
= de
->uid
;
155 inode
->i_gid
= de
->gid
;
158 inode
->i_size
= de
->size
;
160 inode
->i_nlink
= de
->nlink
;
162 __MOD_INC_USE_COUNT(de
->owner
);
163 if (S_ISBLK(de
->mode
)||S_ISCHR(de
->mode
)||S_ISFIFO(de
->mode
))
164 init_special_inode(inode
,de
->mode
,kdev_t_to_nr(de
->rdev
));
167 inode
->i_op
= de
->proc_iops
;
169 inode
->i_fop
= de
->proc_fops
;
181 struct super_block
*proc_read_super(struct super_block
*s
,void *data
,
184 struct inode
* root_inode
;
185 struct task_struct
*p
;
187 s
->s_blocksize
= 1024;
188 s
->s_blocksize_bits
= 10;
189 s
->s_magic
= PROC_SUPER_MAGIC
;
190 s
->s_op
= &proc_sops
;
191 root_inode
= proc_get_inode(s
, PROC_ROOT_INO
, &proc_root
);
195 * Fixup the root inode's nlink value
197 read_lock(&tasklist_lock
);
198 for_each_task(p
) if (p
->pid
) root_inode
->i_nlink
++;
199 read_unlock(&tasklist_lock
);
200 s
->s_root
= d_alloc_root(root_inode
);
203 parse_options(data
, &root_inode
->i_uid
, &root_inode
->i_gid
);
207 printk("proc_read_super: get root inode failed\n");