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 */
54 NULL
, /* no special release code */
55 NULL
/* can't fsync */
58 int proc_readlink(struct dentry
* dentry
, char * buffer
, int buflen
);
59 struct dentry
* proc_follow_link(struct dentry
*dentry
, struct dentry
*base
);
62 * proc directories can do almost nothing..
64 struct inode_operations proc_dir_inode_operations
= {
65 &proc_dir_operations
, /* default net directory file-ops */
67 proc_lookup
, /* lookup */
76 NULL
, /* follow_link */
85 * /proc dynamic directories now support unlinking
87 struct inode_operations proc_dyna_dir_inode_operations
= {
88 &proc_dir_operations
, /* default proc dir ops */
90 proc_lookup
, /* lookup */
92 proc_unlink
, /* unlink(struct inode *, struct dentry *) */
99 NULL
, /* follow_link */
101 NULL
, /* writepage */
104 NULL
/* permission */
108 * The root /proc directory is special, as it has the
109 * <pid> directories. Thus we don't use the generic
110 * directory handling functions for that..
112 static struct file_operations proc_root_operations
= {
113 NULL
, /* lseek - default */
114 NULL
, /* read - bad */
115 NULL
, /* write - bad */
116 proc_root_readdir
, /* readdir */
117 NULL
, /* poll - default */
118 NULL
, /* ioctl - default */
120 NULL
, /* no special open code */
122 NULL
, /* no special release code */
127 * proc root can do almost nothing..
129 static struct inode_operations proc_root_inode_operations
= {
130 &proc_root_operations
, /* default base directory file-ops */
132 proc_root_lookup
, /* lookup */
141 NULL
, /* follow_link */
143 NULL
, /* writepage */
146 NULL
/* permission */
150 * This is the root "inode" in the /proc tree..
152 struct proc_dir_entry proc_root
= {
153 PROC_ROOT_INO
, 5, "/proc",
154 S_IFDIR
| S_IRUGO
| S_IXUGO
, 2, 0, 0,
155 0, &proc_root_inode_operations
,
161 struct proc_dir_entry
*proc_net
, *proc_scsi
, *proc_bus
;
164 struct proc_dir_entry proc_mca
= {
166 S_IFDIR
| S_IRUGO
| S_IXUGO
, 2, 0, 0,
167 0, &proc_dir_inode_operations
,
169 NULL
, &proc_root
, NULL
174 struct proc_dir_entry proc_sys_root
= {
175 PROC_SYS
, 3, "sys", /* inode, name */
176 S_IFDIR
| S_IRUGO
| S_IXUGO
, 2, 0, 0, /* mode, nlink, uid, gid */
177 0, &proc_dir_inode_operations
, /* size, ops */
178 NULL
, NULL
, /* get_info, fill_inode */
180 NULL
, NULL
/* parent, subdir */
184 #if defined(CONFIG_SUN_OPENPROMFS) || defined(CONFIG_SUN_OPENPROMFS_MODULE)
186 static int (*proc_openprom_defreaddir_ptr
)(struct file
*, void *, filldir_t
);
187 static int (*proc_openprom_deflookup_ptr
)(struct inode
*, struct dentry
*);
188 void (*proc_openprom_use
)(struct inode
*, int) = 0;
189 static struct openpromfs_dev
*proc_openprom_devices
= NULL
;
190 static ino_t proc_openpromdev_ino
= PROC_OPENPROMD_FIRST
;
192 struct inode_operations
*
193 proc_openprom_register(int (*readdir
)(struct file
*, void *, filldir_t
),
194 int (*lookup
)(struct inode
*, struct dentry
*),
195 void (*use
)(struct inode
*, int),
196 struct openpromfs_dev
***devices
)
198 proc_openprom_defreaddir_ptr
= (proc_openprom_inode_operations
.default_file_ops
)->readdir
;
199 proc_openprom_deflookup_ptr
= proc_openprom_inode_operations
.lookup
;
200 (proc_openprom_inode_operations
.default_file_ops
)->readdir
= readdir
;
201 proc_openprom_inode_operations
.lookup
= lookup
;
202 proc_openprom_use
= use
;
203 *devices
= &proc_openprom_devices
;
204 return &proc_openprom_inode_operations
;
207 int proc_openprom_regdev(struct openpromfs_dev
*d
)
209 if (proc_openpromdev_ino
== PROC_OPENPROMD_FIRST
+ PROC_NOPENPROMD
)
211 d
->next
= proc_openprom_devices
;
212 d
->inode
= proc_openpromdev_ino
++;
213 proc_openprom_devices
= d
;
217 int proc_openprom_unregdev(struct openpromfs_dev
*d
)
219 if (d
== proc_openprom_devices
) {
220 proc_openprom_devices
= d
->next
;
221 } else if (!proc_openprom_devices
)
224 struct openpromfs_dev
*p
;
226 for (p
= proc_openprom_devices
; p
->next
!= d
&& p
->next
; p
= p
->next
);
227 if (!p
->next
) return -1;
233 #ifdef CONFIG_SUN_OPENPROMFS_MODULE
235 proc_openprom_deregister(void)
237 (proc_openprom_inode_operations
.default_file_ops
)->readdir
= proc_openprom_defreaddir_ptr
;
238 proc_openprom_inode_operations
.lookup
= proc_openprom_deflookup_ptr
;
239 proc_openprom_use
= 0;
243 #if defined(CONFIG_SUN_OPENPROMFS_MODULE) && defined(CONFIG_KMOD)
245 proc_openprom_defreaddir(struct file
* filp
, void * dirent
, filldir_t filldir
)
247 request_module("openpromfs");
248 if ((proc_openprom_inode_operations
.default_file_ops
)->readdir
!=
249 proc_openprom_defreaddir
)
250 return (proc_openprom_inode_operations
.default_file_ops
)->readdir
251 (filp
, dirent
, filldir
);
254 #define OPENPROM_DEFREADDIR proc_openprom_defreaddir
257 proc_openprom_deflookup(struct inode
* dir
, struct dentry
*dentry
)
259 request_module("openpromfs");
260 if (proc_openprom_inode_operations
.lookup
!=
261 proc_openprom_deflookup
)
262 return proc_openprom_inode_operations
.lookup
266 #define OPENPROM_DEFLOOKUP proc_openprom_deflookup
268 #define OPENPROM_DEFREADDIR NULL
269 #define OPENPROM_DEFLOOKUP NULL
272 static struct file_operations proc_openprom_operations
= {
273 NULL
, /* lseek - default */
274 NULL
, /* read - bad */
275 NULL
, /* write - bad */
276 OPENPROM_DEFREADDIR
, /* readdir */
277 NULL
, /* poll - default */
278 NULL
, /* ioctl - default */
280 NULL
, /* no special open code */
282 NULL
, /* no special release code */
283 NULL
/* can't fsync */
286 struct inode_operations proc_openprom_inode_operations
= {
287 &proc_openprom_operations
,/* default net directory file-ops */
289 OPENPROM_DEFLOOKUP
, /* lookup */
298 NULL
, /* follow_link */
300 NULL
, /* writepage */
303 NULL
/* permission */
306 struct proc_dir_entry proc_openprom
= {
307 PROC_OPENPROM
, 8, "openprom",
308 S_IFDIR
| S_IRUGO
| S_IXUGO
, 2, 0, 0,
309 0, &proc_openprom_inode_operations
,
315 extern void openpromfs_init (void);
316 #endif /* CONFIG_SUN_OPENPROMFS */
318 static int make_inode_number(void)
320 int i
= find_first_zero_bit((void *) proc_alloc_map
, PROC_NDYNAMIC
);
321 if (i
<0 || i
>=PROC_NDYNAMIC
)
323 set_bit(i
, (void *) proc_alloc_map
);
324 return PROC_DYNAMIC_FIRST
+ i
;
327 int proc_register(struct proc_dir_entry
* dir
, struct proc_dir_entry
* dp
)
331 if (dp
->low_ino
== 0) {
332 i
= make_inode_number();
337 dp
->next
= dir
->subdir
;
340 if (S_ISDIR(dp
->mode
)) {
342 dp
->ops
= &proc_dir_inode_operations
;
344 } else if (S_ISLNK(dp
->mode
)) {
346 dp
->ops
= &proc_link_inode_operations
;
349 dp
->ops
= &proc_file_inode_operations
;
354 int proc_unregister(struct proc_dir_entry
* dir
, int ino
)
356 struct proc_dir_entry
**p
= &dir
->subdir
, *dp
;
358 while ((dp
= *p
) != NULL
) {
359 if (dp
->low_ino
== ino
) {
362 if (S_ISDIR(dp
->mode
))
364 if (ino
>= PROC_DYNAMIC_FIRST
&&
365 ino
< PROC_DYNAMIC_FIRST
+PROC_NDYNAMIC
)
366 clear_bit(ino
-PROC_DYNAMIC_FIRST
,
367 (void *) proc_alloc_map
);
378 static int proc_self_readlink(struct dentry
*dentry
, char *buffer
, int buflen
)
383 len
= sprintf(tmp
, "%d", current
->pid
);
386 copy_to_user(buffer
, tmp
, len
);
390 static struct dentry
* proc_self_follow_link(struct dentry
*dentry
,
395 sprintf(tmp
, "%d", current
->pid
);
396 return lookup_dentry(tmp
, base
, 1);
399 int proc_readlink(struct dentry
* dentry
, char * buffer
, int buflen
)
401 struct inode
*inode
= dentry
->d_inode
;
402 struct proc_dir_entry
* de
;
406 de
= (struct proc_dir_entry
*) inode
->u
.generic_ip
;
409 if (!(page
= (char*) __get_free_page(GFP_KERNEL
)))
412 if (de
->readlink_proc
)
413 len
= de
->readlink_proc(de
, page
);
418 copy_to_user(buffer
, page
, len
);
419 free_page((unsigned long) page
);
423 struct dentry
* proc_follow_link(struct dentry
* dentry
, struct dentry
*base
)
425 struct inode
*inode
= dentry
->d_inode
;
426 struct proc_dir_entry
* de
;
431 de
= (struct proc_dir_entry
*) inode
->u
.generic_ip
;
432 if (!(page
= (char*) __get_free_page(GFP_KERNEL
)))
435 if (de
->readlink_proc
)
436 len
= de
->readlink_proc(de
, page
);
438 d
= lookup_dentry(page
, base
, 1);
439 free_page((unsigned long) page
);
443 static struct inode_operations proc_self_inode_operations
= {
444 NULL
, /* no file-ops */
454 proc_self_readlink
, /* readlink */
455 proc_self_follow_link
, /* follow_link */
457 NULL
, /* writepage */
460 NULL
/* permission */
463 static struct inode_operations proc_link_inode_operations
= {
464 NULL
, /* no file-ops */
474 proc_readlink
, /* readlink */
475 proc_follow_link
, /* follow_link */
477 NULL
, /* writepage */
480 NULL
/* permission */
483 static struct proc_dir_entry proc_root_loadavg
= {
484 PROC_LOADAVG
, 7, "loadavg",
485 S_IFREG
| S_IRUGO
, 1, 0, 0,
486 0, &proc_array_inode_operations
488 static struct proc_dir_entry proc_root_uptime
= {
489 PROC_UPTIME
, 6, "uptime",
490 S_IFREG
| S_IRUGO
, 1, 0, 0,
491 0, &proc_array_inode_operations
493 static struct proc_dir_entry proc_root_meminfo
= {
494 PROC_MEMINFO
, 7, "meminfo",
495 S_IFREG
| S_IRUGO
, 1, 0, 0,
496 0, &proc_array_inode_operations
498 static struct proc_dir_entry proc_root_kmsg
= {
499 PROC_KMSG
, 4, "kmsg",
500 S_IFREG
| S_IRUSR
, 1, 0, 0,
501 0, &proc_kmsg_inode_operations
503 static struct proc_dir_entry proc_root_version
= {
504 PROC_VERSION
, 7, "version",
505 S_IFREG
| S_IRUGO
, 1, 0, 0,
506 0, &proc_array_inode_operations
508 static struct proc_dir_entry proc_root_cpuinfo
= {
509 PROC_CPUINFO
, 7, "cpuinfo",
510 S_IFREG
| S_IRUGO
, 1, 0, 0,
511 0, &proc_array_inode_operations
513 #if defined (CONFIG_PROC_HARDWARE)
514 static struct proc_dir_entry proc_root_hardware
= {
515 PROC_HARDWARE
, 8, "hardware",
516 S_IFREG
| S_IRUGO
, 1, 0, 0,
517 0, &proc_array_inode_operations
520 #ifdef CONFIG_STRAM_PROC
521 static struct proc_dir_entry proc_root_stram
= {
522 PROC_STRAM
, 5, "stram",
523 S_IFREG
| S_IRUGO
, 1, 0, 0,
524 0, &proc_array_inode_operations
527 static struct proc_dir_entry proc_root_self
= {
528 PROC_SELF
, 4, "self",
529 S_IFLNK
| S_IRUGO
| S_IWUGO
| S_IXUGO
, 1, 0, 0,
530 64, &proc_self_inode_operations
,
532 #ifdef CONFIG_DEBUG_MALLOC
533 static struct proc_dir_entry proc_root_malloc
= {
534 PROC_MALLOC
, 6, "malloc",
535 S_IFREG
| S_IRUGO
, 1, 0, 0,
536 0, &proc_array_inode_operations
539 static struct proc_dir_entry proc_root_kcore
= {
540 PROC_KCORE
, 5, "kcore",
541 S_IFREG
| S_IRUSR
, 1, 0, 0,
542 0, &proc_kcore_inode_operations
544 #ifdef CONFIG_MODULES
545 static struct proc_dir_entry proc_root_modules
= {
546 PROC_MODULES
, 7, "modules",
547 S_IFREG
| S_IRUGO
, 1, 0, 0,
548 0, &proc_array_inode_operations
550 static struct proc_dir_entry proc_root_ksyms
= {
551 PROC_KSYMS
, 5, "ksyms",
552 S_IFREG
| S_IRUGO
, 1, 0, 0,
553 0, &proc_array_inode_operations
556 static struct proc_dir_entry proc_root_stat
= {
557 PROC_STAT
, 4, "stat",
558 S_IFREG
| S_IRUGO
, 1, 0, 0,
559 0, &proc_array_inode_operations
561 static struct proc_dir_entry proc_root_devices
= {
562 PROC_DEVICES
, 7, "devices",
563 S_IFREG
| S_IRUGO
, 1, 0, 0,
564 0, &proc_array_inode_operations
566 static struct proc_dir_entry proc_root_partitions
= {
567 PROC_PARTITIONS
, 10, "partitions",
568 S_IFREG
| S_IRUGO
, 1, 0, 0,
569 0, &proc_array_inode_operations
571 static struct proc_dir_entry proc_root_interrupts
= {
572 PROC_INTERRUPTS
, 10,"interrupts",
573 S_IFREG
| S_IRUGO
, 1, 0, 0,
574 0, &proc_array_inode_operations
576 static struct proc_dir_entry proc_root_filesystems
= {
577 PROC_FILESYSTEMS
, 11,"filesystems",
578 S_IFREG
| S_IRUGO
, 1, 0, 0,
579 0, &proc_array_inode_operations
581 struct proc_dir_entry proc_root_fs
= {
583 S_IFDIR
| S_IRUGO
| S_IXUGO
, 2, 0, 0,
584 0, &proc_dir_inode_operations
,
589 static struct proc_dir_entry proc_root_dma
= {
591 S_IFREG
| S_IRUGO
, 1, 0, 0,
592 0, &proc_array_inode_operations
594 static struct proc_dir_entry proc_root_ioports
= {
595 PROC_IOPORTS
, 7, "ioports",
596 S_IFREG
| S_IRUGO
, 1, 0, 0,
597 0, &proc_array_inode_operations
599 static struct proc_dir_entry proc_root_cmdline
= {
600 PROC_CMDLINE
, 7, "cmdline",
601 S_IFREG
| S_IRUGO
, 1, 0, 0,
602 0, &proc_array_inode_operations
605 static struct proc_dir_entry proc_root_rtc
= {
607 S_IFREG
| S_IRUGO
, 1, 0, 0,
608 0, &proc_array_inode_operations
611 static struct proc_dir_entry proc_root_locks
= {
612 PROC_LOCKS
, 5, "locks",
613 S_IFREG
| S_IRUGO
, 1, 0, 0,
614 0, &proc_array_inode_operations
616 static struct proc_dir_entry proc_root_mounts
= {
617 PROC_MTAB
, 6, "mounts",
618 S_IFREG
| S_IRUGO
, 1, 0, 0,
619 0, &proc_array_inode_operations
621 static struct proc_dir_entry proc_root_swaps
= {
622 PROC_SWAP
, 5, "swaps",
623 S_IFREG
| S_IRUGO
, 1, 0, 0,
624 0, &proc_array_inode_operations
626 static struct proc_dir_entry proc_root_profile
= {
627 PROC_PROFILE
, 7, "profile",
628 S_IFREG
| S_IRUGO
| S_IWUSR
, 1, 0, 0,
629 0, &proc_profile_inode_operations
631 static struct proc_dir_entry proc_root_slab
= {
632 PROC_SLABINFO
, 8, "slabinfo",
633 S_IFREG
| S_IRUGO
, 1, 0, 0,
634 0, &proc_array_inode_operations
637 static struct proc_dir_entry proc_root_ppc_htab
= {
638 PROC_PPC_HTAB
, 8, "ppc_htab",
639 S_IFREG
| S_IRUSR
|S_IWUSR
|S_IRGRP
|S_IROTH
, 1, 0, 0,
640 0, &proc_ppc_htab_inode_operations
,
641 NULL
, NULL
, /* get_info, fill_inode */
643 NULL
, NULL
/* parent, subdir */
647 __initfunc(void proc_root_init(void))
650 proc_register(&proc_root
, &proc_root_loadavg
);
651 proc_register(&proc_root
, &proc_root_uptime
);
652 proc_register(&proc_root
, &proc_root_meminfo
);
653 proc_register(&proc_root
, &proc_root_kmsg
);
654 proc_register(&proc_root
, &proc_root_version
);
655 proc_register(&proc_root
, &proc_root_cpuinfo
);
656 proc_register(&proc_root
, &proc_root_self
);
657 proc_net
= create_proc_entry("net", S_IFDIR
, 0);
658 proc_scsi
= create_proc_entry("scsi", S_IFDIR
, 0);
660 proc_register(&proc_root
, &proc_sys_root
);
663 proc_register(&proc_root
, &proc_mca
);
666 #ifdef CONFIG_DEBUG_MALLOC
667 proc_register(&proc_root
, &proc_root_malloc
);
669 proc_register(&proc_root
, &proc_root_kcore
);
670 proc_root_kcore
.size
= (MAP_NR(high_memory
) << PAGE_SHIFT
) + PAGE_SIZE
;
672 #ifdef CONFIG_MODULES
673 proc_register(&proc_root
, &proc_root_modules
);
674 proc_register(&proc_root
, &proc_root_ksyms
);
676 proc_register(&proc_root
, &proc_root_stat
);
677 proc_register(&proc_root
, &proc_root_devices
);
678 proc_register(&proc_root
, &proc_root_partitions
);
679 proc_register(&proc_root
, &proc_root_interrupts
);
680 proc_register(&proc_root
, &proc_root_filesystems
);
681 proc_register(&proc_root
, &proc_root_fs
);
682 proc_register(&proc_root
, &proc_root_dma
);
683 proc_register(&proc_root
, &proc_root_ioports
);
684 proc_register(&proc_root
, &proc_root_cmdline
);
686 proc_register(&proc_root
, &proc_root_rtc
);
688 proc_register(&proc_root
, &proc_root_locks
);
690 proc_register(&proc_root
, &proc_root_mounts
);
691 proc_register(&proc_root
, &proc_root_swaps
);
693 #if defined(CONFIG_SUN_OPENPROMFS) || defined(CONFIG_SUN_OPENPROMFS_MODULE)
694 #ifdef CONFIG_SUN_OPENPROMFS
697 proc_register(&proc_root
, &proc_openprom
);
699 #ifdef CONFIG_PROC_HARDWARE
700 proc_register(&proc_root
, &proc_root_hardware
);
702 #ifdef CONFIG_STRAM_PROC
703 proc_register(&proc_root
, &proc_root_stram
);
705 proc_register(&proc_root
, &proc_root_slab
);
708 proc_register(&proc_root
, &proc_root_profile
);
709 proc_root_profile
.size
= (1+prof_len
) * sizeof(unsigned int);
714 proc_register(&proc_root
, &proc_root_ppc_htab
);
716 #ifdef CONFIG_PROC_DEVICETREE
717 proc_device_tree_init();
720 proc_bus
= create_proc_entry("bus", S_IFDIR
, 0);
724 * As some entries in /proc are volatile, we want to
725 * get rid of unused dentries. This could be made
726 * smarter: we could keep a "volatile" flag in the
727 * inode to indicate which ones to keep.
730 proc_delete_dentry(struct dentry
* dentry
)
735 static struct dentry_operations proc_dentry_operations
=
737 NULL
, /* revalidate */
739 NULL
, /* d_compare */
740 proc_delete_dentry
/* d_delete(struct dentry *) */
744 * Don't create negative dentries here, return -ENOENT by hand
747 int proc_lookup(struct inode
* dir
, struct dentry
*dentry
)
750 struct proc_dir_entry
* de
;
754 if (!dir
|| !S_ISDIR(dir
->i_mode
))
759 de
= (struct proc_dir_entry
*) dir
->u
.generic_ip
;
761 for (de
= de
->subdir
; de
; de
= de
->next
) {
762 if (!de
|| !de
->low_ino
)
764 if (de
->namelen
!= dentry
->d_name
.len
)
766 if (!memcmp(dentry
->d_name
.name
, de
->name
, de
->namelen
)) {
767 int ino
= de
->low_ino
| (dir
->i_ino
& ~(0xffff));
769 inode
= proc_get_inode(dir
->i_sb
, ino
, de
);
776 dentry
->d_op
= &proc_dentry_operations
;
777 d_add(dentry
, inode
);
784 static int proc_root_lookup(struct inode
* dir
, struct dentry
* dentry
)
787 struct task_struct
*p
;
792 if (dir
->i_ino
== PROC_ROOT_INO
) { /* check for safety... */
793 dir
->i_nlink
= proc_root
.nlink
;
795 read_lock(&tasklist_lock
);
800 read_unlock(&tasklist_lock
);
803 if (!proc_lookup(dir
, dentry
))
807 name
= dentry
->d_name
.name
;
808 len
= dentry
->d_name
.len
;
818 if (pid
& 0xffff0000) {
823 read_lock(&tasklist_lock
);
824 p
= find_task_by_pid(pid
);
825 read_unlock(&tasklist_lock
);
828 unsigned long ino
= (pid
<< 16) + PROC_PID_INO
;
829 inode
= proc_get_inode(dir
->i_sb
, ino
, &proc_pid
);
834 dentry
->d_op
= &proc_dentry_operations
;
835 d_add(dentry
, inode
);
840 * This returns non-zero if at EOF, so that the /proc
841 * root directory can use this and check if it should
842 * continue with the <pid> entries..
844 * Note that the VFS-layer doesn't care about the return
845 * value of the readdir() call, as long as it's non-negative
848 int proc_readdir(struct file
* filp
,
849 void * dirent
, filldir_t filldir
)
851 struct proc_dir_entry
* de
;
854 struct inode
*inode
= filp
->f_dentry
->d_inode
;
856 if (!inode
|| !S_ISDIR(inode
->i_mode
))
859 de
= (struct proc_dir_entry
*) inode
->u
.generic_ip
;
865 if (filldir(dirent
, ".", 1, i
, ino
) < 0)
871 if (filldir(dirent
, "..", 2, i
, de
->parent
->low_ino
) < 0)
890 if (filldir(dirent
, de
->name
, de
->namelen
, filp
->f_pos
, ino
| de
->low_ino
) < 0)
899 #define PROC_NUMBUF 10
900 #define PROC_MAXPIDS 20
903 * Get a few pid's to return for filldir - we need to hold the
904 * tasklist lock while doing this, and we must release it before
905 * we actually do the filldir itself, so we use a temp buffer..
907 static int get_pid_list(int index
, unsigned int *pids
)
909 struct task_struct
*p
;
912 index
-= FIRST_PROCESS_ENTRY
;
913 read_lock(&tasklist_lock
);
922 if (nr_pids
>= PROC_MAXPIDS
)
925 read_unlock(&tasklist_lock
);
929 static int proc_root_readdir(struct file
* filp
,
930 void * dirent
, filldir_t filldir
)
932 unsigned int pid_array
[PROC_MAXPIDS
];
933 char buf
[PROC_NUMBUF
];
934 unsigned int nr
= filp
->f_pos
;
935 unsigned int nr_pids
, i
;
937 if (nr
< FIRST_PROCESS_ENTRY
) {
938 int error
= proc_readdir(filp
, dirent
, filldir
);
941 filp
->f_pos
= nr
= FIRST_PROCESS_ENTRY
;
944 nr_pids
= get_pid_list(nr
, pid_array
);
946 for (i
= 0; i
< nr_pids
; i
++) {
947 int pid
= pid_array
[i
];
948 unsigned long j
= PROC_NUMBUF
;
952 buf
[j
] = '0' + (pid
% 10);
956 if (filldir(dirent
, buf
+j
, PROC_NUMBUF
-j
, filp
->f_pos
, (pid
<< 16) + PROC_PID_INO
) < 0)
963 static int proc_unlink(struct inode
*dir
, struct dentry
*dentry
)
965 struct proc_dir_entry
* dp
= dir
->u
.generic_ip
;
967 printk("proc_file_unlink: deleting %s/%s\n", dp
->name
, dentry
->d_name
.name
);
969 remove_proc_entry(dentry
->d_name
.name
, dp
);
970 dentry
->d_inode
->i_nlink
= 0;