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
22 void proc_put_inode(struct inode *inode)
23 {
24 if (inode->i_nlink)
25 return;
26 inode->i_size = 0;
27 }
28
29 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
78 struct super_block *proc_read_super(struct super_block *s,void *data,
79 int silent)
80 {
81 lock_super(s);
82 s->s_blocksize = 1024;
83 s->s_blocksize_bits = 10;
84 s->s_magic = PROC_SUPER_MAGIC;
85 s->s_op = &proc_sops;
86 unlock_super(s);
87 if (!(s->s_mounted = iget(s,PROC_ROOT_INO))) {
88 s->s_dev = 0;
89 printk("get root inode failed\n");
90 return NULL;
91 }
92 parse_options(data, &s->s_mounted->i_uid, &s->s_mounted->i_gid);
93 return s;
94 }
95
96 void proc_statfs(struct super_block *sb, struct statfs *buf)
97 {
98 put_fs_long(PROC_SUPER_MAGIC, &buf->f_type);
99 put_fs_long(PAGE_SIZE/sizeof(long), &buf->f_bsize);
100 put_fs_long(0, &buf->f_blocks);
101 put_fs_long(0, &buf->f_bfree);
102 put_fs_long(0, &buf->f_bavail);
103 put_fs_long(0, &buf->f_files);
104 put_fs_long(0, &buf->f_ffree);
105 put_fs_long(NAME_MAX, &buf->f_namelen);
106
107 }
108
109 void proc_read_inode(struct inode * inode)
110 {
111 unsigned long ino, pid;
112 struct task_struct * p;
113 int i;
114
115 inode->i_op = NULL;
116 inode->i_mode = 0;
117 inode->i_uid = 0;
118 inode->i_gid = 0;
119 inode->i_nlink = 1;
120 inode->i_size = 0;
121 inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
122 inode->i_blocks = 0;
123 inode->i_blksize = 1024;
124 ino = inode->i_ino;
125 pid = ino >> 16;
126 p = task[0];
127 for (i = 0; i < NR_TASKS ; i++)
128 if ((p = task[i]) && (p->pid == pid))
129 break;
130 if (!p || i >= NR_TASKS)
131 return;
132 if (ino == PROC_ROOT_INO) {
133 inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO;
134 inode->i_nlink = 2;
135 for (i = 1 ; i < NR_TASKS ; i++)
136 if (task[i])
137 inode->i_nlink++;
138 inode->i_op = &proc_root_inode_operations;
139 return;
140 }
141
142 #ifdef CONFIG_IP_ACCT
143
144 if (ino == PROC_NET_IPACCT) {
145 inode->i_mode = S_IFREG | S_IRUGO | S_IWUSR;
146 inode->i_op = &proc_net_inode_operations;
147 return;
148 }
149 #endif
150 #ifdef CONFIG_IP_FIREWALL
151
152 if ((ino == PROC_NET_IPFWFWD) || (ino == PROC_NET_IPFWBLK)) {
153 inode->i_mode = S_IFREG | S_IRUGO | S_IWUSR;
154 inode->i_op = &proc_net_inode_operations;
155 return;
156 }
157 #endif
158
159
160 if ((ino >= PROC_NET_UNIX) && (ino < PROC_NET_LAST)) {
161 inode->i_mode = S_IFREG | S_IRUGO;
162 inode->i_op = &proc_net_inode_operations;
163 return;
164 }
165
166 if (!pid) {
167 switch (ino) {
168 case PROC_KMSG:
169 inode->i_mode = S_IFREG | S_IRUSR;
170 inode->i_op = &proc_kmsg_inode_operations;
171 break;
172 case PROC_NET:
173 inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO;
174 inode->i_nlink = 2;
175 inode->i_op = &proc_net_inode_operations;
176 break;
177 case PROC_KCORE:
178 inode->i_mode = S_IFREG | S_IRUSR;
179 inode->i_op = &proc_kcore_inode_operations;
180 inode->i_size = high_memory + PAGE_SIZE;
181 break;
182 #ifdef CONFIG_PROFILE
183 case PROC_PROFILE:
184 inode->i_mode = S_IFREG | S_IRUGO | S_IWUSR;
185 inode->i_op = &proc_profile_inode_operations;
186 inode->i_size = (1+prof_len) * sizeof(unsigned long);
187 break;
188 #endif
189 default:
190 inode->i_mode = S_IFREG | S_IRUGO;
191 inode->i_op = &proc_array_inode_operations;
192 break;
193 }
194 return;
195 }
196 ino &= 0x0000ffff;
197 inode->i_uid = p->euid;
198 inode->i_gid = p->egid;
199 switch (ino) {
200 case PROC_PID_INO:
201 inode->i_nlink = 4;
202 inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO;
203 inode->i_op = &proc_base_inode_operations;
204 return;
205 case PROC_PID_MEM:
206 inode->i_op = &proc_mem_inode_operations;
207 inode->i_mode = S_IFREG | S_IRUSR | S_IWUSR;
208 return;
209 case PROC_PID_CWD:
210 case PROC_PID_ROOT:
211 case PROC_PID_EXE:
212 inode->i_op = &proc_link_inode_operations;
213 inode->i_size = 64;
214 inode->i_mode = S_IFLNK | S_IRWXU;
215 return;
216 case PROC_PID_FD:
217 inode->i_mode = S_IFDIR | S_IRUSR | S_IXUSR;
218 inode->i_op = &proc_fd_inode_operations;
219 inode->i_nlink = 2;
220 return;
221 case PROC_PID_ENVIRON:
222 inode->i_mode = S_IFREG | S_IRUSR;
223 inode->i_op = &proc_array_inode_operations;
224 return;
225 case PROC_PID_CMDLINE:
226 case PROC_PID_STAT:
227 case PROC_PID_STATM:
228 inode->i_mode = S_IFREG | S_IRUGO;
229 inode->i_op = &proc_array_inode_operations;
230 return;
231 case PROC_PID_MAPS:
232 inode->i_mode = S_IFIFO | S_IRUGO;
233 inode->i_op = &proc_arraylong_inode_operations;
234 return;
235 }
236 switch (ino >> 8) {
237 case PROC_PID_FD_DIR:
238 ino &= 0xff;
239 if (ino >= NR_OPEN || !p->files->fd[ino])
240 return;
241 inode->i_op = &proc_link_inode_operations;
242 inode->i_size = 64;
243 inode->i_mode = S_IFLNK;
244 if (p->files->fd[ino]->f_mode & 1)
245 inode->i_mode |= S_IRUSR | S_IXUSR;
246 if (p->files->fd[ino]->f_mode & 2)
247 inode->i_mode |= S_IWUSR | S_IXUSR;
248 return;
249 }
250 return;
251 }
252
253 void proc_write_inode(struct inode * inode)
254 {
255 inode->i_dirt=0;
256 }