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