From: Andy P. <at...@us...> - 2002-04-09 15:08:43
|
Update of /cvsroot/linux-vax/kernel-2.4/fs/proc In directory usw-pr-cvs1:/tmp/cvs-serv29245/proc Modified Files: Makefile array.c base.c generic.c inode.c kcore.c kmsg.c proc_misc.c root.c Removed Files: procfs_syms.c Log Message: synch 2.4.15 commit 13 Index: Makefile =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/fs/proc/Makefile,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- Makefile 14 Jan 2001 16:25:47 -0000 1.1.1.1 +++ Makefile 9 Apr 2002 13:19:36 -0000 1.2 @@ -9,10 +9,10 @@ O_TARGET := proc.o -export-objs := procfs_syms.o +export-objs := root.o obj-y := inode.o root.o base.o generic.o array.o \ - kmsg.o proc_tty.o proc_misc.o kcore.o procfs_syms.o + kmsg.o proc_tty.o proc_misc.o kcore.o ifeq ($(CONFIG_PROC_DEVICETREE),y) obj-y += proc_devtree.o Index: array.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/fs/proc/array.c,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- array.c 14 Jan 2001 16:25:56 -0000 1.1.1.1 +++ array.c 9 Apr 2002 13:19:37 -0000 1.2 @@ -151,13 +151,14 @@ read_lock(&tasklist_lock); buffer += sprintf(buffer, "State:\t%s\n" + "Tgid:\t%d\n" "Pid:\t%d\n" "PPid:\t%d\n" "TracerPid:\t%d\n" "Uid:\t%d\t%d\t%d\t%d\n" "Gid:\t%d\t%d\t%d\t%d\n", - get_task_state(p), - p->pid, p->p_opptr->pid, p->p_pptr->pid != p->p_opptr->pid ? p->p_pptr->pid : 0, + get_task_state(p), p->tgid, + p->pid, p->pid ? p->p_opptr->pid : 0, 0, p->uid, p->euid, p->suid, p->fsuid, p->gid, p->egid, p->sgid, p->fsgid); read_unlock(&tasklist_lock); @@ -181,7 +182,7 @@ unsigned long data = 0, stack = 0; unsigned long exec = 0, lib = 0; - down(&mm->mmap_sem); + down_read(&mm->mmap_sem); for (vma = mm->mmap; vma; vma = vma->vm_next) { unsigned long len = (vma->vm_end - vma->vm_start) >> 10; if (!vma->vm_file) { @@ -212,7 +213,7 @@ mm->rss << (PAGE_SHIFT-10), data - stack, stack, exec - lib, lib); - up(&mm->mmap_sem); + up_read(&mm->mmap_sem); return buffer; } @@ -258,7 +259,7 @@ return buffer; } -extern inline char *task_cap(struct task_struct *p, char *buffer) +static inline char *task_cap(struct task_struct *p, char *buffer) { return buffer + sprintf(buffer, "CapInh:\t%016x\n" "CapPrm:\t%016x\n" @@ -273,9 +274,6 @@ { char * orig = buffer; struct mm_struct *mm; -#if defined(CONFIG_ARCH_S390) - int line,len; -#endif buffer = task_name(task, buffer); buffer = task_state(task, buffer); @@ -291,8 +289,7 @@ buffer = task_sig(task, buffer); buffer = task_cap(task, buffer); #if defined(CONFIG_ARCH_S390) - for(line=0;(len=sprintf_regs(line,buffer,task,NULL,NULL))!=0;line++) - buffer+=len; + buffer = task_show_regs(task, buffer); #endif return buffer - orig; } @@ -321,7 +318,7 @@ task_unlock(task); if (mm) { struct vm_area_struct *vma; - down(&mm->mmap_sem); + down_read(&mm->mmap_sem); vma = mm->mmap; while (vma) { vsize += vma->vm_end - vma->vm_start; @@ -329,7 +326,7 @@ } eip = KSTK_EIP(task); esp = KSTK_ESP(task); - up(&mm->mmap_sem); + up_read(&mm->mmap_sem); } wchan = get_wchan(task); @@ -343,7 +340,7 @@ nice = task->nice; read_lock(&tasklist_lock); - ppid = task->p_opptr->pid; + ppid = task->pid ? task->p_opptr->pid : 0; read_unlock(&tasklist_lock); res = sprintf(buffer,"%d (%s) %c %d %d %d %d %d %lu %lu \ %lu %lu %lu %lu %lu %ld %ld %ld %ld %ld %ld %lu %lu %ld %lu %lu %lu %lu %lu \ @@ -425,13 +422,12 @@ ++*total; if (!pte_present(page)) continue; + ptpage = pte_page(page); + if ((!VALID_PAGE(ptpage)) || PageReserved(ptpage)) + continue; ++*pages; if (pte_dirty(page)) ++*dirty; - ptpage = pte_page(page); - if ((!VALID_PAGE(ptpage)) || - PageReserved(ptpage)) - continue; if (page_count(pte_page(page)) > 1) ++*shared; } while (address < end); @@ -484,7 +480,7 @@ task_unlock(task); if (mm) { struct vm_area_struct * vma; - down(&mm->mmap_sem); + down_read(&mm->mmap_sem); vma = mm->mmap; while (vma) { pgd_t *pgd = pgd_offset(mm, vma->vm_start); @@ -505,7 +501,7 @@ drs += pages; vma = vma->vm_next; } - up(&mm->mmap_sem); + up_read(&mm->mmap_sem); mmput(mm); } return sprintf(buffer,"%d %d %d %d %d %d %d\n", @@ -527,11 +523,8 @@ /* * For the /proc/<pid>/maps file, we use fixed length records, each containing * a single line. - */ -#define MAPS_LINE_LENGTH 4096 -#define MAPS_LINE_SHIFT 12 -/* - * f_pos = (number of the vma in the task->mm->mmap list) * MAPS_LINE_LENGTH + * + * f_pos = (number of the vma in the task->mm->mmap list) * PAGE_SIZE * + (index into the line) */ /* for systems with sizeof(void*) == 4: */ @@ -542,138 +535,142 @@ #define MAPS_LINE_FORMAT8 "%016lx-%016lx %s %016lx %s %lu" #define MAPS_LINE_MAX8 73 /* sum of 16 1 16 1 4 1 16 1 5 1 10 1 */ -#define MAPS_LINE_MAX MAPS_LINE_MAX8 +#define MAPS_LINE_FORMAT (sizeof(void*) == 4 ? MAPS_LINE_FORMAT4 : MAPS_LINE_FORMAT8) +#define MAPS_LINE_MAX (sizeof(void*) == 4 ? MAPS_LINE_MAX4 : MAPS_LINE_MAX8) +static int proc_pid_maps_get_line (char *buf, struct vm_area_struct *map) +{ + /* produce the next line */ + char *line; + char str[5]; + int flags; + kdev_t dev; + unsigned long ino; + int len; + + flags = map->vm_flags; + + str[0] = flags & VM_READ ? 'r' : '-'; + str[1] = flags & VM_WRITE ? 'w' : '-'; + str[2] = flags & VM_EXEC ? 'x' : '-'; + str[3] = flags & VM_MAYSHARE ? 's' : 'p'; + str[4] = 0; + + dev = 0; + ino = 0; + if (map->vm_file != NULL) { + dev = map->vm_file->f_dentry->d_inode->i_dev; + ino = map->vm_file->f_dentry->d_inode->i_ino; + line = d_path(map->vm_file->f_dentry, + map->vm_file->f_vfsmnt, + buf, PAGE_SIZE); + buf[PAGE_SIZE-1] = '\n'; + line -= MAPS_LINE_MAX; + if(line < buf) + line = buf; + } else + line = buf; + + len = sprintf(line, + MAPS_LINE_FORMAT, + map->vm_start, map->vm_end, str, map->vm_pgoff << PAGE_SHIFT, + kdevname(dev), ino); + + if(map->vm_file) { + int i; + for(i = len; i < MAPS_LINE_MAX; i++) + line[i] = ' '; + len = buf + PAGE_SIZE - line; + memmove(buf, line, len); + } else + line[len++] = '\n'; + return len; +} ssize_t proc_pid_read_maps (struct task_struct *task, struct file * file, char * buf, size_t count, loff_t *ppos) { struct mm_struct *mm; - struct vm_area_struct * map, * next; - char * destptr = buf, * buffer; - loff_t lineno; - ssize_t column, i; - int volatile_task; + struct vm_area_struct * map; + char *tmp, *kbuf; long retval; + int off, lineno, loff; + /* reject calls with out of range parameters immediately */ + retval = 0; + if (*ppos > LONG_MAX) + goto out; + if (count == 0) + goto out; + off = (long)*ppos; /* * We might sleep getting the page, so get it first. */ retval = -ENOMEM; - buffer = (char*)__get_free_page(GFP_KERNEL); - if (!buffer) + kbuf = (char*)__get_free_page(GFP_KERNEL); + if (!kbuf) goto out; - if (count == 0) - goto getlen_out; + tmp = (char*)__get_free_page(GFP_KERNEL); + if (!tmp) + goto out_free1; + task_lock(task); mm = task->mm; if (mm) atomic_inc(&mm->mm_users); task_unlock(task); + retval = 0; if (!mm) - goto getlen_out; - - /* Check whether the mmaps could change if we sleep */ - volatile_task = (task != current || atomic_read(&mm->mm_users) > 2); + goto out_free2; - /* decode f_pos */ - lineno = *ppos >> MAPS_LINE_SHIFT; - column = *ppos & (MAPS_LINE_LENGTH-1); - - /* quickly go to line lineno */ - down(&mm->mmap_sem); - for (map = mm->mmap, i = 0; map && (i < lineno); map = map->vm_next, i++) - continue; - - for ( ; map ; map = next ) { - /* produce the next line */ - char *line; - char str[5], *cp = str; - int flags; - kdev_t dev; - unsigned long ino; - int maxlen = (sizeof(void*) == 4) ? - MAPS_LINE_MAX4 : MAPS_LINE_MAX8; + down_read(&mm->mmap_sem); + map = mm->mmap; + lineno = 0; + loff = 0; + if (count > PAGE_SIZE) + count = PAGE_SIZE; + while (map) { int len; - - /* - * Get the next vma now (but it won't be used if we sleep). - */ - next = map->vm_next; - flags = map->vm_flags; - - *cp++ = flags & VM_READ ? 'r' : '-'; - *cp++ = flags & VM_WRITE ? 'w' : '-'; - *cp++ = flags & VM_EXEC ? 'x' : '-'; - *cp++ = flags & VM_MAYSHARE ? 's' : 'p'; - *cp++ = 0; - - dev = 0; - ino = 0; - if (map->vm_file != NULL) { - dev = map->vm_file->f_dentry->d_inode->i_dev; - ino = map->vm_file->f_dentry->d_inode->i_ino; - line = d_path(map->vm_file->f_dentry, - map->vm_file->f_vfsmnt, - buffer, PAGE_SIZE); - buffer[PAGE_SIZE-1] = '\n'; - line -= maxlen; - if(line < buffer) - line = buffer; - } else - line = buffer; - - len = sprintf(line, - sizeof(void*) == 4 ? MAPS_LINE_FORMAT4 : MAPS_LINE_FORMAT8, - map->vm_start, map->vm_end, str, map->vm_pgoff << PAGE_SHIFT, - kdevname(dev), ino); - - if(map->vm_file) { - for(i = len; i < maxlen; i++) - line[i] = ' '; - len = buffer + PAGE_SIZE - line; - } else - line[len++] = '\n'; - if (column >= len) { - column = 0; /* continue with next line at column 0 */ - lineno++; - continue; /* we haven't slept */ + if (off > PAGE_SIZE) { + off -= PAGE_SIZE; + goto next; } - - i = len-column; - if (i > count) - i = count; - up(&mm->mmap_sem); - copy_to_user(destptr, line+column, i); /* may have slept */ - down(&mm->mmap_sem); - destptr += i; - count -= i; - column += i; - if (column >= len) { - column = 0; /* next time: next line at column 0 */ - lineno++; + len = proc_pid_maps_get_line(tmp, map); + len -= off; + if (len > 0) { + if (retval+len > count) { + /* only partial line transfer possible */ + len = count - retval; + /* save the offset where the next read + * must start */ + loff = len+off; + } + memcpy(kbuf+retval, tmp+off, len); + retval += len; } - - /* done? */ - if (count == 0) - break; - - /* By writing to user space, we might have slept. - * Stop the loop, to avoid a race condition. - */ - if (volatile_task) + off = 0; +next: + if (!loff) + lineno++; + if (retval >= count) break; + if (loff) BUG(); + map = map->vm_next; } - up(&mm->mmap_sem); - - /* encode f_pos */ - *ppos = (lineno << MAPS_LINE_SHIFT) + column; + up_read(&mm->mmap_sem); mmput(mm); -getlen_out: - retval = destptr - buf; - free_page((unsigned long)buffer); + if (retval > count) BUG(); + if (copy_to_user(buf, kbuf, retval)) + retval = -EFAULT; + else + *ppos = (lineno << PAGE_SHIFT) + loff; + +out_free2: + free_page((unsigned long)tmp); +out_free1: + free_page((unsigned long)kbuf); out: return retval; } Index: base.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/fs/proc/base.c,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- base.c 14 Jan 2001 16:25:51 -0000 1.1.1.1 +++ base.c 9 Apr 2002 13:19:37 -0000 1.2 @@ -64,7 +64,7 @@ task_unlock(task); if (!mm) goto out; - down(&mm->mmap_sem); + down_read(&mm->mmap_sem); vma = mm->mmap; while (vma) { if ((vma->vm_flags & VM_EXECUTABLE) && @@ -76,7 +76,7 @@ } vma = vma->vm_next; } - up(&mm->mmap_sem); + up_read(&mm->mmap_sem); mmput(mm); out: return result; @@ -184,29 +184,6 @@ /* permission checks */ -static int standard_permission(struct inode *inode, int mask) -{ - int mode = inode->i_mode; - - if ((mask & S_IWOTH) && IS_RDONLY(inode) && - (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode))) - return -EROFS; /* Nobody gets write access to a read-only fs */ - else if ((mask & S_IWOTH) && IS_IMMUTABLE(inode)) - return -EACCES; /* Nobody gets write access to an immutable file */ - else if (current->fsuid == inode->i_uid) - mode >>= 6; - else if (in_group_p(inode->i_gid)) - mode >>= 3; - if (((mode & mask & S_IRWXO) == mask) || capable(CAP_DAC_OVERRIDE)) - return 0; - /* read and search access */ - if ((mask == S_IROTH) || - (S_ISDIR(mode) && !(mask & ~(S_IROTH | S_IXOTH)))) - if (capable(CAP_DAC_READ_SEARCH)) - return 0; - return -EACCES; -} - static int proc_check_root(struct inode *inode) { struct dentry *de, *base, *root; @@ -249,7 +226,7 @@ static int proc_permission(struct inode *inode, int mask) { - if (standard_permission(inode, mask) != 0) + if (vfs_permission(inode, mask) != 0) return -EACCES; return proc_check_root(inode); } @@ -312,6 +289,13 @@ #define MAY_PTRACE(p) \ (p==current||(p->p_pptr==current&&(p->ptrace & PT_PTRACED)&&p->state==TASK_STOPPED)) + +static int mem_open(struct inode* inode, struct file* file) +{ + file->private_data = (void*)((long)current->self_exec_id); + return 0; +} + static ssize_t mem_read(struct file * file, char * buf, size_t count, loff_t *ppos) { @@ -319,6 +303,8 @@ char *page; unsigned long src = *ppos; int copied = 0; + struct mm_struct *mm; + if (!MAY_PTRACE(task)) return -ESRCH; @@ -327,6 +313,20 @@ if (!page) return -ENOMEM; + task_lock(task); + mm = task->mm; + if (mm) + atomic_inc(&mm->mm_users); + task_unlock(task); + if (!mm) + return 0; + + if (file->private_data != (void*)((long)current->self_exec_id) ) { + mmput(mm); + return -EIO; + } + + while (count > 0) { int this_len, retval; @@ -347,6 +347,7 @@ count -= retval; } *ppos = src; + mmput(mm); free_page((unsigned long) page); return copied; } @@ -398,6 +399,7 @@ static struct file_operations proc_mem_operations = { read: mem_read, write: mem_write, + open: mem_open, }; static struct inode_operations proc_mem_inode_operations = { @@ -586,7 +588,7 @@ struct pid_entry *p; pid = inode->u.proc_i.task->pid; - if (!inode->u.proc_i.task->p_pptr) + if (!pid) return -ENOENT; i = filp->f_pos; switch (i) { @@ -620,6 +622,20 @@ /* building an inode */ +static int task_dumpable(struct task_struct *task) +{ + int dumpable = 0; + struct mm_struct *mm; + + task_lock(task); + mm = task->mm; + if (mm) + dumpable = mm->dumpable; + task_unlock(task); + return dumpable; +} + + static struct inode *proc_pid_make_inode(struct super_block * sb, struct task_struct *task, int ino) { struct inode * inode; @@ -635,18 +651,17 @@ inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; inode->i_ino = fake_ino(task->pid, ino); - inode->u.proc_i.file = NULL; + if (!task->pid) + goto out_unlock; + /* * grab the reference to task. */ - inode->u.proc_i.task = task; get_task_struct(task); - if (!task->p_pptr) - goto out_unlock; - + inode->u.proc_i.task = task; inode->i_uid = 0; inode->i_gid = 0; - if (ino == PROC_PID_INO || task->dumpable) { + if (ino == PROC_PID_INO || task_dumpable(task)) { inode->i_uid = task->euid; inode->i_gid = task->egid; } @@ -673,7 +688,7 @@ */ static int pid_base_revalidate(struct dentry * dentry, int flags) { - if (dentry->d_inode->u.proc_i.task->p_pptr) + if (dentry->d_inode->u.proc_i.task->pid) return 1; d_drop(dentry); return 0; Index: generic.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/fs/proc/generic.c,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- generic.c 14 Jan 2001 16:26:00 -0000 1.1.1.1 +++ generic.c 9 Apr 2002 13:19:37 -0000 1.2 @@ -190,15 +190,24 @@ return 0; } -static unsigned char proc_alloc_map[PROC_NDYNAMIC / 8]; +static unsigned long proc_alloc_map[(PROC_NDYNAMIC + BITS_PER_LONG - 1) / BITS_PER_LONG]; + +spinlock_t proc_alloc_map_lock = SPIN_LOCK_UNLOCKED; static int make_inode_number(void) { - int i = find_first_zero_bit((void *) proc_alloc_map, PROC_NDYNAMIC); - if (i<0 || i>=PROC_NDYNAMIC) - return -1; - set_bit(i, (void *) proc_alloc_map); - return PROC_DYNAMIC_FIRST + i; + int i; + spin_lock(&proc_alloc_map_lock); + i = find_first_zero_bit(proc_alloc_map, PROC_NDYNAMIC); + if (i < 0 || i >= PROC_NDYNAMIC) { + i = -1; + goto out; + } + set_bit(i, proc_alloc_map); + i += PROC_DYNAMIC_FIRST; +out: + spin_unlock(&proc_alloc_map_lock); + return i; } static int proc_readlink(struct dentry *dentry, char *buffer, int buflen) @@ -388,149 +397,126 @@ file_list_lock(); for (p = sb->s_files.next; p != &sb->s_files; p = p->next) { struct file * filp = list_entry(p, struct file, f_list); - struct dentry * dentry; + struct dentry * dentry = filp->f_dentry; struct inode * inode; + struct file_operations *fops; - dentry = filp->f_dentry; - if (!dentry) - continue; if (dentry->d_op != &proc_dentry_operations) continue; inode = dentry->d_inode; if (inode->u.generic_ip != de) continue; - fops_put(filp->f_op); + fops = filp->f_op; filp->f_op = NULL; + fops_put(fops); } file_list_unlock(); } -struct proc_dir_entry *proc_symlink(const char *name, - struct proc_dir_entry *parent, const char *dest) +static struct proc_dir_entry *proc_create(struct proc_dir_entry **parent, + const char *name, + mode_t mode, + nlink_t nlink) { struct proc_dir_entry *ent = NULL; const char *fn = name; int len; - if (!parent && xlate_proc_name(name, &parent, &fn) != 0) + /* make sure name is valid */ + if (!name || !strlen(name)) goto out; + + if (!(*parent) && xlate_proc_name(name, parent, &fn) != 0) goto out; len = strlen(fn); ent = kmalloc(sizeof(struct proc_dir_entry) + len + 1, GFP_KERNEL); - if (!ent) - goto out; + if (!ent) goto out; + memset(ent, 0, sizeof(struct proc_dir_entry)); - memcpy(((char *) ent) + sizeof(*ent), fn, len + 1); + memcpy(((char *) ent) + sizeof(struct proc_dir_entry), fn, len + 1); ent->name = ((char *) ent) + sizeof(*ent); ent->namelen = len; - ent->nlink = 1; - ent->mode = S_IFLNK|S_IRUGO|S_IWUGO|S_IXUGO; - ent->data = kmalloc((ent->size=strlen(dest))+1, GFP_KERNEL); - if (!ent->data) { - kfree(ent); - goto out; - } - strcpy((char*)ent->data,dest); + ent->mode = mode; + ent->nlink = nlink; + out: + return ent; +} - proc_register(parent, ent); - -out: +struct proc_dir_entry *proc_symlink(const char *name, + struct proc_dir_entry *parent, const char *dest) +{ + struct proc_dir_entry *ent; + + ent = proc_create(&parent,name, + (S_IFLNK | S_IRUGO | S_IWUGO | S_IXUGO),1); + + if (ent) { + ent->data = kmalloc((ent->size=strlen(dest))+1, GFP_KERNEL); + if (ent->data) { + strcpy((char*)ent->data,dest); + proc_register(parent, ent); + } else { + kfree(ent); + ent = NULL; + } + } return ent; } struct proc_dir_entry *proc_mknod(const char *name, mode_t mode, struct proc_dir_entry *parent, kdev_t rdev) { - struct proc_dir_entry *ent = NULL; - const char *fn = name; - int len; - - if (!parent && xlate_proc_name(name, &parent, &fn) != 0) - goto out; - len = strlen(fn); - - ent = kmalloc(sizeof(struct proc_dir_entry) + len + 1, GFP_KERNEL); - if (!ent) - goto out; - memset(ent, 0, sizeof(struct proc_dir_entry)); - memcpy(((char *) ent) + sizeof(*ent), fn, len + 1); - ent->name = ((char *) ent) + sizeof(*ent); - ent->namelen = len; - ent->nlink = 1; - ent->mode = mode; - ent->rdev = rdev; + struct proc_dir_entry *ent; - proc_register(parent, ent); - -out: + ent = proc_create(&parent,name,mode,1); + if (ent) { + ent->rdev = rdev; + proc_register(parent, ent); + } return ent; } struct proc_dir_entry *proc_mkdir(const char *name, struct proc_dir_entry *parent) { - struct proc_dir_entry *ent = NULL; - const char *fn = name; - int len; - - if (!parent && xlate_proc_name(name, &parent, &fn) != 0) - goto out; - len = strlen(fn); + struct proc_dir_entry *ent; - ent = kmalloc(sizeof(struct proc_dir_entry) + len + 1, GFP_KERNEL); - if (!ent) - goto out; - memset(ent, 0, sizeof(struct proc_dir_entry)); - memcpy(((char *) ent) + sizeof(*ent), fn, len + 1); - ent->name = ((char *) ent) + sizeof(*ent); - ent->namelen = len; - ent->proc_fops = &proc_dir_operations; - ent->proc_iops = &proc_dir_inode_operations; - ent->nlink = 2; - ent->mode = S_IFDIR | S_IRUGO | S_IXUGO; + ent = proc_create(&parent,name, + (S_IFDIR | S_IRUGO | S_IXUGO),2); + if (ent) { + ent->proc_fops = &proc_dir_operations; + ent->proc_iops = &proc_dir_inode_operations; - proc_register(parent, ent); - -out: + proc_register(parent, ent); + } return ent; } struct proc_dir_entry *create_proc_entry(const char *name, mode_t mode, struct proc_dir_entry *parent) { - struct proc_dir_entry *ent = NULL; - const char *fn = name; - int len; - - if (!parent && xlate_proc_name(name, &parent, &fn) != 0) - goto out; - len = strlen(fn); - - ent = kmalloc(sizeof(struct proc_dir_entry) + len + 1, GFP_KERNEL); - if (!ent) - goto out; - memset(ent, 0, sizeof(struct proc_dir_entry)); - memcpy(((char *) ent) + sizeof(*ent), fn, len + 1); - ent->name = ((char *) ent) + sizeof(*ent); - ent->namelen = len; + struct proc_dir_entry *ent; + nlink_t nlink; if (S_ISDIR(mode)) { if ((mode & S_IALLUGO) == 0) - mode |= S_IRUGO | S_IXUGO; - ent->proc_fops = &proc_dir_operations; - ent->proc_iops = &proc_dir_inode_operations; - ent->nlink = 2; + mode |= S_IRUGO | S_IXUGO; + nlink = 2; } else { if ((mode & S_IFMT) == 0) mode |= S_IFREG; if ((mode & S_IALLUGO) == 0) mode |= S_IRUGO; - ent->nlink = 1; + nlink = 1; } - ent->mode = mode; - proc_register(parent, ent); - -out: + ent = proc_create(&parent,name,mode,nlink); + if (ent) { + if (S_ISDIR(mode)) { + ent->proc_fops = &proc_dir_operations; + ent->proc_iops = &proc_dir_inode_operations; + } + proc_register(parent, ent); + } return ent; } @@ -568,8 +554,8 @@ de->next = NULL; if (S_ISDIR(de->mode)) parent->nlink--; - clear_bit(de->low_ino-PROC_DYNAMIC_FIRST, - (void *) proc_alloc_map); + clear_bit(de->low_ino - PROC_DYNAMIC_FIRST, + proc_alloc_map); proc_kill_inodes(de); de->nlink = 0; if (!atomic_read(&de->count)) Index: inode.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/fs/proc/inode.c,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- inode.c 14 Jan 2001 16:25:54 -0000 1.1.1.1 +++ inode.c 9 Apr 2002 13:19:37 -0000 1.2 @@ -160,14 +160,12 @@ inode->i_nlink = de->nlink; if (de->owner) __MOD_INC_USE_COUNT(de->owner); - if (S_ISBLK(de->mode)||S_ISCHR(de->mode)||S_ISFIFO(de->mode)) + if (de->proc_iops) + inode->i_op = de->proc_iops; + if (de->proc_fops) + inode->i_fop = de->proc_fops; + else if (S_ISBLK(de->mode)||S_ISCHR(de->mode)||S_ISFIFO(de->mode)) init_special_inode(inode,de->mode,kdev_t_to_nr(de->rdev)); - else { - if (de->proc_iops) - inode->i_op = de->proc_iops; - if (de->proc_fops) - inode->i_fop = de->proc_fops; - } } out: @@ -188,6 +186,7 @@ s->s_blocksize_bits = 10; s->s_magic = PROC_SUPER_MAGIC; s->s_op = &proc_sops; + root_inode = proc_get_inode(s, PROC_ROOT_INO, &proc_root); if (!root_inode) goto out_no_root; @@ -208,3 +207,4 @@ iput(root_inode); return NULL; } +MODULE_LICENSE("GPL"); Index: kcore.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/fs/proc/kcore.c,v retrieving revision 1.1.1.2 retrieving revision 1.2 diff -u -r1.1.1.2 -r1.2 --- kcore.c 25 Feb 2001 23:14:46 -0000 1.1.1.2 +++ kcore.c 9 Apr 2002 13:19:37 -0000 1.2 @@ -42,7 +42,7 @@ ssize_t count1; char * pnt; struct user dump; -#if defined (__i386__) || defined (__mc68000__) +#if defined (__i386__) || defined (__mc68000__) || defined(__x86_64__) # define FIRST_MAPPED PAGE_SIZE /* we don't have page 0 mapped on x86.. */ #else # define FIRST_MAPPED 0 @@ -51,7 +51,7 @@ memset(&dump, 0, sizeof(struct user)); dump.magic = CMAGIC; dump.u_dsize = (virt_to_phys(high_memory) >> PAGE_SHIFT); -#if defined (__i386__) +#if defined (__i386__) || defined(__x86_64__) dump.start_code = PAGE_OFFSET; #endif #ifdef __alpha__ @@ -361,7 +361,7 @@ read_unlock(&vmlist_lock); /* where page 0 not mapped, write zeros into buffer */ -#if defined (__i386__) || defined (__mc68000__) +#if defined (__i386__) || defined (__mc68000__) || defined(__x86_64__) if (*fpos < PAGE_SIZE + elf_buflen) { /* work out how much to clear */ tsz = PAGE_SIZE + elf_buflen - *fpos; Index: kmsg.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/fs/proc/kmsg.c,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- kmsg.c 14 Jan 2001 16:25:58 -0000 1.1.1.1 +++ kmsg.c 9 Apr 2002 13:19:37 -0000 1.2 @@ -14,7 +14,6 @@ #include <asm/uaccess.h> #include <asm/io.h> -extern unsigned long log_size; extern wait_queue_head_t log_wait; extern int do_syslog(int type, char * bug, int count); @@ -39,7 +38,7 @@ static unsigned int kmsg_poll(struct file *file, poll_table * wait) { poll_wait(file, &log_wait, wait); - if (log_size) + if (do_syslog(9, 0, 0)) return POLLIN | POLLRDNORM; return 0; } Index: proc_misc.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/fs/proc/proc_misc.c,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- proc_misc.c 14 Jan 2001 16:25:53 -0000 1.1.1.1 +++ proc_misc.c 9 Apr 2002 13:19:37 -0000 1.2 @@ -35,6 +35,7 @@ #include <linux/module.h> #include <linux/init.h> #include <linux/smp_lock.h> +#include <linux/seq_file.h> #include <asm/uaccess.h> #include <asm/pgtable.h> @@ -49,20 +50,12 @@ * have a way to deal with that gracefully. Right now I used straightforward * wrappers, but this needs further analysis wrt potential overflows. */ -extern int get_cpuinfo(char *); -extern int get_hardware_list(char *); -extern int get_stram_list(char *); -#ifdef CONFIG_DEBUG_MALLOC -extern int get_malloc(char * buffer); -#endif #ifdef CONFIG_MODULES extern int get_module_list(char *); -extern int get_ksyms_list(char *, char **, off_t, int); #endif extern int get_device_list(char *); extern int get_partition_list(char *, char **, off_t, int); extern int get_filesystem_list(char *); -extern int get_filesystem_info(char *); extern int get_exec_domain_list(char *); extern int get_irq_list(char *); extern int get_dma_list(char *); @@ -140,57 +133,58 @@ { struct sysinfo i; int len; + int pg_size ; /* * display in kilobytes. */ #define K(x) ((x) << (PAGE_SHIFT - 10)) -#define B(x) ((x) << PAGE_SHIFT) - si_meminfo(&i); - si_swapinfo(&i); - len = sprintf(page, " total: used: free: shared: buffers: cached:\n" - "Mem: %8lu %8lu %8lu %8lu %8lu %8u\n" - "Swap: %8lu %8lu %8lu\n", - B(i.totalram), B(i.totalram-i.freeram), B(i.freeram), - B(i.sharedram), B(i.bufferram), - B(atomic_read(&page_cache_size)), B(i.totalswap), - B(i.totalswap-i.freeswap), B(i.freeswap)); - /* - * Tagged format, for easy grepping and expansion. - * The above will go away eventually, once the tools - * have been updated. - */ - len += sprintf(page+len, - "MemTotal: %8lu kB\n" - "MemFree: %8lu kB\n" - "MemShared: %8lu kB\n" - "Buffers: %8lu kB\n" - "Cached: %8u kB\n" +#define B(x) ((unsigned long long)(x) << PAGE_SHIFT) + si_meminfo(&i); + si_swapinfo(&i); + pg_size = atomic_read(&page_cache_size) - i.bufferram ; + + len = sprintf(page, " total: used: free: shared: buffers: cached:\n" + "Mem: %8Lu %8Lu %8Lu %8Lu %8Lu %8Lu\n" + "Swap: %8Lu %8Lu %8Lu\n", + B(i.totalram), B(i.totalram-i.freeram), B(i.freeram), + B(i.sharedram), B(i.bufferram), + B(pg_size), B(i.totalswap), + B(i.totalswap-i.freeswap), B(i.freeswap)); + /* + * Tagged format, for easy grepping and expansion. + * The above will go away eventually, once the tools + * have been updated. + */ + len += sprintf(page+len, + "MemTotal: %8lu kB\n" + "MemFree: %8lu kB\n" + "MemShared: %8lu kB\n" + "Buffers: %8lu kB\n" + "Cached: %8lu kB\n" + "SwapCached: %8lu kB\n" "Active: %8u kB\n" - "Inact_dirty: %8u kB\n" - "Inact_clean: %8u kB\n" - "Inact_target: %8lu kB\n" - "HighTotal: %8lu kB\n" - "HighFree: %8lu kB\n" - "LowTotal: %8lu kB\n" - "LowFree: %8lu kB\n" - "SwapTotal: %8lu kB\n" - "SwapFree: %8lu kB\n", - K(i.totalram), - K(i.freeram), - K(i.sharedram), - K(i.bufferram), - K(atomic_read(&page_cache_size)), + "Inactive: %8u kB\n" + "HighTotal: %8lu kB\n" + "HighFree: %8lu kB\n" + "LowTotal: %8lu kB\n" + "LowFree: %8lu kB\n" + "SwapTotal: %8lu kB\n" + "SwapFree: %8lu kB\n", + K(i.totalram), + K(i.freeram), + K(i.sharedram), + K(i.bufferram), + K(pg_size - swapper_space.nrpages), + K(swapper_space.nrpages), K(nr_active_pages), - K(nr_inactive_dirty_pages), - K(nr_inactive_clean_pages()), - K(inactive_target), - K(i.totalhigh), - K(i.freehigh), - K(i.totalram-i.totalhigh), - K(i.freeram-i.freehigh), - K(i.totalswap), - K(i.freeswap)); + K(nr_inactive_pages), + K(i.totalhigh), + K(i.freehigh), + K(i.totalram-i.totalhigh), + K(i.freeram-i.freehigh), + K(i.totalswap), + K(i.freeswap)); return proc_calc_metrics(page, start, off, count, eof, len); #undef B @@ -208,39 +202,17 @@ return proc_calc_metrics(page, start, off, count, eof, len); } -static int cpuinfo_read_proc(char *page, char **start, off_t off, - int count, int *eof, void *data) +extern struct seq_operations cpuinfo_op; +static int cpuinfo_open(struct inode *inode, struct file *file) { - int len = get_cpuinfo(page); - return proc_calc_metrics(page, start, off, count, eof, len); + return seq_open(file, &cpuinfo_op); } - -#ifdef CONFIG_PROC_HARDWARE -static int hardware_read_proc(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - int len = get_hardware_list(page); - return proc_calc_metrics(page, start, off, count, eof, len); -} -#endif - -#ifdef CONFIG_STRAM_PROC -static int stram_read_proc(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - int len = get_stram_list(page); - return proc_calc_metrics(page, start, off, count, eof, len); -} -#endif - -#ifdef CONFIG_DEBUG_MALLOC -static int malloc_read_proc(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - int len = get_malloc(page); - return proc_calc_metrics(page, start, off, count, eof, len); -} -#endif +static struct file_operations proc_cpuinfo_operations = { + open: cpuinfo_open, + read: seq_read, + llseek: seq_lseek, + release: seq_release, +}; #ifdef CONFIG_MODULES static int modules_read_proc(char *page, char **start, off_t off, @@ -250,13 +222,17 @@ return proc_calc_metrics(page, start, off, count, eof, len); } -static int ksyms_read_proc(char *page, char **start, off_t off, - int count, int *eof, void *data) +extern struct seq_operations ksyms_op; +static int ksyms_open(struct inode *inode, struct file *file) { - int len = get_ksyms_list(page, start, off, count); - if (len < count) *eof = 1; - return len; + return seq_open(file, &ksyms_op); } +static struct file_operations proc_ksyms_operations = { + open: ksyms_open, + read: seq_read, + llseek: seq_lseek, + release: seq_release, +}; #endif static int kstat_read_proc(char *page, char **start, off_t off, @@ -274,8 +250,10 @@ user += kstat.per_cpu_user[cpu]; nice += kstat.per_cpu_nice[cpu]; system += kstat.per_cpu_system[cpu]; +#if !defined(CONFIG_ARCH_S390) for (j = 0 ; j < NR_IRQS ; j++) sum += kstat.irqs[cpu][j]; +#endif } len = sprintf(page, "cpu %u %u %u %lu\n", user, nice, system, @@ -287,20 +265,22 @@ kstat.per_cpu_nice[cpu_logical_map(i)], kstat.per_cpu_system[cpu_logical_map(i)], jif - ( kstat.per_cpu_user[cpu_logical_map(i)] \ - + kstat.per_cpu_nice[cpu_logical_map(i)] \ - + kstat.per_cpu_system[cpu_logical_map(i)])); + + kstat.per_cpu_nice[cpu_logical_map(i)] \ + + kstat.per_cpu_system[cpu_logical_map(i)])); len += sprintf(page + len, "page %u %u\n" - "swap %u %u\n" + "swap %u %u\n" "intr %u", - kstat.pgpgin, - kstat.pgpgout, + kstat.pgpgin >> 1, + kstat.pgpgout >> 1, kstat.pswpin, kstat.pswpout, sum ); +#if !defined(CONFIG_ARCH_S390) for (i = 0 ; i < NR_IRQS ; i++) len += sprintf(page + len, " %u", kstat_irqs(i)); +#endif len += sprintf(page + len, "\ndisk_io: "); @@ -409,13 +389,6 @@ return len; } -static int mounts_read_proc(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - int len = get_filesystem_info(page); - return proc_calc_metrics(page, start, off, count, eof, len); -} - static int execdomains_read_proc(char *page, char **start, off_t off, int count, int *eof, void *data) { @@ -500,8 +473,28 @@ write: write_profile, }; +extern struct seq_operations mounts_op; +static int mounts_open(struct inode *inode, struct file *file) +{ + return seq_open(file, &mounts_op); +} +static struct file_operations proc_mounts_operations = { + open: mounts_open, + read: seq_read, + llseek: seq_lseek, + release: seq_release, +}; + struct proc_dir_entry *proc_root_kcore; +static void create_seq_entry(char *name, mode_t mode, struct file_operations *f) +{ + struct proc_dir_entry *entry; + entry = create_proc_entry(name, mode, NULL); + if (entry) + entry->proc_fops = f; +} + void __init proc_misc_init(void) { struct proc_dir_entry *entry; @@ -513,19 +506,8 @@ {"uptime", uptime_read_proc}, {"meminfo", meminfo_read_proc}, {"version", version_read_proc}, - {"cpuinfo", cpuinfo_read_proc}, -#ifdef CONFIG_PROC_HARDWARE - {"hardware", hardware_read_proc}, -#endif -#ifdef CONFIG_STRAM_PROC - {"stram", stram_read_proc}, -#endif -#ifdef CONFIG_DEBUG_MALLOC - {"malloc", malloc_read_proc}, -#endif #ifdef CONFIG_MODULES {"modules", modules_read_proc}, - {"ksyms", ksyms_read_proc}, #endif {"stat", kstat_read_proc}, {"devices", devices_read_proc}, @@ -541,7 +523,6 @@ {"rtc", ds1286_read_proc}, #endif {"locks", locks_read_proc}, - {"mounts", mounts_read_proc}, {"swaps", swaps_read_proc}, {"iomem", memory_read_proc}, {"execdomains", execdomains_read_proc}, @@ -554,6 +535,11 @@ entry = create_proc_entry("kmsg", S_IRUSR, &proc_root); if (entry) entry->proc_fops = &proc_kmsg_operations; + create_seq_entry("mounts", 0, &proc_mounts_operations); + create_seq_entry("cpuinfo", 0, &proc_cpuinfo_operations); +#ifdef CONFIG_MODULES + create_seq_entry("ksyms", 0, &proc_ksyms_operations); +#endif proc_root_kcore = create_proc_entry("kcore", S_IRUSR, NULL); if (proc_root_kcore) { proc_root_kcore->proc_fops = &proc_kcore_operations; @@ -567,7 +553,7 @@ entry->size = (1+prof_len) * sizeof(unsigned int); } } -#ifdef __powerpc__ +#ifdef CONFIG_PPC32 { extern struct file_operations ppc_htab_operations; entry = create_proc_entry("ppc_htab", S_IRUGO|S_IWUSR, NULL); Index: root.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/fs/proc/root.c,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- root.c 14 Jan 2001 16:25:48 -0000 1.1.1.1 +++ root.c 9 Apr 2002 13:19:37 -0000 1.2 @@ -14,6 +14,7 @@ #include <linux/stat.h> #include <linux/config.h> #include <linux/init.h> +#include <linux/module.h> #include <asm/bitops.h> struct proc_dir_entry *proc_net, *proc_bus, *proc_root_fs, *proc_root_driver; @@ -22,8 +23,19 @@ struct proc_dir_entry *proc_sys_root; #endif +static DECLARE_FSTYPE(proc_fs_type, "proc", proc_read_super, FS_SINGLE); + void __init proc_root_init(void) { + int err = register_filesystem(&proc_fs_type); + if (err) + return; + proc_mnt = kern_mount(&proc_fs_type); + err = PTR_ERR(proc_mnt); + if (IS_ERR(proc_mnt)) { + unregister_filesystem(&proc_fs_type); + return; + } proc_misc_init(); proc_net = proc_mkdir("net", 0); #ifdef CONFIG_SYSVIPC @@ -32,6 +44,10 @@ #ifdef CONFIG_SYSCTL proc_sys_root = proc_mkdir("sys", 0); #endif +#if defined(CONFIG_BINFMT_MISC) || defined(CONFIG_BINFMT_MISC_MODULE) + proc_mkdir("sys/fs", 0); + proc_mkdir("sys/fs/binfmt_misc", 0); +#endif proc_root_fs = proc_mkdir("fs", 0); proc_root_driver = proc_mkdir("driver", 0); #if defined(CONFIG_SUN_OPENPROMFS) || defined(CONFIG_SUN_OPENPROMFS_MODULE) @@ -42,6 +58,9 @@ #ifdef CONFIG_PROC_DEVICETREE proc_device_tree_init(); #endif +#ifdef CONFIG_PPC_RTAS + proc_rtas_init(); +#endif proc_bus = proc_mkdir("bus", 0); } @@ -106,3 +125,17 @@ proc_fops: &proc_root_operations, parent: &proc_root, }; + +#ifdef CONFIG_SYSCTL +EXPORT_SYMBOL(proc_sys_root); +#endif +EXPORT_SYMBOL(proc_symlink); +EXPORT_SYMBOL(proc_mknod); +EXPORT_SYMBOL(proc_mkdir); +EXPORT_SYMBOL(create_proc_entry); +EXPORT_SYMBOL(remove_proc_entry); +EXPORT_SYMBOL(proc_root); +EXPORT_SYMBOL(proc_root_fs); +EXPORT_SYMBOL(proc_net); +EXPORT_SYMBOL(proc_bus); +EXPORT_SYMBOL(proc_root_driver); --- procfs_syms.c DELETED --- |