array.c
来自「elinux jffs初始版本 具体了解JFFS的文件系统!」· C语言 代码 · 共 1,284 行 · 第 1/3 页
C
1,284 行
static void statm_pgd_range(pgd_t * pgd, unsigned long address, unsigned long end, int * pages, int * shared, int * dirty, int * total){ while (address < end) { statm_pmd_range(pgd, address, end - address, pages, shared, dirty, total); address = (address + PGDIR_SIZE) & PGDIR_MASK; pgd++; }}static int get_statm(int pid, char * buffer){ struct task_struct ** p = get_task(pid), *tsk; int size=0, resident=0, share=0, trs=0, lrs=0, drs=0, dt=0; if (!p || (tsk = *p) == NULL) return 0; if (tsk->mm && tsk->mm != &init_mm) { struct vm_area_struct * vma = tsk->mm->mmap; while (vma) { pgd_t *pgd = pgd_offset(tsk->mm, vma->vm_start); int pages = 0, shared = 0, dirty = 0, total = 0; statm_pgd_range(pgd, vma->vm_start, vma->vm_end, &pages, &shared, &dirty, &total); resident += pages; share += shared; dt += dirty; size += total; if (vma->vm_flags & VM_EXECUTABLE) trs += pages; /* text */ else if (vma->vm_flags & VM_GROWSDOWN) drs += pages; /* stack */ else if (vma->vm_end > 0x60000000) lrs += pages; /* library */ else drs += pages; vma = vma->vm_next; } } return sprintf(buffer,"%d %d %d %d %d %d %d\n", size, resident, share, trs, lrs, drs, dt);}/* * The way we support synthetic files > 4K * - without storing their contents in some buffer and * - without walking through the entire synthetic file until we reach the * position of the requested data * is to cleverly encode the current position in the file's f_pos field. * There is no requirement that a read() call which returns `count' bytes * of data increases f_pos by exactly `count'. * * This idea is Linus' one. Bruno implemented it. *//* * For the /proc/<pid>/maps file, we use fixed length records, each containing * a single line. */#define MAPS_LINE_LENGTH 1024#define MAPS_LINE_SHIFT 10/* * f_pos = (number of the vma in the task->mm->mmap list) * MAPS_LINE_LENGTH * + (index into the line) *//* for systems with sizeof(void*) == 4: */#define MAPS_LINE_FORMAT4 "%08lx-%08lx %s %08lx %s %lu\n"#define MAPS_LINE_MAX4 49 /* sum of 8 1 8 1 4 1 8 1 5 1 10 1 *//* for systems with sizeof(void*) == 8: */#define MAPS_LINE_FORMAT8 "%016lx-%016lx %s %016lx %s %lu\n"#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_MAX8static int read_maps (int pid, struct file * file, char * buf, int count){ struct task_struct ** p = get_task(pid); char * destptr; loff_t lineno; int column; struct vm_area_struct * map; int i; if (!p || !*p) return -EINVAL; if (!(*p)->mm || (*p)->mm == &init_mm || count == 0) return 0; /* decode f_pos */ lineno = file->f_pos >> MAPS_LINE_SHIFT; column = file->f_pos & (MAPS_LINE_LENGTH-1); /* quickly go to line lineno */ for (map = (*p)->mm->mmap, i = 0; map && (i < lineno); map = map->vm_next, i++) continue; destptr = buf; for ( ; map ; ) { /* produce the next line */ char line[MAPS_LINE_MAX+1]; char str[5], *cp = str; int flags; kdev_t dev; unsigned long ino; int len; 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; if (map->vm_inode != NULL) { dev = map->vm_inode->i_dev; ino = map->vm_inode->i_ino; } else { dev = 0; ino = 0; } len = sprintf(line, sizeof(void*) == 4 ? MAPS_LINE_FORMAT4 : MAPS_LINE_FORMAT8, map->vm_start, map->vm_end, str, map->vm_offset, kdevname(dev), ino); if (column >= len) { column = 0; /* continue with next line at column 0 */ lineno++; map = map->vm_next; continue; } i = len-column; if (i > count) i = count; memcpy_tofs(destptr, line+column, i); destptr += i; count -= i; column += i; if (column >= len) { column = 0; /* next time: next line at column 0 */ lineno++; map = map->vm_next; } /* done? */ if (count == 0) break; /* By writing to user space, we might have slept. * Stop the loop, to avoid a race condition. */ if (*p != current) break; } /* encode f_pos */ file->f_pos = (lineno << MAPS_LINE_SHIFT) + column; return destptr-buf;}#endif /* NO_MM */#ifdef CONFIG_MODULESextern int get_module_list(char *);extern int get_ksyms_list(char *, char **, off_t, int);#endifextern int get_device_list(char *);extern int get_filesystem_list(char *);extern int get_filesystem_info( char * );extern int get_irq_list(char *);extern int get_dma_list(char *);extern int get_cpuinfo(char *);extern int get_pci_list(char*);extern int get_md_status (char *);extern int get_rtc_status (char *);extern int get_locks_status (char *, char **, off_t, int);#ifdef __SMP_PROF__extern int get_smp_prof_list(char *);#endifstatic int get_root_array(char * page, int type, char **start, off_t offset, int length){ switch (type) { case PROC_LOADAVG: return get_loadavg(page); case PROC_UPTIME: return get_uptime(page); case PROC_MEMINFO: return get_meminfo(page);#ifdef CONFIG_PCI case PROC_PCI: return get_pci_list(page);#endif case PROC_CPUINFO: return get_cpuinfo(page); case PROC_VERSION: return get_version(page);#ifdef CONFIG_DEBUG_MALLOC case PROC_MALLOC: return get_malloc(page);#endif#ifdef CONFIG_MODULES case PROC_MODULES: return get_module_list(page); case PROC_KSYMS: return get_ksyms_list(page, start, offset, length);#endif case PROC_STAT: return get_kstat(page); case PROC_DEVICES: return get_device_list(page); case PROC_INTERRUPTS: return get_irq_list(page); case PROC_FILESYSTEMS: return get_filesystem_list(page); case PROC_DMA: return get_dma_list(page); case PROC_IOPORTS: return get_ioport_list(page);#ifdef CONFIG_BLK_DEV_MD case PROC_MD: return get_md_status(page);#endif#ifdef __SMP_PROF__ case PROC_SMP_PROF: return get_smp_prof_list(page);#endif case PROC_CMDLINE: return get_cmdline(page); case PROC_MTAB: return get_filesystem_info( page );#if defined(CONFIG_RTC) || defined(CONFIG_DS1302) case PROC_RTC: return get_rtc_status(page);#endif case PROC_LOCKS: return get_locks_status(page, start, offset, length); } return -EBADF;}static int get_process_array(char * page, int pid, int type){ switch (type) { case PROC_PID_STATUS: return get_status(pid, page); case PROC_PID_ENVIRON: return get_env(pid, page); case PROC_PID_CMDLINE: return get_arg(pid, page); case PROC_PID_STAT: return get_stat(pid, page);#ifndef NO_MM case PROC_PID_STATM: return get_statm(pid, page);#endif } return -EBADF;}static inline int fill_array(char * page, int pid, int type, char **start, off_t offset, int length){ if (pid) return get_process_array(page, pid, type); return get_root_array(page, type, start, offset, length);}#define PROC_BLOCK_SIZE (3*1024) /* 4K page size but our output routines use some slack for overruns */static int array_read(struct inode * inode, struct file * file,char * buf, int count){ unsigned long page; char *start; int length; int end; unsigned int type, pid; struct proc_dir_entry *dp; if (count < 0) return -EINVAL; if (count > PROC_BLOCK_SIZE) count = PROC_BLOCK_SIZE; if (!(page = __get_free_page(GFP_KERNEL))) return -ENOMEM; type = inode->i_ino; pid = type >> 16; type &= 0x0000ffff; start = NULL; dp = (struct proc_dir_entry *) inode->u.generic_ip; if (dp->get_info) length = dp->get_info((char *)page, &start, file->f_pos, count, 0); else length = fill_array((char *) page, pid, type, &start, file->f_pos, count); if (length < 0) { free_page(page); return length; } if (start != NULL) { /* We have had block-adjusting processing! */ memcpy_tofs(buf, start, length); file->f_pos += length; count = length; } else { /* Static 4kB (or whatever) block capacity */ if (file->f_pos >= length) { free_page(page); return 0; } if (count + file->f_pos > length) count = length - file->f_pos; end = count + file->f_pos; memcpy_tofs(buf, (char *) page + file->f_pos, count); file->f_pos = end; } free_page(page); return count;}static struct file_operations proc_array_operations = { NULL, /* array_lseek */ array_read, NULL, /* array_write */ NULL, /* array_readdir */ NULL, /* array_select */ NULL, /* array_ioctl */ NULL, /* mmap */ NULL, /* no special open code */ NULL, /* no special release code */ NULL /* can't fsync */};struct inode_operations proc_array_inode_operations = { &proc_array_operations, /* default base directory file-ops */ NULL, /* create */ NULL, /* lookup */ NULL, /* link */ NULL, /* unlink */ NULL, /* symlink */ NULL, /* mkdir */ NULL, /* rmdir */ NULL, /* mknod */ NULL, /* rename */ NULL, /* readlink */ NULL, /* follow_link */ NULL, /* readpage */ NULL, /* writepage */ NULL, /* bmap */ NULL, /* truncate */ NULL /* permission */};static int arraylong_read (struct inode * inode, struct file * file, char * buf, int count){#ifndef NO_MM unsigned int pid = inode->i_ino >> 16; unsigned int type = inode->i_ino & 0x0000ffff; if (count < 0) return -EINVAL; switch (type) { case PROC_PID_MAPS: return read_maps(pid, file, buf, count); }#endif return -EINVAL;}static struct file_operations proc_arraylong_operations = { NULL, /* array_lseek */ arraylong_read, NULL, /* array_write */ NULL, /* array_readdir */ NULL, /* array_select */ NULL, /* array_ioctl */ NULL, /* mmap */ NULL, /* no special open code */ NULL, /* no special release code */ NULL /* can't fsync */};struct inode_operations proc_arraylong_inode_operations = { &proc_arraylong_operations, /* default base directory file-ops */ NULL, /* create */ NULL, /* lookup */ NULL, /* link */ NULL, /* unlink */ NULL, /* symlink */ NULL, /* mkdir */ NULL, /* rmdir */ NULL, /* mknod */ NULL, /* rename */ NULL, /* readlink */ NULL, /* follow_link */ NULL, /* readpage */ NULL, /* writepage */ NULL, /* bmap */ NULL, /* truncate */ NULL /* permission */};
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?