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