1 /*
2 * proc/fs/generic.c --- generic routines for the proc-fs
3 *
4 * This file contains generic proc-fs routines for handling
5 * directories and files.
6 *
7 * Copyright (C) 1991, 1992 Linus Torvalds.
8 * Copyright (C) 1997 Theodore Ts'o
9 */
10
11 #include <asm/uaccess.h>
12
13 #include <linux/errno.h>
14 #include <linux/sched.h>
15 #include <linux/proc_fs.h>
16 #include <linux/stat.h>
17 #define __NO_VERSION__
18 #include <linux/module.h>
19 #include <asm/bitops.h>
20
21 static ssize_t proc_file_read(struct file * file, char * buf,
22 size_t nbytes, loff_t *ppos);
23 static ssize_t proc_file_write(struct file * file, const char * buffer,
24 size_t count, loff_t *ppos);
25 static loff_t proc_file_lseek(struct file *, loff_t, int);
26
27 int proc_match(int len, const char *name,struct proc_dir_entry * de)
28 {
29 if (!de || !de->low_ino)
30 return 0;
31 if (de->namelen != len)
32 return 0;
33 return !memcmp(name, de->name, len);
34 }
35
36 static struct file_operations proc_file_operations = {
37 llseek: proc_file_lseek,
38 read: proc_file_read,
39 write: proc_file_write,
40 };
41
42 #ifndef MIN
43 #define MIN(a,b) (((a) < (b)) ? (a) : (b))
44 #endif
45
46 /* buffer size is one page but our output routines use some slack for overruns */
47 #define PROC_BLOCK_SIZE (PAGE_SIZE - 1024)
48
49 static ssize_t
50 proc_file_read(struct file * file, char * buf, size_t nbytes, loff_t *ppos)
51 {
52 struct inode * inode = file->f_dentry->d_inode;
53 char *page;
54 ssize_t retval=0;
55 int eof=0;
56 ssize_t n, count;
57 char *start;
58 struct proc_dir_entry * dp;
59
60 dp = (struct proc_dir_entry *) inode->u.generic_ip;
61 if (!(page = (char*) __get_free_page(GFP_KERNEL)))
62 return -ENOMEM;
63
64 while ((nbytes > 0) && !eof)
65 {
66 count = MIN(PROC_BLOCK_SIZE, nbytes);
67
68 start = NULL;
69 if (dp->get_info) {
70 /*
71 * Handle backwards compatibility with the old net
72 * routines.
73 */
74 n = dp->get_info(page, &start, *ppos, count);
75 if (n < count)
76 eof = 1;
77 } else if (dp->read_proc) {
78 n = dp->read_proc(page, &start, *ppos,
79 count, &eof, dp->data);
80 } else
81 break;
82
83 if (!start) {
84 /*
85 * For proc files that are less than 4k
86 */
87 start = page + *ppos;
88 n -= *ppos;
89 if (n <= 0)
90 break;
91 if (n > count)
92 n = count;
93 }
94 if (n == 0)
95 break; /* End of file */
96 if (n < 0) {
97 if (retval == 0)
98 retval = n;
99 break;
100 }
101
102 /* This is a hack to allow mangling of file pos independent
103 * of actual bytes read. Simply place the data at page,
104 * return the bytes, and set `start' to the desired offset
105 * as an unsigned int. - Paul.Russell@rustcorp.com.au
106 */
107 n -= copy_to_user(buf, start < page ? page : start, n);
108 if (n == 0) {
109 if (retval == 0)
110 retval = -EFAULT;
111 break;
112 }
113
114 *ppos += start < page ? (long)start : n; /* Move down the file */
115 nbytes -= n;
116 buf += n;
117 retval += n;
118 }
119 free_page((unsigned long) page);
120 return retval;
121 }
122
123 static ssize_t
124 proc_file_write(struct file * file, const char * buffer,
125 size_t count, loff_t *ppos)
126 {
127 struct inode *inode = file->f_dentry->d_inode;
128 struct proc_dir_entry * dp;
129
130 dp = (struct proc_dir_entry *) inode->u.generic_ip;
131
132 if (!dp->write_proc)
133 return -EIO;
134
135 /* FIXME: does this routine need ppos? probably... */
136 return dp->write_proc(file, buffer, count, dp->data);
137 }
138
139
140 static loff_t
141 proc_file_lseek(struct file * file, loff_t offset, int orig)
142 {
143 switch (orig) {
144 case 0:
145 if (offset < 0)
146 return -EINVAL;
147 file->f_pos = offset;
148 return(file->f_pos);
149 case 1:
150 if (offset + file->f_pos < 0)
151 return -EINVAL;
152 file->f_pos += offset;
153 return(file->f_pos);
154 case 2:
155 return(-EINVAL);
156 default:
157 return(-EINVAL);
158 }
159 }
160
161 /*
162 * This function parses a name such as "tty/driver/serial", and
163 * returns the struct proc_dir_entry for "/proc/tty/driver", and
164 * returns "serial" in residual.
165 */
166 static int xlate_proc_name(const char *name,
167 struct proc_dir_entry **ret, const char **residual)
168 {
169 const char *cp = name, *next;
170 struct proc_dir_entry *de;
171 int len;
172
173 de = &proc_root;
174 while (1) {
175 next = strchr(cp, '/');
176 if (!next)
177 break;
178
179 len = next - cp;
180 for (de = de->subdir; de ; de = de->next) {
181 if (proc_match(len, cp, de))
182 break;
183 }
184 if (!de)
185 return -ENOENT;
186 cp += len + 1;
187 }
188 *residual = cp;
189 *ret = de;
190 return 0;
191 }
192
193 static unsigned char proc_alloc_map[PROC_NDYNAMIC / 8];
194
195 static int make_inode_number(void)
196 {
197 int i = find_first_zero_bit((void *) proc_alloc_map, PROC_NDYNAMIC);
198 if (i<0 || i>=PROC_NDYNAMIC)
199 return -1;
200 set_bit(i, (void *) proc_alloc_map);
201 return PROC_DYNAMIC_FIRST + i;
202 }
203
204 static int proc_readlink(struct dentry *dentry, char *buffer, int buflen)
205 {
206 char *s=((struct proc_dir_entry *)dentry->d_inode->u.generic_ip)->data;
207 return vfs_readlink(dentry, buffer, buflen, s);
208 }
209
210 static int proc_follow_link(struct dentry *dentry, struct nameidata *nd)
211 {
212 char *s=((struct proc_dir_entry *)dentry->d_inode->u.generic_ip)->data;
213 return vfs_follow_link(nd, s);
214 }
215
216 static struct inode_operations proc_link_inode_operations = {
217 readlink: proc_readlink,
218 follow_link: proc_follow_link,
219 };
220
221 /*
222 * As some entries in /proc are volatile, we want to
223 * get rid of unused dentries. This could be made
224 * smarter: we could keep a "volatile" flag in the
225 * inode to indicate which ones to keep.
226 */
227 static int proc_delete_dentry(struct dentry * dentry)
228 {
229 return 1;
230 }
231
232 static struct dentry_operations proc_dentry_operations =
233 {
234 d_delete: proc_delete_dentry,
235 };
236
237 /*
238 * Don't create negative dentries here, return -ENOENT by hand
239 * instead.
240 */
241 struct dentry *proc_lookup(struct inode * dir, struct dentry *dentry)
242 {
243 struct inode *inode;
244 struct proc_dir_entry * de;
245 int error;
246
247 error = -ENOENT;
248 inode = NULL;
249 de = (struct proc_dir_entry *) dir->u.generic_ip;
250 if (de) {
251 for (de = de->subdir; de ; de = de->next) {
252 if (!de || !de->low_ino)
253 continue;
254 if (de->namelen != dentry->d_name.len)
255 continue;
256 if (!memcmp(dentry->d_name.name, de->name, de->namelen)) {
257 int ino = de->low_ino;
258 error = -EINVAL;
259 inode = proc_get_inode(dir->i_sb, ino, de);
260 break;
261 }
262 }
263 }
264
265 if (inode) {
266 dentry->d_op = &proc_dentry_operations;
267 d_add(dentry, inode);
268 return NULL;
269 }
270 return ERR_PTR(error);
271 }
272
273 /*
274 * This returns non-zero if at EOF, so that the /proc
275 * root directory can use this and check if it should
276 * continue with the <pid> entries..
277 *
278 * Note that the VFS-layer doesn't care about the return
279 * value of the readdir() call, as long as it's non-negative
280 * for success..
281 */
282 int proc_readdir(struct file * filp,
283 void * dirent, filldir_t filldir)
284 {
285 struct proc_dir_entry * de;
286 unsigned int ino;
287 int i;
288 struct inode *inode = filp->f_dentry->d_inode;
289
290 ino = inode->i_ino;
291 de = (struct proc_dir_entry *) inode->u.generic_ip;
292 if (!de)
293 return -EINVAL;
294 i = filp->f_pos;
295 switch (i) {
296 case 0:
297 if (filldir(dirent, ".", 1, i, ino, DT_DIR) < 0)
298 return 0;
299 i++;
300 filp->f_pos++;
301 /* fall through */
302 case 1:
303 if (filldir(dirent, "..", 2, i,
304 filp->f_dentry->d_parent->d_inode->i_ino,
305 DT_DIR) < 0)
306 return 0;
307 i++;
308 filp->f_pos++;
309 /* fall through */
310 default:
311 de = de->subdir;
312 i -= 2;
313 for (;;) {
314 if (!de)
315 return 1;
316 if (!i)
317 break;
318 de = de->next;
319 i--;
320 }
321
322 do {
323 if (filldir(dirent, de->name, de->namelen, filp->f_pos,
324 de->low_ino, de->mode >> 12) < 0)
325 return 0;
326 filp->f_pos++;
327 de = de->next;
328 } while (de);
329 }
330 return 1;
331 }
332
333 /*
334 * These are the generic /proc directory operations. They
335 * use the in-memory "struct proc_dir_entry" tree to parse
336 * the /proc directory.
337 */
338 static struct file_operations proc_dir_operations = {
339 read: generic_read_dir,
340 readdir: proc_readdir,
341 };
342
343 /*
344 * proc directories can do almost nothing..
345 */
346 static struct inode_operations proc_dir_inode_operations = {
347 lookup: proc_lookup,
348 };
349
350 static int proc_register(struct proc_dir_entry * dir, struct proc_dir_entry * dp)
351 {
352 int i;
353
354 i = make_inode_number();
355 if (i < 0)
356 return -EAGAIN;
357 dp->low_ino = i;
358 dp->next = dir->subdir;
359 dp->parent = dir;
360 dir->subdir = dp;
361 if (S_ISDIR(dp->mode)) {
362 if (dp->proc_iops == NULL) {
363 dp->proc_fops = &proc_dir_operations;
364 dp->proc_iops = &proc_dir_inode_operations;
365 }
366 dir->nlink++;
367 } else if (S_ISLNK(dp->mode)) {
368 if (dp->proc_iops == NULL)
369 dp->proc_iops = &proc_link_inode_operations;
370 } else if (S_ISREG(dp->mode)) {
371 if (dp->proc_fops == NULL)
372 dp->proc_fops = &proc_file_operations;
373 }
374 return 0;
375 }
376
377 /*
378 * Kill an inode that got unregistered..
379 */
380 static void proc_kill_inodes(struct proc_dir_entry *de)
381 {
382 struct list_head *p;
383 struct super_block *sb = proc_mnt->mnt_sb;
384
385 /*
386 * Actually it's a partial revoke().
387 */
388 file_list_lock();
389 for (p = sb->s_files.next; p != &sb->s_files; p = p->next) {
390 struct file * filp = list_entry(p, struct file, f_list);
391 struct dentry * dentry;
392 struct inode * inode;
393
394 dentry = filp->f_dentry;
395 if (!dentry)
396 continue;
397 if (dentry->d_op != &proc_dentry_operations)
398 continue;
399 inode = dentry->d_inode;
400 if (inode->u.generic_ip != de)
401 continue;
402 fops_put(filp->f_op);
403 filp->f_op = NULL;
404 }
405 file_list_unlock();
406 }
407
408 struct proc_dir_entry *proc_symlink(const char *name,
409 struct proc_dir_entry *parent, const char *dest)
410 {
411 struct proc_dir_entry *ent = NULL;
412 const char *fn = name;
413 int len;
414
415 if (!parent && xlate_proc_name(name, &parent, &fn) != 0)
416 goto out;
417 len = strlen(fn);
418
419 ent = kmalloc(sizeof(struct proc_dir_entry) + len + 1, GFP_KERNEL);
420 if (!ent)
421 goto out;
422 memset(ent, 0, sizeof(struct proc_dir_entry));
423 memcpy(((char *) ent) + sizeof(*ent), fn, len + 1);
424 ent->name = ((char *) ent) + sizeof(*ent);
425 ent->namelen = len;
426 ent->nlink = 1;
427 ent->mode = S_IFLNK|S_IRUGO|S_IWUGO|S_IXUGO;
428 ent->data = kmalloc((ent->size=strlen(dest))+1, GFP_KERNEL);
429 if (!ent->data) {
430 kfree(ent);
431 goto out;
432 }
433 strcpy((char*)ent->data,dest);
434
435 proc_register(parent, ent);
436
437 out:
438 return ent;
439 }
440
441 struct proc_dir_entry *proc_mknod(const char *name, mode_t mode,
442 struct proc_dir_entry *parent, kdev_t rdev)
443 {
444 struct proc_dir_entry *ent = NULL;
445 const char *fn = name;
446 int len;
447
448 if (!parent && xlate_proc_name(name, &parent, &fn) != 0)
449 goto out;
450 len = strlen(fn);
451
452 ent = kmalloc(sizeof(struct proc_dir_entry) + len + 1, GFP_KERNEL);
453 if (!ent)
454 goto out;
455 memset(ent, 0, sizeof(struct proc_dir_entry));
456 memcpy(((char *) ent) + sizeof(*ent), fn, len + 1);
457 ent->name = ((char *) ent) + sizeof(*ent);
458 ent->namelen = len;
459 ent->nlink = 1;
460 ent->mode = mode;
461 ent->rdev = rdev;
462
463 proc_register(parent, ent);
464
465 out:
466 return ent;
467 }
468
469 struct proc_dir_entry *proc_mkdir(const char *name, struct proc_dir_entry *parent)
470 {
471 struct proc_dir_entry *ent = NULL;
472 const char *fn = name;
473 int len;
474
475 if (!parent && xlate_proc_name(name, &parent, &fn) != 0)
476 goto out;
477 len = strlen(fn);
478
479 ent = kmalloc(sizeof(struct proc_dir_entry) + len + 1, GFP_KERNEL);
480 if (!ent)
481 goto out;
482 memset(ent, 0, sizeof(struct proc_dir_entry));
483 memcpy(((char *) ent) + sizeof(*ent), fn, len + 1);
484 ent->name = ((char *) ent) + sizeof(*ent);
485 ent->namelen = len;
486 ent->proc_fops = &proc_dir_operations;
487 ent->proc_iops = &proc_dir_inode_operations;
488 ent->nlink = 2;
489 ent->mode = S_IFDIR | S_IRUGO | S_IXUGO;
490
491 proc_register(parent, ent);
492
493 out:
494 return ent;
495 }
496
497 struct proc_dir_entry *create_proc_entry(const char *name, mode_t mode,
498 struct proc_dir_entry *parent)
499 {
500 struct proc_dir_entry *ent = NULL;
501 const char *fn = name;
502 int len;
503
504 if (!parent && xlate_proc_name(name, &parent, &fn) != 0)
505 goto out;
506 len = strlen(fn);
507
508 ent = kmalloc(sizeof(struct proc_dir_entry) + len + 1, GFP_KERNEL);
509 if (!ent)
510 goto out;
511 memset(ent, 0, sizeof(struct proc_dir_entry));
512 memcpy(((char *) ent) + sizeof(*ent), fn, len + 1);
513 ent->name = ((char *) ent) + sizeof(*ent);
514 ent->namelen = len;
515
516 if (S_ISDIR(mode)) {
517 if ((mode & S_IALLUGO) == 0)
518 mode |= S_IRUGO | S_IXUGO;
519 ent->proc_fops = &proc_dir_operations;
520 ent->proc_iops = &proc_dir_inode_operations;
521 ent->nlink = 2;
522 } else {
523 if ((mode & S_IFMT) == 0)
524 mode |= S_IFREG;
525 if ((mode & S_IALLUGO) == 0)
526 mode |= S_IRUGO;
527 ent->nlink = 1;
528 }
529 ent->mode = mode;
530
531 proc_register(parent, ent);
532
533 out:
534 return ent;
535 }
536
537 void free_proc_entry(struct proc_dir_entry *de)
538 {
539 int ino = de->low_ino;
540
541 if (ino < PROC_DYNAMIC_FIRST ||
542 ino >= PROC_DYNAMIC_FIRST+PROC_NDYNAMIC)
543 return;
544 if (S_ISLNK(de->mode) && de->data)
545 kfree(de->data);
546 kfree(de);
547 }
548
549 /*
550 * Remove a /proc entry and free it if it's not currently in use.
551 * If it is in use, we set the 'deleted' flag.
552 */
553 void remove_proc_entry(const char *name, struct proc_dir_entry *parent)
554 {
555 struct proc_dir_entry **p;
556 struct proc_dir_entry *de;
557 const char *fn = name;
558 int len;
559
560 if (!parent && xlate_proc_name(name, &parent, &fn) != 0)
561 goto out;
562 len = strlen(fn);
563 for (p = &parent->subdir; *p; p=&(*p)->next ) {
564 if (!proc_match(len, fn, *p))
565 continue;
566 de = *p;
567 *p = de->next;
568 de->next = NULL;
569 if (S_ISDIR(de->mode))
570 parent->nlink--;
571 clear_bit(de->low_ino-PROC_DYNAMIC_FIRST,
572 (void *) proc_alloc_map);
573 proc_kill_inodes(de);
574 de->nlink = 0;
575 if (!atomic_read(&de->count))
576 free_proc_entry(de);
577 else {
578 de->deleted = 1;
579 printk("remove_proc_entry: %s/%s busy, count=%d\n",
580 parent->name, de->name, atomic_read(&de->count));
581 }
582 break;
583 }
584 out:
585 return;
586 }
587
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.