4 * Copyright (C) 1991, 1992 Linus Torvalds
6 * proc root directory handling functions
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>
19 #include <linux/kmod.h>
22 #include <linux/zorro.h>
26 * Offset of the first process in the /proc root directory..
28 #define FIRST_PROCESS_ENTRY 256
30 static int proc_root_readdir(struct file
*, void *, filldir_t
);
31 static int proc_root_lookup(struct inode
*,struct dentry
*);
32 static int proc_unlink(struct inode
*, struct dentry
*);
34 static unsigned char proc_alloc_map
[PROC_NDYNAMIC
/ 8] = {0};
37 * These are the generic /proc directory operations. They
38 * use the in-memory "struct proc_dir_entry" tree to parse
39 * the /proc directory.
41 * NOTE! The /proc/scsi directory currently does not correctly
42 * build up the proc_dir_entry tree, and will show up empty.
44 static struct file_operations proc_dir_operations
= {
45 NULL
, /* lseek - default */
46 NULL
, /* read - bad */
47 NULL
, /* write - bad */
48 proc_readdir
, /* readdir */
49 NULL
, /* poll - default */
50 NULL
, /* ioctl - default */
52 NULL
, /* no special open code */
53 NULL
, /* no special release code */
54 NULL
/* can't fsync */
57 int proc_readlink(struct dentry
* dentry
, char * buffer
, int buflen
);
58 struct dentry
* proc_follow_link(struct dentry
*dentry
, struct dentry
*base
);
61 * proc directories can do almost nothing..
63 struct inode_operations proc_dir_inode_operations
= {
64 &proc_dir_operations
, /* default net directory file-ops */
66 proc_lookup
, /* lookup */
75 NULL
, /* follow_link */
84 * /proc dynamic directories now support unlinking
86 struct inode_operations proc_dyna_dir_inode_operations
= {
87 &proc_dir_operations
, /* default proc dir ops */
89 proc_lookup
, /* lookup */
91 proc_unlink
, /* unlink(struct inode *, struct dentry *) */
98 NULL
, /* follow_link */
100 NULL
, /* writepage */
103 NULL
/* permission */
107 * The root /proc directory is special, as it has the
108 * <pid> directories. Thus we don't use the generic
109 * directory handling functions for that..
111 static struct file_operations proc_root_operations
= {
112 NULL
, /* lseek - default */
113 NULL
, /* read - bad */
114 NULL
, /* write - bad */
115 proc_root_readdir
, /* readdir */
116 NULL
, /* poll - default */
117 NULL
, /* ioctl - default */
119 NULL
, /* no special open code */
120 NULL
, /* no special release code */
125 * proc root can do almost nothing..
127 static struct inode_operations proc_root_inode_operations
= {
128 &proc_root_operations
, /* default base directory file-ops */
130 proc_root_lookup
, /* lookup */
139 NULL
, /* follow_link */
141 NULL
, /* writepage */
144 NULL
/* permission */
148 * This is the root "inode" in the /proc tree..
150 struct proc_dir_entry proc_root
= {
151 PROC_ROOT_INO
, 5, "/proc",
152 S_IFDIR
| S_IRUGO
| S_IXUGO
, 2, 0, 0,
153 0, &proc_root_inode_operations
,
159 struct proc_dir_entry
*proc_net
, *proc_scsi
, *proc_bus
;
162 struct proc_dir_entry proc_mca
= {
164 S_IFDIR
| S_IRUGO
| S_IXUGO
, 2, 0, 0,
165 0, &proc_dir_inode_operations
,
167 NULL
, &proc_root
, NULL
172 struct proc_dir_entry proc_sys_root
= {
173 PROC_SYS
, 3, "sys", /* inode, name */
174 S_IFDIR
| S_IRUGO
| S_IXUGO
, 2, 0, 0, /* mode, nlink, uid, gid */
175 0, &proc_dir_inode_operations
, /* size, ops */
176 NULL
, NULL
, /* get_info, fill_inode */
178 NULL
, NULL
/* parent, subdir */
182 #if defined(CONFIG_SUN_OPENPROMFS) || defined(CONFIG_SUN_OPENPROMFS_MODULE)
184 static int (*proc_openprom_defreaddir_ptr
)(struct file
*, void *, filldir_t
);
185 static int (*proc_openprom_deflookup_ptr
)(struct inode
*, struct dentry
*);
186 void (*proc_openprom_use
)(struct inode
*, int) = 0;
187 static struct openpromfs_dev
*proc_openprom_devices
= NULL
;
188 static ino_t proc_openpromdev_ino
= PROC_OPENPROMD_FIRST
;
190 struct inode_operations
*
191 proc_openprom_register(int (*readdir
)(struct file
*, void *, filldir_t
),
192 int (*lookup
)(struct inode
*, struct dentry
*),
193 void (*use
)(struct inode
*, int),
194 struct openpromfs_dev
***devices
)
196 proc_openprom_defreaddir_ptr
= (proc_openprom_inode_operations
.default_file_ops
)->readdir
;
197 proc_openprom_deflookup_ptr
= proc_openprom_inode_operations
.lookup
;
198 (proc_openprom_inode_operations
.default_file_ops
)->readdir
= readdir
;
199 proc_openprom_inode_operations
.lookup
= lookup
;
200 proc_openprom_use
= use
;
201 *devices
= &proc_openprom_devices
;
202 return &proc_openprom_inode_operations
;
205 int proc_openprom_regdev(struct openpromfs_dev
*d
)
207 if (proc_openpromdev_ino
== PROC_OPENPROMD_FIRST
+ PROC_NOPENPROMD
)
209 d
->next
= proc_openprom_devices
;
210 d
->inode
= proc_openpromdev_ino
++;
211 proc_openprom_devices
= d
;
215 int proc_openprom_unregdev(struct openpromfs_dev
*d
)
217 if (d
== proc_openprom_devices
) {
218 proc_openprom_devices
= d
->next
;
219 } else if (!proc_openprom_devices
)
222 struct openpromfs_dev
*p
;
224 for (p
= proc_openprom_devices
; p
->next
!= d
&& p
->next
; p
= p
->next
);
225 if (!p
->next
) return -1;
231 #ifdef CONFIG_SUN_OPENPROMFS_MODULE
233 proc_openprom_deregister(void)
235 (proc_openprom_inode_operations
.default_file_ops
)->readdir
= proc_openprom_defreaddir_ptr
;
236 proc_openprom_inode_operations
.lookup
= proc_openprom_deflookup_ptr
;
237 proc_openprom_use
= 0;
241 #if defined(CONFIG_SUN_OPENPROMFS_MODULE) && defined(CONFIG_KMOD)
243 proc_openprom_defreaddir(struct file
* filp
, void * dirent
, filldir_t filldir
)
245 request_module("openpromfs");
246 if ((proc_openprom_inode_operations
.default_file_ops
)->readdir
!=
247 proc_openprom_defreaddir
)
248 return (proc_openprom_inode_operations
.default_file_ops
)->readdir
249 (filp
, dirent
, filldir
);
252 #define OPENPROM_DEFREADDIR proc_openprom_defreaddir
255 proc_openprom_deflookup(struct inode
* dir
, struct dentry
*dentry
)
257 request_module("openpromfs");
258 if (proc_openprom_inode_operations
.lookup
!=
259 proc_openprom_deflookup
)
260 return proc_openprom_inode_operations
.lookup
264 #define OPENPROM_DEFLOOKUP proc_openprom_deflookup
266 #define OPENPROM_DEFREADDIR NULL
267 #define OPENPROM_DEFLOOKUP NULL
270 static struct file_operations proc_openprom_operations
= {
271 NULL
, /* lseek - default */
272 NULL
, /* read - bad */
273 NULL
, /* write - bad */
274 OPENPROM_DEFREADDIR
, /* readdir */
275 NULL
, /* poll - default */
276 NULL
, /* ioctl - default */
278 NULL
, /* no special open code */
279 NULL
, /* no special release code */
280 NULL
/* can't fsync */
283 struct inode_operations proc_openprom_inode_operations
= {
284 &proc_openprom_operations
,/* default net directory file-ops */
286 OPENPROM_DEFLOOKUP
, /* lookup */
295 NULL
, /* follow_link */
297 NULL
, /* writepage */
300 NULL
/* permission */
303 struct proc_dir_entry proc_openprom
= {
304 PROC_OPENPROM
, 8, "openprom",
305 S_IFDIR
| S_IRUGO
| S_IXUGO
, 2, 0, 0,
306 0, &proc_openprom_inode_operations
,
312 extern void openpromfs_init (void);
313 #endif /* CONFIG_SUN_OPENPROMFS */
315 static int make_inode_number(void)
317 int i
= find_first_zero_bit((void *) proc_alloc_map
, PROC_NDYNAMIC
);
318 if (i
<0 || i
>=PROC_NDYNAMIC
)
320 set_bit(i
, (void *) proc_alloc_map
);
321 return PROC_DYNAMIC_FIRST
+ i
;
324 int proc_register(struct proc_dir_entry
* dir
, struct proc_dir_entry
* dp
)
328 if (dp
->low_ino
== 0) {
329 i
= make_inode_number();
334 dp
->next
= dir
->subdir
;
337 if (S_ISDIR(dp
->mode
)) {
339 dp
->ops
= &proc_dir_inode_operations
;
341 } else if (S_ISLNK(dp
->mode
)) {
343 dp
->ops
= &proc_link_inode_operations
;
346 dp
->ops
= &proc_file_inode_operations
;
351 int proc_unregister(struct proc_dir_entry
* dir
, int ino
)
353 struct proc_dir_entry
**p
= &dir
->subdir
, *dp
;
355 while ((dp
= *p
) != NULL
) {
356 if (dp
->low_ino
== ino
) {
359 if (S_ISDIR(dp
->mode
))
361 if (ino
>= PROC_DYNAMIC_FIRST
&&
362 ino
< PROC_DYNAMIC_FIRST
+PROC_NDYNAMIC
)
363 clear_bit(ino
-PROC_DYNAMIC_FIRST
,
364 (void *) proc_alloc_map
);
375 static int proc_self_readlink(struct dentry
*dentry
, char *buffer
, int buflen
)
380 len
= sprintf(tmp
, "%d", current
->pid
);
383 copy_to_user(buffer
, tmp
, len
);
387 static struct dentry
* proc_self_follow_link(struct dentry
*dentry
,
392 sprintf(tmp
, "%d", current
->pid
);
393 return lookup_dentry(tmp
, base
, 1);
396 int proc_readlink(struct dentry
* dentry
, char * buffer
, int buflen
)
398 struct inode
*inode
= dentry
->d_inode
;
399 struct proc_dir_entry
* de
;
403 de
= (struct proc_dir_entry
*) inode
->u
.generic_ip
;
406 if (!(page
= (char*) __get_free_page(GFP_KERNEL
)))
409 if (de
->readlink_proc
)
410 len
= de
->readlink_proc(de
, page
);
415 copy_to_user(buffer
, page
, len
);
416 free_page((unsigned long) page
);
420 struct dentry
* proc_follow_link(struct dentry
* dentry
, struct dentry
*base
)
422 struct inode
*inode
= dentry
->d_inode
;
423 struct proc_dir_entry
* de
;
428 de
= (struct proc_dir_entry
*) inode
->u
.generic_ip
;
429 if (!(page
= (char*) __get_free_page(GFP_KERNEL
)))
432 if (de
->readlink_proc
)
433 len
= de
->readlink_proc(de
, page
);
435 d
= lookup_dentry(page
, base
, 1);
436 free_page((unsigned long) page
);
440 static struct inode_operations proc_self_inode_operations
= {
441 NULL
, /* no file-ops */
451 proc_self_readlink
, /* readlink */
452 proc_self_follow_link
, /* follow_link */
454 NULL
, /* writepage */
457 NULL
/* permission */
460 static struct inode_operations proc_link_inode_operations
= {
461 NULL
, /* no file-ops */
471 proc_readlink
, /* readlink */
472 proc_follow_link
, /* follow_link */
474 NULL
, /* writepage */
477 NULL
/* permission */
480 static struct proc_dir_entry proc_root_loadavg
= {
481 PROC_LOADAVG
, 7, "loadavg",
482 S_IFREG
| S_IRUGO
, 1, 0, 0,
483 0, &proc_array_inode_operations
485 static struct proc_dir_entry proc_root_uptime
= {
486 PROC_UPTIME
, 6, "uptime",
487 S_IFREG
| S_IRUGO
, 1, 0, 0,
488 0, &proc_array_inode_operations
490 static struct proc_dir_entry proc_root_meminfo
= {
491 PROC_MEMINFO
, 7, "meminfo",
492 S_IFREG
| S_IRUGO
, 1, 0, 0,
493 0, &proc_array_inode_operations
495 static struct proc_dir_entry proc_root_kmsg
= {
496 PROC_KMSG
, 4, "kmsg",
497 S_IFREG
| S_IRUSR
, 1, 0, 0,
498 0, &proc_kmsg_inode_operations
500 static struct proc_dir_entry proc_root_version
= {
501 PROC_VERSION
, 7, "version",
502 S_IFREG
| S_IRUGO
, 1, 0, 0,
503 0, &proc_array_inode_operations
505 static struct proc_dir_entry proc_root_cpuinfo
= {
506 PROC_CPUINFO
, 7, "cpuinfo",
507 S_IFREG
| S_IRUGO
, 1, 0, 0,
508 0, &proc_array_inode_operations
510 #if defined (CONFIG_PROC_HARDWARE)
511 static struct proc_dir_entry proc_root_hardware
= {
512 PROC_HARDWARE
, 8, "hardware",
513 S_IFREG
| S_IRUGO
, 1, 0, 0,
514 0, &proc_array_inode_operations
517 #ifdef CONFIG_STRAM_PROC
518 static struct proc_dir_entry proc_root_stram
= {
519 PROC_STRAM
, 5, "stram",
520 S_IFREG
| S_IRUGO
, 1, 0, 0,
521 0, &proc_array_inode_operations
524 static struct proc_dir_entry proc_root_self
= {
525 PROC_SELF
, 4, "self",
526 S_IFLNK
| S_IRUGO
| S_IWUGO
| S_IXUGO
, 1, 0, 0,
527 64, &proc_self_inode_operations
,
529 #ifdef CONFIG_DEBUG_MALLOC
530 static struct proc_dir_entry proc_root_malloc
= {
531 PROC_MALLOC
, 6, "malloc",
532 S_IFREG
| S_IRUGO
, 1, 0, 0,
533 0, &proc_array_inode_operations
536 static struct proc_dir_entry proc_root_kcore
= {
537 PROC_KCORE
, 5, "kcore",
538 S_IFREG
| S_IRUSR
, 1, 0, 0,
539 0, &proc_kcore_inode_operations
541 #ifdef CONFIG_MODULES
542 static struct proc_dir_entry proc_root_modules
= {
543 PROC_MODULES
, 7, "modules",
544 S_IFREG
| S_IRUGO
, 1, 0, 0,
545 0, &proc_array_inode_operations
547 static struct proc_dir_entry proc_root_ksyms
= {
548 PROC_KSYMS
, 5, "ksyms",
549 S_IFREG
| S_IRUGO
, 1, 0, 0,
550 0, &proc_array_inode_operations
553 static struct proc_dir_entry proc_root_stat
= {
554 PROC_STAT
, 4, "stat",
555 S_IFREG
| S_IRUGO
, 1, 0, 0,
556 0, &proc_array_inode_operations
558 static struct proc_dir_entry proc_root_devices
= {
559 PROC_DEVICES
, 7, "devices",
560 S_IFREG
| S_IRUGO
, 1, 0, 0,
561 0, &proc_array_inode_operations
563 static struct proc_dir_entry proc_root_partitions
= {
564 PROC_PARTITIONS
, 10, "partitions",
565 S_IFREG
| S_IRUGO
, 1, 0, 0,
566 0, &proc_array_inode_operations
568 static struct proc_dir_entry proc_root_interrupts
= {
569 PROC_INTERRUPTS
, 10,"interrupts",
570 S_IFREG
| S_IRUGO
, 1, 0, 0,
571 0, &proc_array_inode_operations
573 static struct proc_dir_entry proc_root_filesystems
= {
574 PROC_FILESYSTEMS
, 11,"filesystems",
575 S_IFREG
| S_IRUGO
, 1, 0, 0,
576 0, &proc_array_inode_operations
578 struct proc_dir_entry proc_root_fs
= {
580 S_IFDIR
| S_IRUGO
| S_IXUGO
, 2, 0, 0,
581 0, &proc_dir_inode_operations
,
586 static struct proc_dir_entry proc_root_dma
= {
588 S_IFREG
| S_IRUGO
, 1, 0, 0,
589 0, &proc_array_inode_operations
591 static struct proc_dir_entry proc_root_ioports
= {
592 PROC_IOPORTS
, 7, "ioports",
593 S_IFREG
| S_IRUGO
, 1, 0, 0,
594 0, &proc_array_inode_operations
596 static struct proc_dir_entry proc_root_cmdline
= {
597 PROC_CMDLINE
, 7, "cmdline",
598 S_IFREG
| S_IRUGO
, 1, 0, 0,
599 0, &proc_array_inode_operations
602 static struct proc_dir_entry proc_root_rtc
= {
604 S_IFREG
| S_IRUGO
, 1, 0, 0,
605 0, &proc_array_inode_operations
608 static struct proc_dir_entry proc_root_locks
= {
609 PROC_LOCKS
, 5, "locks",
610 S_IFREG
| S_IRUGO
, 1, 0, 0,
611 0, &proc_array_inode_operations
613 static struct proc_dir_entry proc_root_mounts
= {
614 PROC_MTAB
, 6, "mounts",
615 S_IFREG
| S_IRUGO
, 1, 0, 0,
616 0, &proc_array_inode_operations
618 static struct proc_dir_entry proc_root_swaps
= {
619 PROC_SWAP
, 5, "swaps",
620 S_IFREG
| S_IRUGO
, 1, 0, 0,
621 0, &proc_array_inode_operations
623 static struct proc_dir_entry proc_root_profile
= {
624 PROC_PROFILE
, 7, "profile",
625 S_IFREG
| S_IRUGO
| S_IWUSR
, 1, 0, 0,
626 0, &proc_profile_inode_operations
628 static struct proc_dir_entry proc_root_slab
= {
629 PROC_SLABINFO
, 8, "slabinfo",
630 S_IFREG
| S_IRUGO
, 1, 0, 0,
631 0, &proc_array_inode_operations
634 static struct proc_dir_entry proc_root_ppc_htab
= {
635 PROC_PPC_HTAB
, 8, "ppc_htab",
636 S_IFREG
| S_IRUSR
|S_IWUSR
|S_IRGRP
|S_IROTH
, 1, 0, 0,
637 0, &proc_ppc_htab_inode_operations
,
638 NULL
, NULL
, /* get_info, fill_inode */
640 NULL
, NULL
/* parent, subdir */
644 __initfunc(void proc_root_init(void))
647 proc_register(&proc_root
, &proc_root_loadavg
);
648 proc_register(&proc_root
, &proc_root_uptime
);
649 proc_register(&proc_root
, &proc_root_meminfo
);
650 proc_register(&proc_root
, &proc_root_kmsg
);
651 proc_register(&proc_root
, &proc_root_version
);
652 proc_register(&proc_root
, &proc_root_cpuinfo
);
653 proc_register(&proc_root
, &proc_root_self
);
654 proc_net
= create_proc_entry("net", S_IFDIR
, 0);
655 proc_scsi
= create_proc_entry("scsi", S_IFDIR
, 0);
657 proc_register(&proc_root
, &proc_sys_root
);
660 proc_register(&proc_root
, &proc_mca
);
663 #ifdef CONFIG_DEBUG_MALLOC
664 proc_register(&proc_root
, &proc_root_malloc
);
666 proc_register(&proc_root
, &proc_root_kcore
);
667 proc_root_kcore
.size
= (MAP_NR(high_memory
) << PAGE_SHIFT
) + PAGE_SIZE
;
669 #ifdef CONFIG_MODULES
670 proc_register(&proc_root
, &proc_root_modules
);
671 proc_register(&proc_root
, &proc_root_ksyms
);
673 proc_register(&proc_root
, &proc_root_stat
);
674 proc_register(&proc_root
, &proc_root_devices
);
675 proc_register(&proc_root
, &proc_root_partitions
);
676 proc_register(&proc_root
, &proc_root_interrupts
);
677 proc_register(&proc_root
, &proc_root_filesystems
);
678 proc_register(&proc_root
, &proc_root_fs
);
679 proc_register(&proc_root
, &proc_root_dma
);
680 proc_register(&proc_root
, &proc_root_ioports
);
681 proc_register(&proc_root
, &proc_root_cmdline
);
683 proc_register(&proc_root
, &proc_root_rtc
);
685 proc_register(&proc_root
, &proc_root_locks
);
687 proc_register(&proc_root
, &proc_root_mounts
);
688 proc_register(&proc_root
, &proc_root_swaps
);
690 #if defined(CONFIG_SUN_OPENPROMFS) || defined(CONFIG_SUN_OPENPROMFS_MODULE)
691 #ifdef CONFIG_SUN_OPENPROMFS
694 proc_register(&proc_root
, &proc_openprom
);
696 #ifdef CONFIG_PROC_HARDWARE
697 proc_register(&proc_root
, &proc_root_hardware
);
699 #ifdef CONFIG_STRAM_PROC
700 proc_register(&proc_root
, &proc_root_stram
);
702 proc_register(&proc_root
, &proc_root_slab
);
705 proc_register(&proc_root
, &proc_root_profile
);
706 proc_root_profile
.size
= (1+prof_len
) * sizeof(unsigned int);
711 proc_register(&proc_root
, &proc_root_ppc_htab
);
713 #ifdef CONFIG_PROC_DEVICETREE
714 proc_device_tree_init();
717 proc_bus
= create_proc_entry("bus", S_IFDIR
, 0);
721 * As some entries in /proc are volatile, we want to
722 * get rid of unused dentries. This could be made
723 * smarter: we could keep a "volatile" flag in the
724 * inode to indicate which ones to keep.
727 proc_delete_dentry(struct dentry
* dentry
)
732 static struct dentry_operations proc_dentry_operations
=
734 NULL
, /* revalidate */
736 NULL
, /* d_compare */
737 proc_delete_dentry
/* d_delete(struct dentry *) */
741 * Don't create negative dentries here, return -ENOENT by hand
744 int proc_lookup(struct inode
* dir
, struct dentry
*dentry
)
747 struct proc_dir_entry
* de
;
751 if (!dir
|| !S_ISDIR(dir
->i_mode
))
756 de
= (struct proc_dir_entry
*) dir
->u
.generic_ip
;
758 for (de
= de
->subdir
; de
; de
= de
->next
) {
759 if (!de
|| !de
->low_ino
)
761 if (de
->namelen
!= dentry
->d_name
.len
)
763 if (!memcmp(dentry
->d_name
.name
, de
->name
, de
->namelen
)) {
764 int ino
= de
->low_ino
| (dir
->i_ino
& ~(0xffff));
766 inode
= proc_get_inode(dir
->i_sb
, ino
, de
);
773 dentry
->d_op
= &proc_dentry_operations
;
774 d_add(dentry
, inode
);
781 static int proc_root_lookup(struct inode
* dir
, struct dentry
* dentry
)
784 struct task_struct
*p
;
789 if (dir
->i_ino
== PROC_ROOT_INO
) { /* check for safety... */
790 dir
->i_nlink
= proc_root
.nlink
;
792 read_lock(&tasklist_lock
);
797 read_unlock(&tasklist_lock
);
800 if (!proc_lookup(dir
, dentry
))
804 name
= dentry
->d_name
.name
;
805 len
= dentry
->d_name
.len
;
815 if (pid
& 0xffff0000) {
820 read_lock(&tasklist_lock
);
821 p
= find_task_by_pid(pid
);
822 read_unlock(&tasklist_lock
);
825 unsigned long ino
= (pid
<< 16) + PROC_PID_INO
;
826 inode
= proc_get_inode(dir
->i_sb
, ino
, &proc_pid
);
831 dentry
->d_op
= &proc_dentry_operations
;
832 d_add(dentry
, inode
);
837 * This returns non-zero if at EOF, so that the /proc
838 * root directory can use this and check if it should
839 * continue with the <pid> entries..
841 * Note that the VFS-layer doesn't care about the return
842 * value of the readdir() call, as long as it's non-negative
845 int proc_readdir(struct file
* filp
,
846 void * dirent
, filldir_t filldir
)
848 struct proc_dir_entry
* de
;
851 struct inode
*inode
= filp
->f_dentry
->d_inode
;
853 if (!inode
|| !S_ISDIR(inode
->i_mode
))
856 de
= (struct proc_dir_entry
*) inode
->u
.generic_ip
;
862 if (filldir(dirent
, ".", 1, i
, ino
) < 0)
868 if (filldir(dirent
, "..", 2, i
, de
->parent
->low_ino
) < 0)
887 if (filldir(dirent
, de
->name
, de
->namelen
, filp
->f_pos
, ino
| de
->low_ino
) < 0)
896 #define PROC_NUMBUF 10
897 #define PROC_MAXPIDS 20
900 * Get a few pid's to return for filldir - we need to hold the
901 * tasklist lock while doing this, and we must release it before
902 * we actually do the filldir itself, so we use a temp buffer..
904 static int get_pid_list(unsigned int index
, unsigned int *pids
)
906 struct task_struct
*p
;
907 int nr
= FIRST_PROCESS_ENTRY
;
910 read_lock(&tasklist_lock
);
920 if (nr_pids
>= PROC_MAXPIDS
)
923 read_unlock(&tasklist_lock
);
927 static int proc_root_readdir(struct file
* filp
,
928 void * dirent
, filldir_t filldir
)
930 unsigned int pid_array
[PROC_MAXPIDS
];
931 char buf
[PROC_NUMBUF
];
932 unsigned int nr
= filp
->f_pos
;
933 unsigned int nr_pids
, i
;
935 if (nr
< FIRST_PROCESS_ENTRY
) {
936 int error
= proc_readdir(filp
, dirent
, filldir
);
939 filp
->f_pos
= nr
= FIRST_PROCESS_ENTRY
;
942 nr_pids
= get_pid_list(nr
, pid_array
);
944 for (i
= 0; i
< nr_pids
; i
++) {
945 int pid
= pid_array
[i
];
946 unsigned long j
= PROC_NUMBUF
;
950 buf
[j
] = '0' + (pid
% 10);
954 if (filldir(dirent
, buf
+j
, PROC_NUMBUF
-j
, filp
->f_pos
, (pid
<< 16) + PROC_PID_INO
) < 0)
961 static int proc_unlink(struct inode
*dir
, struct dentry
*dentry
)
963 struct proc_dir_entry
* dp
= dir
->u
.generic_ip
;
965 printk("proc_file_unlink: deleting %s/%s\n", dp
->name
, dentry
->d_name
.name
);
967 remove_proc_entry(dentry
->d_name
.name
, dp
);
968 dentry
->d_inode
->i_nlink
= 0;