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 + -
显示快捷键?