OpenCores
URL https://opencores.org/ocsvn/or1k_old/or1k_old/trunk

Subversion Repositories or1k_old

[/] [or1k_old/] [trunk/] [rc203soc/] [sw/] [uClinux/] [fs/] [proc/] [root.c] - Diff between revs 1765 and 1782

Only display areas with differences | Details | Blame | View Log

Rev 1765 Rev 1782
/*
/*
 *  linux/fs/proc/root.c
 *  linux/fs/proc/root.c
 *
 *
 *  Copyright (C) 1991, 1992 Linus Torvalds
 *  Copyright (C) 1991, 1992 Linus Torvalds
 *
 *
 *  proc root directory handling functions
 *  proc root directory handling functions
 */
 */
 
 
#include <asm/segment.h>
#include <asm/segment.h>
 
 
#include <linux/errno.h>
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/sched.h>
#include <linux/proc_fs.h>
#include <linux/proc_fs.h>
#include <linux/stat.h>
#include <linux/stat.h>
#include <linux/config.h>
#include <linux/config.h>
#include <asm/bitops.h>
#include <asm/bitops.h>
 
 
/*
/*
 * Offset of the first process in the /proc root directory..
 * Offset of the first process in the /proc root directory..
 */
 */
#define FIRST_PROCESS_ENTRY 256
#define FIRST_PROCESS_ENTRY 256
 
 
static int proc_root_readdir(struct inode *, struct file *, void *, filldir_t);
static int proc_root_readdir(struct inode *, struct file *, void *, filldir_t);
static int proc_root_lookup(struct inode *,const char *,int,struct inode **);
static int proc_root_lookup(struct inode *,const char *,int,struct inode **);
 
 
static unsigned char proc_alloc_map[PROC_NDYNAMIC / 8] = {0};
static unsigned char proc_alloc_map[PROC_NDYNAMIC / 8] = {0};
 
 
/*
/*
 * These are the generic /proc directory operations. They
 * These are the generic /proc directory operations. They
 * use the in-memory "struct proc_dir_entry" tree to parse
 * use the in-memory "struct proc_dir_entry" tree to parse
 * the /proc directory.
 * the /proc directory.
 *
 *
 * NOTE! The /proc/scsi directory currently does not correctly
 * NOTE! The /proc/scsi directory currently does not correctly
 * build up the proc_dir_entry tree, and will show up empty.
 * build up the proc_dir_entry tree, and will show up empty.
 */
 */
static struct file_operations proc_dir_operations = {
static struct file_operations proc_dir_operations = {
        NULL,                   /* lseek - default */
        NULL,                   /* lseek - default */
        NULL,                   /* read - bad */
        NULL,                   /* read - bad */
        NULL,                   /* write - bad */
        NULL,                   /* write - bad */
        proc_readdir,           /* readdir */
        proc_readdir,           /* readdir */
        NULL,                   /* select - default */
        NULL,                   /* select - default */
        NULL,                   /* ioctl - default */
        NULL,                   /* ioctl - default */
        NULL,                   /* mmap */
        NULL,                   /* mmap */
        NULL,                   /* no special open code */
        NULL,                   /* no special open code */
        NULL,                   /* no special release code */
        NULL,                   /* no special release code */
        NULL                    /* can't fsync */
        NULL                    /* can't fsync */
};
};
 
 
/*
/*
 * proc directories can do almost nothing..
 * proc directories can do almost nothing..
 */
 */
struct inode_operations proc_dir_inode_operations = {
struct inode_operations proc_dir_inode_operations = {
        &proc_dir_operations,   /* default net directory file-ops */
        &proc_dir_operations,   /* default net directory file-ops */
        NULL,                   /* create */
        NULL,                   /* create */
        proc_lookup,            /* lookup */
        proc_lookup,            /* lookup */
        NULL,                   /* link */
        NULL,                   /* link */
        NULL,                   /* unlink */
        NULL,                   /* unlink */
        NULL,                   /* symlink */
        NULL,                   /* symlink */
        NULL,                   /* mkdir */
        NULL,                   /* mkdir */
        NULL,                   /* rmdir */
        NULL,                   /* rmdir */
        NULL,                   /* mknod */
        NULL,                   /* mknod */
        NULL,                   /* rename */
        NULL,                   /* rename */
        NULL,                   /* readlink */
        NULL,                   /* readlink */
        NULL,                   /* follow_link */
        NULL,                   /* follow_link */
        NULL,                   /* readpage */
        NULL,                   /* readpage */
        NULL,                   /* writepage */
        NULL,                   /* writepage */
        NULL,                   /* bmap */
        NULL,                   /* bmap */
        NULL,                   /* truncate */
        NULL,                   /* truncate */
        NULL                    /* permission */
        NULL                    /* permission */
};
};
 
 
/*
/*
 * The root /proc directory is special, as it has the
 * The root /proc directory is special, as it has the
 * <pid> directories. Thus we don't use the generic
 * <pid> directories. Thus we don't use the generic
 * directory handling functions for that..
 * directory handling functions for that..
 */
 */
static struct file_operations proc_root_operations = {
static struct file_operations proc_root_operations = {
        NULL,                   /* lseek - default */
        NULL,                   /* lseek - default */
        NULL,                   /* read - bad */
        NULL,                   /* read - bad */
        NULL,                   /* write - bad */
        NULL,                   /* write - bad */
        proc_root_readdir,      /* readdir */
        proc_root_readdir,      /* readdir */
        NULL,                   /* select - default */
        NULL,                   /* select - default */
        NULL,                   /* ioctl - default */
        NULL,                   /* ioctl - default */
        NULL,                   /* mmap */
        NULL,                   /* mmap */
        NULL,                   /* no special open code */
        NULL,                   /* no special open code */
        NULL,                   /* no special release code */
        NULL,                   /* no special release code */
        NULL                    /* no fsync */
        NULL                    /* no fsync */
};
};
 
 
/*
/*
 * proc root can do almost nothing..
 * proc root can do almost nothing..
 */
 */
static struct inode_operations proc_root_inode_operations = {
static struct inode_operations proc_root_inode_operations = {
        &proc_root_operations,  /* default base directory file-ops */
        &proc_root_operations,  /* default base directory file-ops */
        NULL,                   /* create */
        NULL,                   /* create */
        proc_root_lookup,       /* lookup */
        proc_root_lookup,       /* lookup */
        NULL,                   /* link */
        NULL,                   /* link */
        NULL,                   /* unlink */
        NULL,                   /* unlink */
        NULL,                   /* symlink */
        NULL,                   /* symlink */
        NULL,                   /* mkdir */
        NULL,                   /* mkdir */
        NULL,                   /* rmdir */
        NULL,                   /* rmdir */
        NULL,                   /* mknod */
        NULL,                   /* mknod */
        NULL,                   /* rename */
        NULL,                   /* rename */
        NULL,                   /* readlink */
        NULL,                   /* readlink */
        NULL,                   /* follow_link */
        NULL,                   /* follow_link */
        NULL,                   /* readpage */
        NULL,                   /* readpage */
        NULL,                   /* writepage */
        NULL,                   /* writepage */
        NULL,                   /* bmap */
        NULL,                   /* bmap */
        NULL,                   /* truncate */
        NULL,                   /* truncate */
        NULL                    /* permission */
        NULL                    /* permission */
};
};
 
 
/*
/*
 * This is the root "inode" in the /proc tree..
 * This is the root "inode" in the /proc tree..
 */
 */
struct proc_dir_entry proc_root = {
struct proc_dir_entry proc_root = {
        PROC_ROOT_INO, 5, "/proc",
        PROC_ROOT_INO, 5, "/proc",
        S_IFDIR | S_IRUGO | S_IXUGO, 2, 0, 0,
        S_IFDIR | S_IRUGO | S_IXUGO, 2, 0, 0,
        0, &proc_root_inode_operations,
        0, &proc_root_inode_operations,
        NULL, NULL,
        NULL, NULL,
        NULL,
        NULL,
        &proc_root, NULL
        &proc_root, NULL
};
};
 
 
struct proc_dir_entry proc_net = {
struct proc_dir_entry proc_net = {
        PROC_NET, 3, "net",
        PROC_NET, 3, "net",
        S_IFDIR | S_IRUGO | S_IXUGO, 2, 0, 0,
        S_IFDIR | S_IRUGO | S_IXUGO, 2, 0, 0,
        0, &proc_dir_inode_operations,
        0, &proc_dir_inode_operations,
        NULL, NULL,
        NULL, NULL,
        NULL,
        NULL,
        NULL, NULL
        NULL, NULL
};
};
 
 
struct proc_dir_entry proc_scsi = {
struct proc_dir_entry proc_scsi = {
        PROC_SCSI, 4, "scsi",
        PROC_SCSI, 4, "scsi",
        S_IFDIR | S_IRUGO | S_IXUGO, 2, 0, 0,
        S_IFDIR | S_IRUGO | S_IXUGO, 2, 0, 0,
        0, &proc_dir_inode_operations,
        0, &proc_dir_inode_operations,
        NULL, NULL,
        NULL, NULL,
        NULL, &proc_root, NULL
        NULL, &proc_root, NULL
};
};
 
 
struct proc_dir_entry proc_sys_root = {
struct proc_dir_entry proc_sys_root = {
        PROC_SYS, 3, "sys",                     /* inode, name */
        PROC_SYS, 3, "sys",                     /* inode, name */
        S_IFDIR | S_IRUGO | S_IXUGO, 2, 0, 0,     /* mode, nlink, uid, gid */
        S_IFDIR | S_IRUGO | S_IXUGO, 2, 0, 0,     /* mode, nlink, uid, gid */
        0, &proc_dir_inode_operations,           /* size, ops */
        0, &proc_dir_inode_operations,           /* size, ops */
        NULL, NULL,                             /* get_info, fill_inode */
        NULL, NULL,                             /* get_info, fill_inode */
        NULL,                                   /* next */
        NULL,                                   /* next */
        NULL, NULL                              /* parent, subdir */
        NULL, NULL                              /* parent, subdir */
};
};
 
 
int proc_register(struct proc_dir_entry * dir, struct proc_dir_entry * dp)
int proc_register(struct proc_dir_entry * dir, struct proc_dir_entry * dp)
{
{
        dp->next = dir->subdir;
        dp->next = dir->subdir;
        dp->parent = dir;
        dp->parent = dir;
        dir->subdir = dp;
        dir->subdir = dp;
        if (S_ISDIR(dp->mode))
        if (S_ISDIR(dp->mode))
                dir->nlink++;
                dir->nlink++;
        return 0;
        return 0;
}
}
 
 
int proc_unregister(struct proc_dir_entry * dir, int ino)
int proc_unregister(struct proc_dir_entry * dir, int ino)
{
{
        struct proc_dir_entry **p = &dir->subdir, *dp;
        struct proc_dir_entry **p = &dir->subdir, *dp;
 
 
        while ((dp = *p) != NULL) {
        while ((dp = *p) != NULL) {
                if (dp->low_ino == ino) {
                if (dp->low_ino == ino) {
                        *p = dp->next;
                        *p = dp->next;
                        dp->next = NULL;
                        dp->next = NULL;
                        if (S_ISDIR(dp->mode))
                        if (S_ISDIR(dp->mode))
                                dir->nlink--;
                                dir->nlink--;
                        if (ino >= PROC_DYNAMIC_FIRST &&
                        if (ino >= PROC_DYNAMIC_FIRST &&
                            ino < PROC_DYNAMIC_FIRST+PROC_NDYNAMIC)
                            ino < PROC_DYNAMIC_FIRST+PROC_NDYNAMIC)
                                clear_bit(ino-PROC_DYNAMIC_FIRST,
                                clear_bit(ino-PROC_DYNAMIC_FIRST,
                                          (void *) proc_alloc_map);
                                          (void *) proc_alloc_map);
                        return 0;
                        return 0;
                }
                }
                p = &dp->next;
                p = &dp->next;
        }
        }
        return -EINVAL;
        return -EINVAL;
}
}
 
 
static int make_inode_number(void)
static int make_inode_number(void)
{
{
        int i = find_first_zero_bit((void *) proc_alloc_map, PROC_NDYNAMIC);
        int i = find_first_zero_bit((void *) proc_alloc_map, PROC_NDYNAMIC);
        if (i<0 || i>=PROC_NDYNAMIC)
        if (i<0 || i>=PROC_NDYNAMIC)
                return -1;
                return -1;
        set_bit(i, (void *) proc_alloc_map);
        set_bit(i, (void *) proc_alloc_map);
        return PROC_DYNAMIC_FIRST + i;
        return PROC_DYNAMIC_FIRST + i;
}
}
 
 
int proc_register_dynamic(struct proc_dir_entry * dir,
int proc_register_dynamic(struct proc_dir_entry * dir,
                          struct proc_dir_entry * dp)
                          struct proc_dir_entry * dp)
{
{
        int i = make_inode_number();
        int i = make_inode_number();
        if (i < 0)
        if (i < 0)
                return -EAGAIN;
                return -EAGAIN;
        dp->low_ino = i;
        dp->low_ino = i;
        dp->next = dir->subdir;
        dp->next = dir->subdir;
        dp->parent = dir;
        dp->parent = dir;
        dir->subdir = dp;
        dir->subdir = dp;
        if (S_ISDIR(dp->mode))
        if (S_ISDIR(dp->mode))
                dir->nlink++;
                dir->nlink++;
        return 0;
        return 0;
}
}
 
 
/*
/*
 * /proc/self:
 * /proc/self:
 */
 */
static int proc_self_followlink(struct inode * dir, struct inode * inode,
static int proc_self_followlink(struct inode * dir, struct inode * inode,
                        int flag, int mode, struct inode ** res_inode)
                        int flag, int mode, struct inode ** res_inode)
{
{
        iput(dir);
        iput(dir);
        *res_inode = proc_get_inode(inode->i_sb, (current->pid << 16) + PROC_PID_INO, &proc_pid);
        *res_inode = proc_get_inode(inode->i_sb, (current->pid << 16) + PROC_PID_INO, &proc_pid);
        iput(inode);
        iput(inode);
        if (!*res_inode)
        if (!*res_inode)
                return -ENOENT;
                return -ENOENT;
        return 0;
        return 0;
}
}
 
 
static int proc_self_readlink(struct inode * inode, char * buffer, int buflen)
static int proc_self_readlink(struct inode * inode, char * buffer, int buflen)
{
{
        int len;
        int len;
        char tmp[30];
        char tmp[30];
 
 
        iput(inode);
        iput(inode);
        len = 1 + sprintf(tmp, "%d", current->pid);
        len = 1 + sprintf(tmp, "%d", current->pid);
        if (buflen < len)
        if (buflen < len)
                len = buflen;
                len = buflen;
        memcpy_tofs(buffer, tmp, len);
        memcpy_tofs(buffer, tmp, len);
        return len;
        return len;
}
}
 
 
static struct inode_operations proc_self_inode_operations = {
static struct inode_operations proc_self_inode_operations = {
        NULL,                   /* no file-ops */
        NULL,                   /* no file-ops */
        NULL,                   /* create */
        NULL,                   /* create */
        NULL,                   /* lookup */
        NULL,                   /* lookup */
        NULL,                   /* link */
        NULL,                   /* link */
        NULL,                   /* unlink */
        NULL,                   /* unlink */
        NULL,                   /* symlink */
        NULL,                   /* symlink */
        NULL,                   /* mkdir */
        NULL,                   /* mkdir */
        NULL,                   /* rmdir */
        NULL,                   /* rmdir */
        NULL,                   /* mknod */
        NULL,                   /* mknod */
        NULL,                   /* rename */
        NULL,                   /* rename */
        proc_self_readlink,     /* readlink */
        proc_self_readlink,     /* readlink */
        proc_self_followlink,   /* follow_link */
        proc_self_followlink,   /* follow_link */
        NULL,                   /* readpage */
        NULL,                   /* readpage */
        NULL,                   /* writepage */
        NULL,                   /* writepage */
        NULL,                   /* bmap */
        NULL,                   /* bmap */
        NULL,                   /* truncate */
        NULL,                   /* truncate */
        NULL                    /* permission */
        NULL                    /* permission */
};
};
 
 
struct proc_dir_entry pde_loadavg = {
struct proc_dir_entry pde_loadavg = {
                PROC_LOADAVG, 7, "loadavg",
                PROC_LOADAVG, 7, "loadavg",
                S_IFREG | S_IRUGO, 1, 0, 0,
                S_IFREG | S_IRUGO, 1, 0, 0,
};
};
struct proc_dir_entry pde_uptime = {
struct proc_dir_entry pde_uptime = {
                PROC_UPTIME, 6, "uptime",
                PROC_UPTIME, 6, "uptime",
                S_IFREG | S_IRUGO, 1, 0, 0,
                S_IFREG | S_IRUGO, 1, 0, 0,
};
};
struct proc_dir_entry pde_meminfo = {
struct proc_dir_entry pde_meminfo = {
                PROC_MEMINFO, 7, "meminfo",
                PROC_MEMINFO, 7, "meminfo",
                S_IFREG | S_IRUGO, 1, 0, 0,
                S_IFREG | S_IRUGO, 1, 0, 0,
};
};
struct proc_dir_entry pde_serial = {
struct proc_dir_entry pde_serial = {
                PROC_SERIAL, 6, "serial",
                PROC_SERIAL, 6, "serial",
                S_IFREG | S_IRUGO, 1, 0, 0,
                S_IFREG | S_IRUGO, 1, 0, 0,
};
};
struct proc_dir_entry pde_kmsg = {
struct proc_dir_entry pde_kmsg = {
                PROC_KMSG, 4, "kmsg",
                PROC_KMSG, 4, "kmsg",
                S_IFREG | S_IRUSR, 1, 0, 0,
                S_IFREG | S_IRUSR, 1, 0, 0,
};
};
struct proc_dir_entry pde_version = {
struct proc_dir_entry pde_version = {
                PROC_VERSION, 7, "version",
                PROC_VERSION, 7, "version",
                S_IFREG | S_IRUGO, 1, 0, 0,
                S_IFREG | S_IRUGO, 1, 0, 0,
};
};
#ifdef CONFIG_PCI
#ifdef CONFIG_PCI
struct proc_dir_entry pde_pci = {
struct proc_dir_entry pde_pci = {
                PROC_PCI, 3, "pci",
                PROC_PCI, 3, "pci",
                S_IFREG | S_IRUGO, 1, 0, 0,
                S_IFREG | S_IRUGO, 1, 0, 0,
};
};
#endif
#endif
struct proc_dir_entry pde_cpuinfo = {
struct proc_dir_entry pde_cpuinfo = {
                PROC_CPUINFO, 7, "cpuinfo",
                PROC_CPUINFO, 7, "cpuinfo",
                S_IFREG | S_IRUGO, 1, 0, 0,
                S_IFREG | S_IRUGO, 1, 0, 0,
};
};
struct proc_dir_entry pde_self = {
struct proc_dir_entry pde_self = {
                PROC_SELF, 4, "self",
                PROC_SELF, 4, "self",
                S_IFLNK | S_IRUGO | S_IWUGO | S_IXUGO, 1, 0, 0,
                S_IFLNK | S_IRUGO | S_IWUGO | S_IXUGO, 1, 0, 0,
                64, &proc_self_inode_operations,
                64, &proc_self_inode_operations,
};
};
 
 
#ifdef CONFIG_DEBUG_MALLOC
#ifdef CONFIG_DEBUG_MALLOC
struct proc_dir_entry pde_malloc = {
struct proc_dir_entry pde_malloc = {
                PROC_MALLOC, 6, "malloc",
                PROC_MALLOC, 6, "malloc",
                S_IFREG | S_IRUGO, 1, 0, 0,
                S_IFREG | S_IRUGO, 1, 0, 0,
};
};
#endif
#endif
struct proc_dir_entry pde_kcore = {
struct proc_dir_entry pde_kcore = {
                PROC_KCORE, 5, "kcore",
                PROC_KCORE, 5, "kcore",
                S_IFREG | S_IRUSR, 1, 0, 0,
                S_IFREG | S_IRUSR, 1, 0, 0,
};
};
 
 
#ifdef CONFIG_MODULES
#ifdef CONFIG_MODULES
struct proc_dir_entry pde_modules = {
struct proc_dir_entry pde_modules = {
                PROC_MODULES, 7, "modules",
                PROC_MODULES, 7, "modules",
                S_IFREG | S_IRUGO, 1, 0, 0,
                S_IFREG | S_IRUGO, 1, 0, 0,
};
};
struct proc_dir_entry pde_ksyms = {
struct proc_dir_entry pde_ksyms = {
                PROC_KSYMS, 5, "ksyms",
                PROC_KSYMS, 5, "ksyms",
                S_IFREG | S_IRUGO, 1, 0, 0,
                S_IFREG | S_IRUGO, 1, 0, 0,
};
};
#endif
#endif
struct proc_dir_entry pde_stat = {
struct proc_dir_entry pde_stat = {
                PROC_STAT, 4, "stat",
                PROC_STAT, 4, "stat",
                S_IFREG | S_IRUGO, 1, 0, 0,
                S_IFREG | S_IRUGO, 1, 0, 0,
};
};
struct proc_dir_entry pde_devices =  {
struct proc_dir_entry pde_devices =  {
                PROC_DEVICES, 7, "devices",
                PROC_DEVICES, 7, "devices",
                S_IFREG | S_IRUGO, 1, 0, 0,
                S_IFREG | S_IRUGO, 1, 0, 0,
};
};
struct proc_dir_entry pde_interrupts =  {
struct proc_dir_entry pde_interrupts =  {
                PROC_INTERRUPTS, 10,"interrupts",
                PROC_INTERRUPTS, 10,"interrupts",
                S_IFREG | S_IRUGO, 1, 0, 0,
                S_IFREG | S_IRUGO, 1, 0, 0,
};
};
#ifdef __SMP_PROF__
#ifdef __SMP_PROF__
struct proc_dir_entry pde_smp =  {
struct proc_dir_entry pde_smp =  {
                PROC_SMP_PROF, 3,"smp",
                PROC_SMP_PROF, 3,"smp",
                S_IFREG | S_IRUGO, 1, 0, 0,
                S_IFREG | S_IRUGO, 1, 0, 0,
};
};
#endif 
#endif 
struct proc_dir_entry pde_filesystems =  {
struct proc_dir_entry pde_filesystems =  {
                PROC_FILESYSTEMS, 11,"filesystems",
                PROC_FILESYSTEMS, 11,"filesystems",
                S_IFREG | S_IRUGO, 1, 0, 0,
                S_IFREG | S_IRUGO, 1, 0, 0,
};
};
struct proc_dir_entry pde_dma =  {
struct proc_dir_entry pde_dma =  {
                PROC_DMA, 3, "dma",
                PROC_DMA, 3, "dma",
                S_IFREG | S_IRUGO, 1, 0, 0,
                S_IFREG | S_IRUGO, 1, 0, 0,
};
};
struct proc_dir_entry pde_ioports =  {
struct proc_dir_entry pde_ioports =  {
                PROC_IOPORTS, 7, "ioports",
                PROC_IOPORTS, 7, "ioports",
                S_IFREG | S_IRUGO, 1, 0, 0,
                S_IFREG | S_IRUGO, 1, 0, 0,
};
};
struct proc_dir_entry pde_cmdline =  {
struct proc_dir_entry pde_cmdline =  {
                PROC_CMDLINE, 7, "cmdline",
                PROC_CMDLINE, 7, "cmdline",
                S_IFREG | S_IRUGO, 1, 0, 0,
                S_IFREG | S_IRUGO, 1, 0, 0,
};
};
#ifdef CONFIG_RTC
#ifdef CONFIG_RTC
struct proc_dir_entry pde_rtc =  {
struct proc_dir_entry pde_rtc =  {
                PROC_RTC, 3, "rtc",
                PROC_RTC, 3, "rtc",
                S_IFREG | S_IRUGO, 1, 0, 0,
                S_IFREG | S_IRUGO, 1, 0, 0,
};
};
#endif
#endif
struct proc_dir_entry pde_locks =  {
struct proc_dir_entry pde_locks =  {
                PROC_LOCKS, 5, "locks",
                PROC_LOCKS, 5, "locks",
                S_IFREG | S_IRUGO, 1, 0, 0,
                S_IFREG | S_IRUGO, 1, 0, 0,
};
};
 
 
struct proc_dir_entry pde_mounts =
struct proc_dir_entry pde_mounts =
           { PROC_MTAB, 6, "mounts", S_IFREG | S_IRUGO, 1, 0, 0, };
           { PROC_MTAB, 6, "mounts", S_IFREG | S_IRUGO, 1, 0, 0, };
 
 
struct proc_dir_entry pde_profile = {
struct proc_dir_entry pde_profile = {
                        PROC_PROFILE, 7, "profile",
                        PROC_PROFILE, 7, "profile",
                        S_IFREG | S_IRUGO | S_IWUSR, 1, 0, 0,
                        S_IFREG | S_IRUGO | S_IWUSR, 1, 0, 0,
};
};
 
 
void proc_root_init(void)
void proc_root_init(void)
{
{
        static int done = 0;
        static int done = 0;
 
 
        if (done)
        if (done)
                return;
                return;
        done = 1;
        done = 1;
        proc_base_init();
        proc_base_init();
 
 
        proc_register(&proc_root, &pde_loadavg);
        proc_register(&proc_root, &pde_loadavg);
        proc_register(&proc_root, &pde_uptime);
        proc_register(&proc_root, &pde_uptime);
        proc_register(&proc_root, &pde_meminfo);
        proc_register(&proc_root, &pde_meminfo);
        proc_register(&proc_root, &pde_kmsg);
        proc_register(&proc_root, &pde_kmsg);
        proc_register(&proc_root, &pde_version);
        proc_register(&proc_root, &pde_version);
#ifdef CONFIG_PCI
#ifdef CONFIG_PCI
        proc_register(&proc_root, &pde_pci);
        proc_register(&proc_root, &pde_pci);
#endif
#endif
        proc_register(&proc_root, &pde_cpuinfo);
        proc_register(&proc_root, &pde_cpuinfo);
        proc_register(&proc_root, &pde_self);
        proc_register(&proc_root, &pde_self);
        proc_register(&proc_root, &proc_net);
        proc_register(&proc_root, &proc_net);
        proc_register(&proc_root, &proc_scsi);
        proc_register(&proc_root, &proc_scsi);
        proc_register(&proc_root, &proc_sys_root);
        proc_register(&proc_root, &proc_sys_root);
        proc_register(&proc_root, &pde_serial);
        proc_register(&proc_root, &pde_serial);
 
 
#ifdef CONFIG_DEBUG_MALLOC
#ifdef CONFIG_DEBUG_MALLOC
        proc_register(&proc_root, &pde_malloc);
        proc_register(&proc_root, &pde_malloc);
#endif
#endif
        proc_register(&proc_root, &pde_kcore);
        proc_register(&proc_root, &pde_kcore);
 
 
#ifdef CONFIG_MODULES
#ifdef CONFIG_MODULES
        proc_register(&proc_root, &pde_modules);
        proc_register(&proc_root, &pde_modules);
        proc_register(&proc_root, &pde_ksyms);
        proc_register(&proc_root, &pde_ksyms);
#endif
#endif
        proc_register(&proc_root, &pde_stat);
        proc_register(&proc_root, &pde_stat);
        proc_register(&proc_root, &pde_devices);
        proc_register(&proc_root, &pde_devices);
        proc_register(&proc_root, &pde_interrupts);
        proc_register(&proc_root, &pde_interrupts);
#ifdef __SMP_PROF__
#ifdef __SMP_PROF__
        proc_register(&proc_root, &pde_smp);
        proc_register(&proc_root, &pde_smp);
#endif 
#endif 
        proc_register(&proc_root, &pde_filesystems);
        proc_register(&proc_root, &pde_filesystems);
        proc_register(&proc_root, &pde_dma);
        proc_register(&proc_root, &pde_dma);
        proc_register(&proc_root, &pde_ioports);
        proc_register(&proc_root, &pde_ioports);
        proc_register(&proc_root, &pde_cmdline);
        proc_register(&proc_root, &pde_cmdline);
#ifdef CONFIG_RTC
#ifdef CONFIG_RTC
        proc_register(&proc_root, &pde_rtc);
        proc_register(&proc_root, &pde_rtc);
#endif
#endif
        proc_register(&proc_root, &pde_locks);
        proc_register(&proc_root, &pde_locks);
 
 
        proc_register( &proc_root, &pde_mounts);
        proc_register( &proc_root, &pde_mounts);
 
 
        if (prof_shift) {
        if (prof_shift) {
                proc_register(&proc_root, &pde_profile);
                proc_register(&proc_root, &pde_profile);
        }
        }
}
}
 
 
 
 
int proc_match(int len,const char * name,struct proc_dir_entry * de)
int proc_match(int len,const char * name,struct proc_dir_entry * de)
{
{
        if (!de || !de->low_ino)
        if (!de || !de->low_ino)
                return 0;
                return 0;
        /* "" means "." ---> so paths like "/usr/lib//libc.a" work */
        /* "" means "." ---> so paths like "/usr/lib//libc.a" work */
        if (!len && (de->name[0]=='.') && (de->name[1]=='\0'))
        if (!len && (de->name[0]=='.') && (de->name[1]=='\0'))
                return 1;
                return 1;
        if (de->namelen != len)
        if (de->namelen != len)
                return 0;
                return 0;
        return !memcmp(name, de->name, len);
        return !memcmp(name, de->name, len);
}
}
 
 
int proc_lookup(struct inode * dir,const char * name, int len,
int proc_lookup(struct inode * dir,const char * name, int len,
        struct inode ** result)
        struct inode ** result)
{
{
        struct proc_dir_entry * de;
        struct proc_dir_entry * de;
        int ino;
        int ino;
 
 
        *result = NULL;
        *result = NULL;
        if (!dir || !S_ISDIR(dir->i_mode)) {
        if (!dir || !S_ISDIR(dir->i_mode)) {
                iput(dir);
                iput(dir);
                return -ENOTDIR;
                return -ENOTDIR;
        }
        }
 
 
        de = (struct proc_dir_entry *) dir->u.generic_ip;
        de = (struct proc_dir_entry *) dir->u.generic_ip;
        if (!de) {
        if (!de) {
                iput(dir);
                iput(dir);
                return -EINVAL;
                return -EINVAL;
        }
        }
 
 
        /* Special case "." and "..": they aren't on the directory list */
        /* Special case "." and "..": they aren't on the directory list */
        *result = dir;
        *result = dir;
        if (!len)
        if (!len)
                return 0;
                return 0;
        if (name[0] == '.') {
        if (name[0] == '.') {
                if (len == 1)
                if (len == 1)
                        return 0;
                        return 0;
                if (name[1] == '.' && len == 2) {
                if (name[1] == '.' && len == 2) {
                        struct inode * inode;
                        struct inode * inode;
                        inode = proc_get_inode(dir->i_sb, de->parent->low_ino, de->parent);
                        inode = proc_get_inode(dir->i_sb, de->parent->low_ino, de->parent);
                        iput(dir);
                        iput(dir);
                        if (!inode)
                        if (!inode)
                                return -EINVAL;
                                return -EINVAL;
                        *result = inode;
                        *result = inode;
                        return 0;
                        return 0;
                }
                }
        }
        }
 
 
        *result = NULL;
        *result = NULL;
        for (de = de->subdir; de ; de = de->next) {
        for (de = de->subdir; de ; de = de->next) {
                if (proc_match(len, name, de))
                if (proc_match(len, name, de))
                        break;
                        break;
        }
        }
        if (!de) {
        if (!de) {
                iput(dir);
                iput(dir);
                return -ENOENT;
                return -ENOENT;
        }
        }
 
 
        ino = de->low_ino | (dir->i_ino & ~(0xffff));
        ino = de->low_ino | (dir->i_ino & ~(0xffff));
 
 
        if (!(*result = proc_get_inode(dir->i_sb, ino, de))) {
        if (!(*result = proc_get_inode(dir->i_sb, ino, de))) {
                iput(dir);
                iput(dir);
                return -EINVAL;
                return -EINVAL;
        }
        }
        iput(dir);
        iput(dir);
        return 0;
        return 0;
}
}
 
 
static int proc_root_lookup(struct inode * dir,const char * name, int len,
static int proc_root_lookup(struct inode * dir,const char * name, int len,
        struct inode ** result)
        struct inode ** result)
{
{
        unsigned int pid, c;
        unsigned int pid, c;
        int i, ino, retval;
        int i, ino, retval;
 
 
        dir->i_count++;
        dir->i_count++;
        retval = proc_lookup(dir, name, len, result);
        retval = proc_lookup(dir, name, len, result);
        if (retval != -ENOENT) {
        if (retval != -ENOENT) {
                iput(dir);
                iput(dir);
                return retval;
                return retval;
        }
        }
 
 
        pid = 0;
        pid = 0;
        while (len-- > 0) {
        while (len-- > 0) {
                c = *name - '0';
                c = *name - '0';
                name++;
                name++;
                if (c > 9) {
                if (c > 9) {
                        pid = 0;
                        pid = 0;
                        break;
                        break;
                }
                }
                pid *= 10;
                pid *= 10;
                pid += c;
                pid += c;
                if (pid & 0xffff0000) {
                if (pid & 0xffff0000) {
                        pid = 0;
                        pid = 0;
                        break;
                        break;
                }
                }
        }
        }
        for (i = 0 ; i < NR_TASKS ; i++)
        for (i = 0 ; i < NR_TASKS ; i++)
                if (task[i] && task[i]->pid == pid)
                if (task[i] && task[i]->pid == pid)
                        break;
                        break;
        if (!pid || i >= NR_TASKS) {
        if (!pid || i >= NR_TASKS) {
                iput(dir);
                iput(dir);
                return -ENOENT;
                return -ENOENT;
        }
        }
        ino = (pid << 16) + PROC_PID_INO;
        ino = (pid << 16) + PROC_PID_INO;
        if (!(*result = proc_get_inode(dir->i_sb, ino, &proc_pid))) {
        if (!(*result = proc_get_inode(dir->i_sb, ino, &proc_pid))) {
                iput(dir);
                iput(dir);
                return -EINVAL;
                return -EINVAL;
        }
        }
        iput(dir);
        iput(dir);
        return 0;
        return 0;
}
}
 
 
/*
/*
 * This returns non-zero if at EOF, so that the /proc
 * This returns non-zero if at EOF, so that the /proc
 * root directory can use this and check if it should
 * root directory can use this and check if it should
 * continue with the <pid> entries..
 * continue with the <pid> entries..
 *
 *
 * Note that the VFS-layer doesn't care about the return
 * Note that the VFS-layer doesn't care about the return
 * value of the readdir() call, as long as it's non-negative
 * value of the readdir() call, as long as it's non-negative
 * for success..
 * for success..
 */
 */
int proc_readdir(struct inode * inode, struct file * filp,
int proc_readdir(struct inode * inode, struct file * filp,
        void * dirent, filldir_t filldir)
        void * dirent, filldir_t filldir)
{
{
        struct proc_dir_entry * de;
        struct proc_dir_entry * de;
        unsigned int ino;
        unsigned int ino;
        int i;
        int i;
 
 
        if (!inode || !S_ISDIR(inode->i_mode))
        if (!inode || !S_ISDIR(inode->i_mode))
                return -ENOTDIR;
                return -ENOTDIR;
        ino = inode->i_ino;
        ino = inode->i_ino;
        de = (struct proc_dir_entry *) inode->u.generic_ip;
        de = (struct proc_dir_entry *) inode->u.generic_ip;
        if (!de)
        if (!de)
                return -EINVAL;
                return -EINVAL;
        i = filp->f_pos;
        i = filp->f_pos;
        switch (i) {
        switch (i) {
                case 0:
                case 0:
                        if (filldir(dirent, ".", 1, i, ino) < 0)
                        if (filldir(dirent, ".", 1, i, ino) < 0)
                                return 0;
                                return 0;
                        i++;
                        i++;
                        filp->f_pos++;
                        filp->f_pos++;
                        /* fall through */
                        /* fall through */
                case 1:
                case 1:
                        if (filldir(dirent, "..", 2, i, de->parent->low_ino) < 0)
                        if (filldir(dirent, "..", 2, i, de->parent->low_ino) < 0)
                                return 0;
                                return 0;
                        i++;
                        i++;
                        filp->f_pos++;
                        filp->f_pos++;
                        /* fall through */
                        /* fall through */
                default:
                default:
                        ino &= ~0xffff;
                        ino &= ~0xffff;
                        de = de->subdir;
                        de = de->subdir;
                        i -= 2;
                        i -= 2;
                        for (;;) {
                        for (;;) {
                                if (!de)
                                if (!de)
                                        return 1;
                                        return 1;
                                if (!i)
                                if (!i)
                                        break;
                                        break;
                                de = de->next;
                                de = de->next;
                                i--;
                                i--;
                        }
                        }
 
 
                        do {
                        do {
                                if (filldir(dirent, de->name, de->namelen, filp->f_pos, ino | de->low_ino) < 0)
                                if (filldir(dirent, de->name, de->namelen, filp->f_pos, ino | de->low_ino) < 0)
                                        return 0;
                                        return 0;
                                filp->f_pos++;
                                filp->f_pos++;
                                de = de->next;
                                de = de->next;
                        } while (de);
                        } while (de);
        }
        }
        return 1;
        return 1;
}
}
 
 
#define NUMBUF 10
#define NUMBUF 10
 
 
static int proc_root_readdir(struct inode * inode, struct file * filp,
static int proc_root_readdir(struct inode * inode, struct file * filp,
        void * dirent, filldir_t filldir)
        void * dirent, filldir_t filldir)
{
{
        char buf[NUMBUF];
        char buf[NUMBUF];
        unsigned int nr,pid;
        unsigned int nr,pid;
        unsigned long i,j;
        unsigned long i,j;
 
 
        nr = filp->f_pos;
        nr = filp->f_pos;
        if (nr < FIRST_PROCESS_ENTRY) {
        if (nr < FIRST_PROCESS_ENTRY) {
                int error = proc_readdir(inode, filp, dirent, filldir);
                int error = proc_readdir(inode, filp, dirent, filldir);
                if (error <= 0)
                if (error <= 0)
                        return error;
                        return error;
                filp->f_pos = nr = FIRST_PROCESS_ENTRY;
                filp->f_pos = nr = FIRST_PROCESS_ENTRY;
        }
        }
 
 
        for (nr -= FIRST_PROCESS_ENTRY; nr < NR_TASKS; nr++, filp->f_pos++) {
        for (nr -= FIRST_PROCESS_ENTRY; nr < NR_TASKS; nr++, filp->f_pos++) {
                struct task_struct * p = task[nr];
                struct task_struct * p = task[nr];
 
 
                if (!p || !(pid = p->pid))
                if (!p || !(pid = p->pid))
                        continue;
                        continue;
 
 
                j = NUMBUF;
                j = NUMBUF;
                i = pid;
                i = pid;
                do {
                do {
                        j--;
                        j--;
                        buf[j] = '0' + (i % 10);
                        buf[j] = '0' + (i % 10);
                        i /= 10;
                        i /= 10;
                } while (i);
                } while (i);
 
 
                if (filldir(dirent, buf+j, NUMBUF-j, filp->f_pos, (pid << 16) + PROC_PID_INO) < 0)
                if (filldir(dirent, buf+j, NUMBUF-j, filp->f_pos, (pid << 16) + PROC_PID_INO) < 0)
                        break;
                        break;
        }
        }
        return 0;
        return 0;
}
}
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.