This source file includes following definitions.
- proc_put_inode
- proc_put_super
- parse_options
- proc_get_inode
- proc_read_super
- proc_statfs
- proc_read_inode
- proc_write_inode
1
2
3
4
5
6
7 #include <linux/sched.h>
8 #include <linux/proc_fs.h>
9 #include <linux/kernel.h>
10 #include <linux/mm.h>
11 #include <linux/string.h>
12 #include <linux/stat.h>
13 #include <linux/locks.h>
14 #include <linux/limits.h>
15 #include <linux/config.h>
16
17 #include <asm/system.h>
18 #include <asm/segment.h>
19
20 extern unsigned long prof_len;
21
22 static void proc_put_inode(struct inode *inode)
23 {
24 if (inode->i_nlink)
25 return;
26 inode->i_size = 0;
27 }
28
29 static void proc_put_super(struct super_block *sb)
30 {
31 lock_super(sb);
32 sb->s_dev = 0;
33 unlock_super(sb);
34 }
35
36 static struct super_operations proc_sops = {
37 proc_read_inode,
38 NULL,
39 proc_write_inode,
40 proc_put_inode,
41 proc_put_super,
42 NULL,
43 proc_statfs,
44 NULL
45 };
46
47
48 static int parse_options(char *options,uid_t *uid,gid_t *gid)
49 {
50 char *this_char,*value;
51
52 *uid = current->uid;
53 *gid = current->gid;
54 if (!options) return 1;
55 for (this_char = strtok(options,","); this_char; this_char = strtok(NULL,",")) {
56 if ((value = strchr(this_char,'=')) != NULL)
57 *value++ = 0;
58 if (!strcmp(this_char,"uid")) {
59 if (!value || !*value)
60 return 0;
61 *uid = simple_strtoul(value,&value,0);
62 if (*value)
63 return 0;
64 }
65 else if (!strcmp(this_char,"gid")) {
66 if (!value || !*value)
67 return 0;
68 *gid = simple_strtoul(value,&value,0);
69 if (*value)
70 return 0;
71 }
72 else return 0;
73 }
74 return 1;
75 }
76
77 struct inode * proc_get_inode(struct super_block * s, int ino, struct proc_dir_entry * de)
78 {
79 struct inode * inode = iget(s, ino);
80 if (inode) {
81 inode->u.generic_ip = (void *) de;
82 if (de) {
83 if (de->mode) {
84 inode->i_mode = de->mode;
85 inode->i_uid = de->uid;
86 inode->i_gid = de->gid;
87 }
88 if (de->size)
89 inode->i_size = de->size;
90 if (de->ops)
91 inode->i_op = de->ops;
92 if (de->nlink)
93 inode->i_nlink = de->nlink;
94 if (de->fill_inode)
95 de->fill_inode(inode);
96 }
97 }
98 return inode;
99 }
100
101 struct super_block *proc_read_super(struct super_block *s,void *data,
102 int silent)
103 {
104 proc_root_init();
105 lock_super(s);
106 s->s_blocksize = 1024;
107 s->s_blocksize_bits = 10;
108 s->s_magic = PROC_SUPER_MAGIC;
109 s->s_op = &proc_sops;
110 unlock_super(s);
111 if (!(s->s_mounted = proc_get_inode(s, PROC_ROOT_INO, &proc_root))) {
112 s->s_dev = 0;
113 printk("get root inode failed\n");
114 return NULL;
115 }
116 parse_options(data, &s->s_mounted->i_uid, &s->s_mounted->i_gid);
117 return s;
118 }
119
120 void proc_statfs(struct super_block *sb, struct statfs *buf, int bufsiz)
121 {
122 struct statfs tmp;
123
124 tmp.f_type = PROC_SUPER_MAGIC;
125 tmp.f_bsize = PAGE_SIZE/sizeof(long);
126 tmp.f_blocks = 0;
127 tmp.f_bfree = 0;
128 tmp.f_bavail = 0;
129 tmp.f_files = 0;
130 tmp.f_ffree = 0;
131 tmp.f_namelen = NAME_MAX;
132 memcpy_tofs(buf, &tmp, bufsiz);
133 }
134
135 void proc_read_inode(struct inode * inode)
136 {
137 unsigned long ino, pid;
138 struct task_struct * p;
139 int i;
140
141 inode->i_op = NULL;
142 inode->i_mode = 0;
143 inode->i_uid = 0;
144 inode->i_gid = 0;
145 inode->i_nlink = 1;
146 inode->i_size = 0;
147 inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
148 inode->i_blocks = 0;
149 inode->i_blksize = 1024;
150 ino = inode->i_ino;
151 pid = ino >> 16;
152 p = task[0];
153 for (i = 0; i < NR_TASKS ; i++)
154 if ((p = task[i]) && (p->pid == pid))
155 break;
156 if (!p || i >= NR_TASKS)
157 return;
158 if (ino == PROC_ROOT_INO) {
159 inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO;
160 inode->i_nlink = 2;
161 for (i = 1 ; i < NR_TASKS ; i++)
162 if (task[i])
163 inode->i_nlink++;
164 return;
165 }
166
167 if (ino == PROC_SCSI_SCSI) {
168 inode->i_mode = S_IFREG | S_IRUGO | S_IWUSR;
169 inode->i_op = &proc_scsi_inode_operations;
170 return;
171 }
172
173
174
175 if (ino == PROC_SCSI_NOT_PRESENT) {
176 inode->i_mode = S_IFREG | S_IRUGO | S_IXUGO;
177 inode->i_op = &proc_scsi_inode_operations;
178 return;
179 }
180
181
182 if ((ino > PROC_SCSI_SCSI) && (ino < PROC_SCSI_FILE)) {
183 inode->i_nlink = 2;
184 inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO;
185 inode->i_op = &proc_scsi_inode_operations;
186 return;
187 }
188
189
190 if ((ino >= PROC_SCSI_FILE) && (ino <= PROC_SCSI_LAST)) {
191 inode->i_mode = S_IFREG | S_IRUGO | S_IWUSR;
192 inode->i_op = &proc_scsi_inode_operations;
193 return;
194 }
195
196 if (!pid) {
197 switch (ino) {
198 case PROC_KMSG:
199 inode->i_mode = S_IFREG | S_IRUSR;
200 inode->i_op = &proc_kmsg_inode_operations;
201 break;
202 case PROC_NET:
203 inode->i_nlink = 2;
204 break;
205 case PROC_SCSI:
206 inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO;
207 inode->i_nlink = 2;
208 inode->i_op = &proc_scsi_inode_operations;
209 break;
210 case PROC_KCORE:
211 inode->i_mode = S_IFREG | S_IRUSR;
212 inode->i_op = &proc_kcore_inode_operations;
213 inode->i_size = (MAP_NR(high_memory) << PAGE_SHIFT) + PAGE_SIZE;
214 break;
215 #ifdef CONFIG_PROFILE
216 case PROC_PROFILE:
217 inode->i_mode = S_IFREG | S_IRUGO | S_IWUSR;
218 inode->i_op = &proc_profile_inode_operations;
219 inode->i_size = (1+prof_len) * sizeof(unsigned long);
220 break;
221 #endif
222 default:
223 inode->i_mode = S_IFREG | S_IRUGO;
224 inode->i_op = &proc_array_inode_operations;
225 break;
226 }
227 return;
228 }
229 ino &= 0x0000ffff;
230 if (ino == PROC_PID_INO || p->dumpable) {
231 inode->i_uid = p->euid;
232 inode->i_gid = p->egid;
233 }
234 switch (ino) {
235 case PROC_PID_INO:
236 inode->i_nlink = 4;
237 return;
238 case PROC_PID_MEM:
239 inode->i_op = &proc_mem_inode_operations;
240 inode->i_mode = S_IFREG | S_IRUSR | S_IWUSR;
241 return;
242 case PROC_PID_CWD:
243 case PROC_PID_ROOT:
244 case PROC_PID_EXE:
245 inode->i_op = &proc_link_inode_operations;
246 inode->i_size = 64;
247 inode->i_mode = S_IFLNK | S_IRWXU;
248 return;
249 case PROC_PID_FD:
250 inode->i_mode = S_IFDIR | S_IRUSR | S_IXUSR;
251 inode->i_op = &proc_fd_inode_operations;
252 inode->i_nlink = 2;
253 return;
254 case PROC_PID_ENVIRON:
255 inode->i_mode = S_IFREG | S_IRUSR;
256 inode->i_op = &proc_array_inode_operations;
257 return;
258 case PROC_PID_CMDLINE:
259 case PROC_PID_STAT:
260 case PROC_PID_STATM:
261 inode->i_mode = S_IFREG | S_IRUGO;
262 inode->i_op = &proc_array_inode_operations;
263 return;
264 case PROC_PID_MAPS:
265 inode->i_mode = S_IFIFO | S_IRUGO;
266 inode->i_op = &proc_arraylong_inode_operations;
267 return;
268 }
269 switch (ino >> 8) {
270 case PROC_PID_FD_DIR:
271 ino &= 0xff;
272 if (ino >= NR_OPEN || !p->files->fd[ino])
273 return;
274 inode->i_op = &proc_link_inode_operations;
275 inode->i_size = 64;
276 inode->i_mode = S_IFLNK;
277 if (p->files->fd[ino]->f_mode & 1)
278 inode->i_mode |= S_IRUSR | S_IXUSR;
279 if (p->files->fd[ino]->f_mode & 2)
280 inode->i_mode |= S_IWUSR | S_IXUSR;
281 return;
282 }
283 return;
284 }
285
286 void proc_write_inode(struct inode * inode)
287 {
288 inode->i_dirt=0;
289 }