Import 2.1.112pre1
[davej-history.git] / fs / proc / root.c
blob9941ff559a6ed752879aeb0b8b0e8d43b608af10
1 /*
2 * linux/fs/proc/root.c
4 * Copyright (C) 1991, 1992 Linus Torvalds
6 * proc root directory handling functions
7 */
9 #include <asm/uaccess.h>
11 #include <linux/errno.h>
12 #include <linux/sched.h>
13 #include <linux/proc_fs.h>
14 #include <linux/stat.h>
15 #include <linux/config.h>
16 #include <linux/init.h>
17 #include <asm/bitops.h>
18 #ifdef CONFIG_KMOD
19 #include <linux/kmod.h>
20 #endif
23 * Offset of the first process in the /proc root directory..
25 #define FIRST_PROCESS_ENTRY 256
27 static int proc_root_readdir(struct file *, void *, filldir_t);
28 static int proc_root_lookup(struct inode *,struct dentry *);
29 static int proc_unlink(struct inode *, struct dentry *);
31 static unsigned char proc_alloc_map[PROC_NDYNAMIC / 8] = {0};
34 * These are the generic /proc directory operations. They
35 * use the in-memory "struct proc_dir_entry" tree to parse
36 * the /proc directory.
38 * NOTE! The /proc/scsi directory currently does not correctly
39 * build up the proc_dir_entry tree, and will show up empty.
41 static struct file_operations proc_dir_operations = {
42 NULL, /* lseek - default */
43 NULL, /* read - bad */
44 NULL, /* write - bad */
45 proc_readdir, /* readdir */
46 NULL, /* poll - default */
47 NULL, /* ioctl - default */
48 NULL, /* mmap */
49 NULL, /* no special open code */
50 NULL, /* no special release code */
51 NULL /* can't fsync */
54 int proc_readlink(struct dentry * dentry, char * buffer, int buflen);
55 struct dentry * proc_follow_link(struct dentry *dentry, struct dentry *base);
58 * proc directories can do almost nothing..
60 struct inode_operations proc_dir_inode_operations = {
61 &proc_dir_operations, /* default net directory file-ops */
62 NULL, /* create */
63 proc_lookup, /* lookup */
64 NULL, /* link */
65 NULL, /* unlink */
66 NULL, /* symlink */
67 NULL, /* mkdir */
68 NULL, /* rmdir */
69 NULL, /* mknod */
70 NULL, /* rename */
71 NULL, /* readlink */
72 NULL, /* follow_link */
73 NULL, /* readpage */
74 NULL, /* writepage */
75 NULL, /* bmap */
76 NULL, /* truncate */
77 NULL /* permission */
81 * /proc dynamic directories now support unlinking
83 struct inode_operations proc_dyna_dir_inode_operations = {
84 &proc_dir_operations, /* default proc dir ops */
85 NULL, /* create */
86 proc_lookup, /* lookup */
87 NULL, /* link */
88 proc_unlink, /* unlink(struct inode *, struct dentry *) */
89 NULL, /* symlink */
90 NULL, /* mkdir */
91 NULL, /* rmdir */
92 NULL, /* mknod */
93 NULL, /* rename */
94 NULL, /* readlink */
95 NULL, /* follow_link */
96 NULL, /* readpage */
97 NULL, /* writepage */
98 NULL, /* bmap */
99 NULL, /* truncate */
100 NULL /* permission */
104 * The root /proc directory is special, as it has the
105 * <pid> directories. Thus we don't use the generic
106 * directory handling functions for that..
108 static struct file_operations proc_root_operations = {
109 NULL, /* lseek - default */
110 NULL, /* read - bad */
111 NULL, /* write - bad */
112 proc_root_readdir, /* readdir */
113 NULL, /* poll - default */
114 NULL, /* ioctl - default */
115 NULL, /* mmap */
116 NULL, /* no special open code */
117 NULL, /* no special release code */
118 NULL /* no fsync */
122 * proc root can do almost nothing..
124 static struct inode_operations proc_root_inode_operations = {
125 &proc_root_operations, /* default base directory file-ops */
126 NULL, /* create */
127 proc_root_lookup, /* lookup */
128 NULL, /* link */
129 NULL, /* unlink */
130 NULL, /* symlink */
131 NULL, /* mkdir */
132 NULL, /* rmdir */
133 NULL, /* mknod */
134 NULL, /* rename */
135 NULL, /* readlink */
136 NULL, /* follow_link */
137 NULL, /* readpage */
138 NULL, /* writepage */
139 NULL, /* bmap */
140 NULL, /* truncate */
141 NULL /* permission */
145 * This is the root "inode" in the /proc tree..
147 struct proc_dir_entry proc_root = {
148 PROC_ROOT_INO, 5, "/proc",
149 S_IFDIR | S_IRUGO | S_IXUGO, 2, 0, 0,
150 0, &proc_root_inode_operations,
151 NULL, NULL,
152 NULL,
153 &proc_root, NULL
156 struct proc_dir_entry *proc_net, *proc_scsi, *proc_bus;
158 #ifdef CONFIG_MCA
159 struct proc_dir_entry proc_mca = {
160 PROC_MCA, 3, "mca",
161 S_IFDIR | S_IRUGO | S_IXUGO, 2, 0, 0,
162 0, &proc_dir_inode_operations,
163 NULL, NULL,
164 NULL, &proc_root, NULL
166 #endif
168 #ifdef CONFIG_SYSCTL
169 struct proc_dir_entry proc_sys_root = {
170 PROC_SYS, 3, "sys", /* inode, name */
171 S_IFDIR | S_IRUGO | S_IXUGO, 2, 0, 0, /* mode, nlink, uid, gid */
172 0, &proc_dir_inode_operations, /* size, ops */
173 NULL, NULL, /* get_info, fill_inode */
174 NULL, /* next */
175 NULL, NULL /* parent, subdir */
177 #endif
179 #if defined(CONFIG_SUN_OPENPROMFS) || defined(CONFIG_SUN_OPENPROMFS_MODULE)
181 static int (*proc_openprom_defreaddir_ptr)(struct file *, void *, filldir_t);
182 static int (*proc_openprom_deflookup_ptr)(struct inode *, struct dentry *);
183 void (*proc_openprom_use)(struct inode *, int) = 0;
184 static struct openpromfs_dev *proc_openprom_devices = NULL;
185 static ino_t proc_openpromdev_ino = PROC_OPENPROMD_FIRST;
187 struct inode_operations *
188 proc_openprom_register(int (*readdir)(struct file *, void *, filldir_t),
189 int (*lookup)(struct inode *, struct dentry *),
190 void (*use)(struct inode *, int),
191 struct openpromfs_dev ***devices)
193 proc_openprom_defreaddir_ptr = (proc_openprom_inode_operations.default_file_ops)->readdir;
194 proc_openprom_deflookup_ptr = proc_openprom_inode_operations.lookup;
195 (proc_openprom_inode_operations.default_file_ops)->readdir = readdir;
196 proc_openprom_inode_operations.lookup = lookup;
197 proc_openprom_use = use;
198 *devices = &proc_openprom_devices;
199 return &proc_openprom_inode_operations;
202 int proc_openprom_regdev(struct openpromfs_dev *d)
204 if (proc_openpromdev_ino == PROC_OPENPROMD_FIRST + PROC_NOPENPROMD)
205 return -1;
206 d->next = proc_openprom_devices;
207 d->inode = proc_openpromdev_ino++;
208 proc_openprom_devices = d;
209 return 0;
212 int proc_openprom_unregdev(struct openpromfs_dev *d)
214 if (d == proc_openprom_devices) {
215 proc_openprom_devices = d->next;
216 } else if (!proc_openprom_devices)
217 return -1;
218 else {
219 struct openpromfs_dev *p;
221 for (p = proc_openprom_devices; p->next != d && p->next; p = p->next);
222 if (!p->next) return -1;
223 p->next = d->next;
225 return 0;
228 #ifdef CONFIG_SUN_OPENPROMFS_MODULE
229 void
230 proc_openprom_deregister(void)
232 (proc_openprom_inode_operations.default_file_ops)->readdir = proc_openprom_defreaddir_ptr;
233 proc_openprom_inode_operations.lookup = proc_openprom_deflookup_ptr;
234 proc_openprom_use = 0;
236 #endif
238 #if defined(CONFIG_SUN_OPENPROMFS_MODULE) && defined(CONFIG_KMOD)
239 static int
240 proc_openprom_defreaddir(struct file * filp, void * dirent, filldir_t filldir)
242 request_module("openpromfs");
243 if ((proc_openprom_inode_operations.default_file_ops)->readdir !=
244 proc_openprom_defreaddir)
245 return (proc_openprom_inode_operations.default_file_ops)->readdir
246 (filp, dirent, filldir);
247 return -EINVAL;
249 #define OPENPROM_DEFREADDIR proc_openprom_defreaddir
251 static int
252 proc_openprom_deflookup(struct inode * dir, struct dentry *dentry)
254 request_module("openpromfs");
255 if (proc_openprom_inode_operations.lookup !=
256 proc_openprom_deflookup)
257 return proc_openprom_inode_operations.lookup
258 (dir, dentry);
259 return -ENOENT;
261 #define OPENPROM_DEFLOOKUP proc_openprom_deflookup
262 #else
263 #define OPENPROM_DEFREADDIR NULL
264 #define OPENPROM_DEFLOOKUP NULL
265 #endif
267 static struct file_operations proc_openprom_operations = {
268 NULL, /* lseek - default */
269 NULL, /* read - bad */
270 NULL, /* write - bad */
271 OPENPROM_DEFREADDIR, /* readdir */
272 NULL, /* poll - default */
273 NULL, /* ioctl - default */
274 NULL, /* mmap */
275 NULL, /* no special open code */
276 NULL, /* no special release code */
277 NULL /* can't fsync */
280 struct inode_operations proc_openprom_inode_operations = {
281 &proc_openprom_operations,/* default net directory file-ops */
282 NULL, /* create */
283 OPENPROM_DEFLOOKUP, /* lookup */
284 NULL, /* link */
285 NULL, /* unlink */
286 NULL, /* symlink */
287 NULL, /* mkdir */
288 NULL, /* rmdir */
289 NULL, /* mknod */
290 NULL, /* rename */
291 NULL, /* readlink */
292 NULL, /* follow_link */
293 NULL, /* readpage */
294 NULL, /* writepage */
295 NULL, /* bmap */
296 NULL, /* truncate */
297 NULL /* permission */
300 struct proc_dir_entry proc_openprom = {
301 PROC_OPENPROM, 8, "openprom",
302 S_IFDIR | S_IRUGO | S_IXUGO, 2, 0, 0,
303 0, &proc_openprom_inode_operations,
304 NULL, NULL,
305 NULL,
306 &proc_root, NULL
309 extern void openpromfs_init (void);
310 #endif /* CONFIG_SUN_OPENPROMFS */
312 static int make_inode_number(void)
314 int i = find_first_zero_bit((void *) proc_alloc_map, PROC_NDYNAMIC);
315 if (i<0 || i>=PROC_NDYNAMIC)
316 return -1;
317 set_bit(i, (void *) proc_alloc_map);
318 return PROC_DYNAMIC_FIRST + i;
321 int proc_register(struct proc_dir_entry * dir, struct proc_dir_entry * dp)
323 int i;
325 if (dp->low_ino == 0) {
326 i = make_inode_number();
327 if (i < 0)
328 return -EAGAIN;
329 dp->low_ino = i;
331 dp->next = dir->subdir;
332 dp->parent = dir;
333 dir->subdir = dp;
334 if (S_ISDIR(dp->mode)) {
335 if (dp->ops == NULL)
336 dp->ops = &proc_dir_inode_operations;
337 dir->nlink++;
338 } else if (S_ISLNK(dp->mode)) {
339 if (dp->ops == NULL)
340 dp->ops = &proc_link_inode_operations;
341 } else {
342 if (dp->ops == NULL)
343 dp->ops = &proc_file_inode_operations;
345 return 0;
348 int proc_unregister(struct proc_dir_entry * dir, int ino)
350 struct proc_dir_entry **p = &dir->subdir, *dp;
352 while ((dp = *p) != NULL) {
353 if (dp->low_ino == ino) {
354 *p = dp->next;
355 dp->next = NULL;
356 if (S_ISDIR(dp->mode))
357 dir->nlink--;
358 if (ino >= PROC_DYNAMIC_FIRST &&
359 ino < PROC_DYNAMIC_FIRST+PROC_NDYNAMIC)
360 clear_bit(ino-PROC_DYNAMIC_FIRST,
361 (void *) proc_alloc_map);
362 return 0;
364 p = &dp->next;
366 return -EINVAL;
370 * /proc/self:
372 static int proc_self_readlink(struct dentry *dentry, char *buffer, int buflen)
374 int len;
375 char tmp[30];
377 len = sprintf(tmp, "%d", current->pid);
378 if (buflen < len)
379 len = buflen;
380 copy_to_user(buffer, tmp, len);
381 return len;
384 static struct dentry * proc_self_follow_link(struct dentry *dentry,
385 struct dentry *base)
387 char tmp[30];
389 sprintf(tmp, "%d", current->pid);
390 return lookup_dentry(tmp, base, 1);
393 int proc_readlink(struct dentry * dentry, char * buffer, int buflen)
395 struct inode *inode = dentry->d_inode;
396 struct proc_dir_entry * de;
397 char *page;
398 int len = 0;
400 de = (struct proc_dir_entry *) inode->u.generic_ip;
401 if (!de)
402 return -ENOENT;
403 if (!(page = (char*) __get_free_page(GFP_KERNEL)))
404 return -ENOMEM;
406 if (de->readlink_proc)
407 len = de->readlink_proc(de, page);
409 if (len > buflen)
410 len = buflen;
412 copy_to_user(buffer, page, len);
413 free_page((unsigned long) page);
414 return len;
417 struct dentry * proc_follow_link(struct dentry * dentry, struct dentry *base)
419 struct inode *inode = dentry->d_inode;
420 struct proc_dir_entry * de;
421 char *page;
422 struct dentry *d;
423 int len = 0;
425 de = (struct proc_dir_entry *) inode->u.generic_ip;
426 if (!(page = (char*) __get_free_page(GFP_KERNEL)))
427 return NULL;
429 if (de->readlink_proc)
430 len = de->readlink_proc(de, page);
432 d = lookup_dentry(page, base, 1);
433 free_page((unsigned long) page);
434 return d;
437 static struct inode_operations proc_self_inode_operations = {
438 NULL, /* no file-ops */
439 NULL, /* create */
440 NULL, /* lookup */
441 NULL, /* link */
442 NULL, /* unlink */
443 NULL, /* symlink */
444 NULL, /* mkdir */
445 NULL, /* rmdir */
446 NULL, /* mknod */
447 NULL, /* rename */
448 proc_self_readlink, /* readlink */
449 proc_self_follow_link, /* follow_link */
450 NULL, /* readpage */
451 NULL, /* writepage */
452 NULL, /* bmap */
453 NULL, /* truncate */
454 NULL /* permission */
457 static struct inode_operations proc_link_inode_operations = {
458 NULL, /* no file-ops */
459 NULL, /* create */
460 NULL, /* lookup */
461 NULL, /* link */
462 NULL, /* unlink */
463 NULL, /* symlink */
464 NULL, /* mkdir */
465 NULL, /* rmdir */
466 NULL, /* mknod */
467 NULL, /* rename */
468 proc_readlink, /* readlink */
469 proc_follow_link, /* follow_link */
470 NULL, /* readpage */
471 NULL, /* writepage */
472 NULL, /* bmap */
473 NULL, /* truncate */
474 NULL /* permission */
477 static struct proc_dir_entry proc_root_loadavg = {
478 PROC_LOADAVG, 7, "loadavg",
479 S_IFREG | S_IRUGO, 1, 0, 0,
480 0, &proc_array_inode_operations
482 static struct proc_dir_entry proc_root_uptime = {
483 PROC_UPTIME, 6, "uptime",
484 S_IFREG | S_IRUGO, 1, 0, 0,
485 0, &proc_array_inode_operations
487 static struct proc_dir_entry proc_root_meminfo = {
488 PROC_MEMINFO, 7, "meminfo",
489 S_IFREG | S_IRUGO, 1, 0, 0,
490 0, &proc_array_inode_operations
492 static struct proc_dir_entry proc_root_kmsg = {
493 PROC_KMSG, 4, "kmsg",
494 S_IFREG | S_IRUSR, 1, 0, 0,
495 0, &proc_kmsg_inode_operations
497 static struct proc_dir_entry proc_root_version = {
498 PROC_VERSION, 7, "version",
499 S_IFREG | S_IRUGO, 1, 0, 0,
500 0, &proc_array_inode_operations
502 #ifdef CONFIG_ZORRO
503 static struct proc_dir_entry proc_root_zorro = {
504 PROC_ZORRO, 5, "zorro",
505 S_IFREG | S_IRUGO, 1, 0, 0,
506 0, &proc_array_inode_operations
508 #endif
509 static struct proc_dir_entry proc_root_cpuinfo = {
510 PROC_CPUINFO, 7, "cpuinfo",
511 S_IFREG | S_IRUGO, 1, 0, 0,
512 0, &proc_array_inode_operations
514 #if defined (CONFIG_AMIGA) || defined (CONFIG_ATARI)
515 static struct proc_dir_entry proc_root_hardware = {
516 PROC_HARDWARE, 8, "hardware",
517 S_IFREG | S_IRUGO, 1, 0, 0,
518 0, &proc_array_inode_operations
520 #endif
521 static struct proc_dir_entry proc_root_self = {
522 PROC_SELF, 4, "self",
523 S_IFLNK | S_IRUGO | S_IWUGO | S_IXUGO, 1, 0, 0,
524 64, &proc_self_inode_operations,
526 #ifdef CONFIG_DEBUG_MALLOC
527 static struct proc_dir_entry proc_root_malloc = {
528 PROC_MALLOC, 6, "malloc",
529 S_IFREG | S_IRUGO, 1, 0, 0,
530 0, &proc_array_inode_operations
532 #endif
533 static struct proc_dir_entry proc_root_kcore = {
534 PROC_KCORE, 5, "kcore",
535 S_IFREG | S_IRUSR, 1, 0, 0,
536 0, &proc_kcore_inode_operations
538 #ifdef CONFIG_MODULES
539 static struct proc_dir_entry proc_root_modules = {
540 PROC_MODULES, 7, "modules",
541 S_IFREG | S_IRUGO, 1, 0, 0,
542 0, &proc_array_inode_operations
544 static struct proc_dir_entry proc_root_ksyms = {
545 PROC_KSYMS, 5, "ksyms",
546 S_IFREG | S_IRUGO, 1, 0, 0,
547 0, &proc_array_inode_operations
549 #endif
550 static struct proc_dir_entry proc_root_stat = {
551 PROC_STAT, 4, "stat",
552 S_IFREG | S_IRUGO, 1, 0, 0,
553 0, &proc_array_inode_operations
555 static struct proc_dir_entry proc_root_devices = {
556 PROC_DEVICES, 7, "devices",
557 S_IFREG | S_IRUGO, 1, 0, 0,
558 0, &proc_array_inode_operations
560 static struct proc_dir_entry proc_root_interrupts = {
561 PROC_INTERRUPTS, 10,"interrupts",
562 S_IFREG | S_IRUGO, 1, 0, 0,
563 0, &proc_array_inode_operations
565 static struct proc_dir_entry proc_root_filesystems = {
566 PROC_FILESYSTEMS, 11,"filesystems",
567 S_IFREG | S_IRUGO, 1, 0, 0,
568 0, &proc_array_inode_operations
570 struct proc_dir_entry proc_root_fs = {
571 PROC_FS, 2, "fs",
572 S_IFDIR | S_IRUGO | S_IXUGO, 2, 0, 0,
573 0, &proc_dir_inode_operations,
574 NULL, NULL,
575 NULL,
576 NULL, NULL
578 static struct proc_dir_entry proc_root_dma = {
579 PROC_DMA, 3, "dma",
580 S_IFREG | S_IRUGO, 1, 0, 0,
581 0, &proc_array_inode_operations
583 static struct proc_dir_entry proc_root_ioports = {
584 PROC_IOPORTS, 7, "ioports",
585 S_IFREG | S_IRUGO, 1, 0, 0,
586 0, &proc_array_inode_operations
588 static struct proc_dir_entry proc_root_cmdline = {
589 PROC_CMDLINE, 7, "cmdline",
590 S_IFREG | S_IRUGO, 1, 0, 0,
591 0, &proc_array_inode_operations
593 #ifdef CONFIG_RTC
594 static struct proc_dir_entry proc_root_rtc = {
595 PROC_RTC, 3, "rtc",
596 S_IFREG | S_IRUGO, 1, 0, 0,
597 0, &proc_array_inode_operations
599 #endif
600 static struct proc_dir_entry proc_root_locks = {
601 PROC_LOCKS, 5, "locks",
602 S_IFREG | S_IRUGO, 1, 0, 0,
603 0, &proc_array_inode_operations
605 static struct proc_dir_entry proc_root_mounts = {
606 PROC_MTAB, 6, "mounts",
607 S_IFREG | S_IRUGO, 1, 0, 0,
608 0, &proc_array_inode_operations
610 static struct proc_dir_entry proc_root_swaps = {
611 PROC_SWAP, 5, "swaps",
612 S_IFREG | S_IRUGO, 1, 0, 0,
613 0, &proc_array_inode_operations
615 static struct proc_dir_entry proc_root_profile = {
616 PROC_PROFILE, 7, "profile",
617 S_IFREG | S_IRUGO | S_IWUSR, 1, 0, 0,
618 0, &proc_profile_inode_operations
620 static struct proc_dir_entry proc_root_slab = {
621 PROC_SLABINFO, 8, "slabinfo",
622 S_IFREG | S_IRUGO, 1, 0, 0,
623 0, &proc_array_inode_operations
625 #ifdef __powerpc__
626 static struct proc_dir_entry proc_root_ppc_htab = {
627 PROC_PPC_HTAB, 8, "ppc_htab",
628 S_IFREG | S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH, 1, 0, 0,
629 0, &proc_ppc_htab_inode_operations,
630 NULL, NULL, /* get_info, fill_inode */
631 NULL, /* next */
632 NULL, NULL /* parent, subdir */
634 #endif
636 __initfunc(void proc_root_init(void))
638 proc_base_init();
639 proc_register(&proc_root, &proc_root_loadavg);
640 proc_register(&proc_root, &proc_root_uptime);
641 proc_register(&proc_root, &proc_root_meminfo);
642 proc_register(&proc_root, &proc_root_kmsg);
643 proc_register(&proc_root, &proc_root_version);
644 #ifdef CONFIG_ZORRO
645 proc_register(&proc_root, &proc_root_zorro);
646 #endif
647 proc_register(&proc_root, &proc_root_cpuinfo);
648 proc_register(&proc_root, &proc_root_self);
649 proc_net = create_proc_entry("net", S_IFDIR, 0);
650 proc_scsi = create_proc_entry("scsi", S_IFDIR, 0);
651 #ifdef CONFIG_SYSCTL
652 proc_register(&proc_root, &proc_sys_root);
653 #endif
654 #ifdef CONFIG_MCA
655 proc_register(&proc_root, &proc_mca);
656 #endif
658 #ifdef CONFIG_DEBUG_MALLOC
659 proc_register(&proc_root, &proc_root_malloc);
660 #endif
661 proc_register(&proc_root, &proc_root_kcore);
662 proc_root_kcore.size = (MAP_NR(high_memory) << PAGE_SHIFT) + PAGE_SIZE;
664 #ifdef CONFIG_MODULES
665 proc_register(&proc_root, &proc_root_modules);
666 proc_register(&proc_root, &proc_root_ksyms);
667 #endif
668 proc_register(&proc_root, &proc_root_stat);
669 proc_register(&proc_root, &proc_root_devices);
670 proc_register(&proc_root, &proc_root_interrupts);
671 proc_register(&proc_root, &proc_root_filesystems);
672 proc_register(&proc_root, &proc_root_fs);
673 proc_register(&proc_root, &proc_root_dma);
674 proc_register(&proc_root, &proc_root_ioports);
675 proc_register(&proc_root, &proc_root_cmdline);
676 #ifdef CONFIG_RTC
677 proc_register(&proc_root, &proc_root_rtc);
678 #endif
679 proc_register(&proc_root, &proc_root_locks);
681 proc_register(&proc_root, &proc_root_mounts);
682 proc_register(&proc_root, &proc_root_swaps);
684 #if defined(CONFIG_SUN_OPENPROMFS) || defined(CONFIG_SUN_OPENPROMFS_MODULE)
685 #ifdef CONFIG_SUN_OPENPROMFS
686 openpromfs_init ();
687 #endif
688 proc_register(&proc_root, &proc_openprom);
689 #endif
690 #if defined (CONFIG_AMIGA) || defined (CONFIG_ATARI)
691 proc_register(&proc_root, &proc_root_hardware);
692 #endif
693 proc_register(&proc_root, &proc_root_slab);
695 if (prof_shift) {
696 proc_register(&proc_root, &proc_root_profile);
697 proc_root_profile.size = (1+prof_len) * sizeof(unsigned int);
700 proc_tty_init();
701 #ifdef __powerpc__
702 proc_register(&proc_root, &proc_root_ppc_htab);
703 #endif
704 #ifdef CONFIG_PROC_DEVICETREE
705 proc_device_tree_init();
706 #endif
708 proc_bus = create_proc_entry("bus", S_IFDIR, 0);
712 * As some entries in /proc are volatile, we want to
713 * get rid of unused dentries. This could be made
714 * smarter: we could keep a "volatile" flag in the
715 * inode to indicate which ones to keep.
717 static void
718 proc_delete_dentry(struct dentry * dentry)
720 d_drop(dentry);
723 static struct dentry_operations proc_dentry_operations =
725 NULL, /* revalidate */
726 NULL, /* d_hash */
727 NULL, /* d_compare */
728 proc_delete_dentry /* d_delete(struct dentry *) */
732 * Don't create negative dentries here, return -ENOENT by hand
733 * instead.
735 int proc_lookup(struct inode * dir, struct dentry *dentry)
737 struct inode *inode;
738 struct proc_dir_entry * de;
739 int error;
741 error = -ENOTDIR;
742 if (!dir || !S_ISDIR(dir->i_mode))
743 goto out;
745 error = -ENOENT;
746 inode = NULL;
747 de = (struct proc_dir_entry *) dir->u.generic_ip;
748 if (de) {
749 for (de = de->subdir; de ; de = de->next) {
750 if (!de || !de->low_ino)
751 continue;
752 if (de->namelen != dentry->d_name.len)
753 continue;
754 if (!memcmp(dentry->d_name.name, de->name, de->namelen)) {
755 int ino = de->low_ino | (dir->i_ino & ~(0xffff));
756 error = -EINVAL;
757 inode = proc_get_inode(dir->i_sb, ino, de);
758 break;
763 if (inode) {
764 dentry->d_op = &proc_dentry_operations;
765 d_add(dentry, inode);
766 error = 0;
768 out:
769 return error;
772 static int proc_root_lookup(struct inode * dir, struct dentry * dentry)
774 unsigned int pid, c;
775 struct task_struct *p;
776 const char *name;
777 struct inode *inode;
778 int len;
780 if (dir->i_ino == PROC_ROOT_INO) { /* check for safety... */
781 dir->i_nlink = proc_root.nlink;
783 read_lock(&tasklist_lock);
784 for_each_task(p) {
785 if (p->pid)
786 dir->i_nlink++;
788 read_unlock(&tasklist_lock);
791 if (!proc_lookup(dir, dentry))
792 return 0;
794 pid = 0;
795 name = dentry->d_name.name;
796 len = dentry->d_name.len;
797 while (len-- > 0) {
798 c = *name - '0';
799 name++;
800 if (c > 9) {
801 pid = 0;
802 break;
804 pid *= 10;
805 pid += c;
806 if (pid & 0xffff0000) {
807 pid = 0;
808 break;
811 read_lock(&tasklist_lock);
812 p = find_task_by_pid(pid);
813 inode = NULL;
814 if (pid && p) {
815 unsigned long ino = (pid << 16) + PROC_PID_INO;
816 inode = proc_get_inode(dir->i_sb, ino, &proc_pid);
817 if (!inode) {
818 read_unlock(&tasklist_lock);
819 return -EINVAL;
822 read_unlock(&tasklist_lock);
824 dentry->d_op = &proc_dentry_operations;
825 d_add(dentry, inode);
826 return 0;
830 * This returns non-zero if at EOF, so that the /proc
831 * root directory can use this and check if it should
832 * continue with the <pid> entries..
834 * Note that the VFS-layer doesn't care about the return
835 * value of the readdir() call, as long as it's non-negative
836 * for success..
838 int proc_readdir(struct file * filp,
839 void * dirent, filldir_t filldir)
841 struct proc_dir_entry * de;
842 unsigned int ino;
843 int i;
844 struct inode *inode = filp->f_dentry->d_inode;
846 if (!inode || !S_ISDIR(inode->i_mode))
847 return -ENOTDIR;
848 ino = inode->i_ino;
849 de = (struct proc_dir_entry *) inode->u.generic_ip;
850 if (!de)
851 return -EINVAL;
852 i = filp->f_pos;
853 switch (i) {
854 case 0:
855 if (filldir(dirent, ".", 1, i, ino) < 0)
856 return 0;
857 i++;
858 filp->f_pos++;
859 /* fall through */
860 case 1:
861 if (filldir(dirent, "..", 2, i, de->parent->low_ino) < 0)
862 return 0;
863 i++;
864 filp->f_pos++;
865 /* fall through */
866 default:
867 ino &= ~0xffff;
868 de = de->subdir;
869 i -= 2;
870 for (;;) {
871 if (!de)
872 return 1;
873 if (!i)
874 break;
875 de = de->next;
876 i--;
879 do {
880 if (filldir(dirent, de->name, de->namelen, filp->f_pos, ino | de->low_ino) < 0)
881 return 0;
882 filp->f_pos++;
883 de = de->next;
884 } while (de);
886 return 1;
889 #define NUMBUF 10
891 static int proc_root_readdir(struct file * filp,
892 void * dirent, filldir_t filldir)
894 struct task_struct *p;
895 char buf[NUMBUF];
896 unsigned int nr = filp->f_pos;
898 if (nr < FIRST_PROCESS_ENTRY) {
899 int error = proc_readdir(filp, dirent, filldir);
900 if (error <= 0)
901 return error;
902 filp->f_pos = FIRST_PROCESS_ENTRY;
904 nr = FIRST_PROCESS_ENTRY;
906 read_lock(&tasklist_lock);
907 for_each_task(p) {
908 unsigned int pid;
910 if(nr++ < filp->f_pos)
911 continue;
913 if((pid = p->pid) != 0) {
914 unsigned long j = NUMBUF, i = pid;
916 do {
917 j--;
918 buf[j] = '0' + (i % 10);
919 i /= 10;
920 } while (i);
922 if (filldir(dirent, buf+j, NUMBUF-j,
923 filp->f_pos, (pid << 16) + PROC_PID_INO) < 0)
924 break;
926 filp->f_pos++;
928 read_unlock(&tasklist_lock);
929 return 0;
932 static int proc_unlink(struct inode *dir, struct dentry *dentry)
934 struct proc_dir_entry * dp = dir->u.generic_ip;
936 printk("proc_file_unlink: deleting %s/%s\n", dp->name, dentry->d_name.name);
938 remove_proc_entry(dentry->d_name.name, dp);
939 dentry->d_inode->i_nlink = 0;
940 d_delete(dentry);
941 return 0;