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 1;
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 (!pid) {
166 switch (ino) {
167 case PROC_KMSG:
168 inode->i_mode = S_IFREG | S_IRUSR;
169 inode->i_op = &proc_kmsg_inode_operations;
170 break;
171 case PROC_NET:
172 inode->i_nlink = 2;
173 break;
174 #ifdef CONFIG_SCSI
175 case PROC_SCSI:
176 inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO;
177 inode->i_nlink = 2;
178 inode->i_op = &proc_scsi_inode_operations;
179 break;
180 #endif
181 case PROC_KCORE:
182 inode->i_mode = S_IFREG | S_IRUSR;
183 inode->i_op = &proc_kcore_inode_operations;
184 inode->i_size = (MAP_NR(high_memory) << PAGE_SHIFT) + PAGE_SIZE;
185 break;
186 case PROC_PROFILE:
187 inode->i_mode = S_IFREG | S_IRUGO | S_IWUSR;
188 inode->i_op = &proc_profile_inode_operations;
189 inode->i_size = (1+prof_len) * sizeof(unsigned long);
190 break;
191 default:
192 inode->i_mode = S_IFREG | S_IRUGO;
193 inode->i_op = &proc_array_inode_operations;
194 break;
195 }
196 return;
197 }
198 ino &= 0x0000ffff;
199 if (ino == PROC_PID_INO || p->dumpable) {
200 inode->i_uid = p->euid;
201 inode->i_gid = p->egid;
202 }
203 switch (ino) {
204 case PROC_PID_INO:
205 inode->i_nlink = 4;
206 return;
207 case PROC_PID_MEM:
208 inode->i_op = &proc_mem_inode_operations;
209 inode->i_mode = S_IFREG | S_IRUSR | S_IWUSR;
210 return;
211 case PROC_PID_CWD:
212 case PROC_PID_ROOT:
213 case PROC_PID_EXE:
214 inode->i_op = &proc_link_inode_operations;
215 inode->i_size = 64;
216 inode->i_mode = S_IFLNK | S_IRWXU;
217 return;
218 case PROC_PID_FD:
219 inode->i_mode = S_IFDIR | S_IRUSR | S_IXUSR;
220 inode->i_op = &proc_fd_inode_operations;
221 inode->i_nlink = 2;
222 return;
223 case PROC_PID_ENVIRON:
224 inode->i_mode = S_IFREG | S_IRUSR;
225 inode->i_op = &proc_array_inode_operations;
226 return;
227 case PROC_PID_CMDLINE:
228 case PROC_PID_STAT:
229 case PROC_PID_STATM:
230 inode->i_mode = S_IFREG | S_IRUGO;
231 inode->i_op = &proc_array_inode_operations;
232 return;
233 case PROC_PID_MAPS:
234 inode->i_mode = S_IFIFO | S_IRUGO;
235 inode->i_op = &proc_arraylong_inode_operations;
236 return;
237 }
238 switch (ino >> 8) {
239 case PROC_PID_FD_DIR:
240 ino &= 0xff;
241 if (ino >= NR_OPEN || !p->files->fd[ino])
242 return;
243 inode->i_op = &proc_link_inode_operations;
244 inode->i_size = 64;
245 inode->i_mode = S_IFLNK;
246 if (p->files->fd[ino]->f_mode & 1)
247 inode->i_mode |= S_IRUSR | S_IXUSR;
248 if (p->files->fd[ino]->f_mode & 2)
249 inode->i_mode |= S_IWUSR | S_IXUSR;
250 return;
251 }
252 return;
253 }
254
255 void proc_write_inode(struct inode * inode)
256 {
257 inode->i_dirt=0;
258 }