jffs_proc.c

来自「Linux Kernel 2.6.9 for OMAP1710」· C语言 代码 · 共 262 行

C
262
字号
/* * JFFS -- Journaling Flash File System, Linux implementation. * * Copyright (C) 2000  Axis Communications AB. * * Created by Simon Kagstrom <simonk@axis.com>. * * $Id: jffs_proc.c,v 1.5 2001/06/02 14:34:55 dwmw2 Exp $ * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * *  Overview: *   This file defines JFFS partition entries in the proc file system. * *  TODO: *   Create some more proc files for different kinds of info, i.e. statistics *   about written and read bytes, number of calls to different routines, *   reports about failures. */#include <linux/errno.h>#include <linux/fs.h>#include <linux/jffs.h>#include <linux/slab.h>#include <linux/proc_fs.h>#include <linux/time.h>#include <linux/types.h>#include "jffs_fm.h"#include "jffs_proc.h"/* * Structure for a JFFS partition in the system */struct jffs_partition_dir {	struct jffs_control *c;	struct proc_dir_entry *part_root;	struct proc_dir_entry *part_info;	struct proc_dir_entry *part_layout;	struct jffs_partition_dir *next;};/* * Structure for top-level entry in '/proc/fs' directory */struct proc_dir_entry *jffs_proc_root;/* * Linked list of 'jffs_partition_dirs' to help us track * the mounted JFFS partitions in the system */static struct jffs_partition_dir *jffs_part_dirs;/* * Read functions for entries */static int jffs_proc_info_read(char *page, char **start, off_t off,		int count, int *eof, void *data);static int jffs_proc_layout_read (char *page, char **start, off_t off,		int count, int *eof, void *data);/* * Register a JFFS partition directory (called upon mount) */int jffs_register_jffs_proc_dir(int mtd, struct jffs_control *c){	struct jffs_partition_dir *part_dir;	struct proc_dir_entry *part_info = NULL;	struct proc_dir_entry *part_layout = NULL;	struct proc_dir_entry *part_root = NULL;	char name[10];	sprintf(name, "%d", mtd);	/* Allocate structure for local JFFS partition table */	part_dir = (struct jffs_partition_dir *)		kmalloc(sizeof (struct jffs_partition_dir), GFP_KERNEL);	if (!part_dir)		goto out;	/* Create entry for this partition */	part_root = proc_mkdir(name, jffs_proc_root);	if (!part_root)		goto out1;	/* Create entry for 'info' file */	part_info = create_proc_entry ("info", 0, part_root);	if (!part_info)		goto out2;	part_info->read_proc = jffs_proc_info_read;	part_info->data = (void *) c;	/* Create entry for 'layout' file */	part_layout = create_proc_entry ("layout", 0, part_root);	if (!part_layout)		goto out3;	part_layout->read_proc = jffs_proc_layout_read;	part_layout->data = (void *) c;	/* Fill in structure for table and insert in the list */	part_dir->c = c;	part_dir->part_root = part_root;	part_dir->part_info = part_info;	part_dir->part_layout = part_layout;	part_dir->next = jffs_part_dirs;	jffs_part_dirs = part_dir;	/* Return happy */	return 0;out3:	remove_proc_entry("info", part_root);out2:	remove_proc_entry(name, jffs_proc_root);out1:	kfree(part_dir);out:	return -ENOMEM;}/* * Unregister a JFFS partition directory (called at umount) */int jffs_unregister_jffs_proc_dir(struct jffs_control *c){	struct jffs_partition_dir *part_dir = jffs_part_dirs;	struct jffs_partition_dir *prev_part_dir = NULL;	while (part_dir) {		if (part_dir->c == c) {			/* Remove entries for partition */			remove_proc_entry (part_dir->part_info->name,				part_dir->part_root);			remove_proc_entry (part_dir->part_layout->name,				part_dir->part_root);			remove_proc_entry (part_dir->part_root->name,				jffs_proc_root);			/* Remove entry from list */			if (prev_part_dir)				prev_part_dir->next = part_dir->next;			else				jffs_part_dirs = part_dir->next;			/*			 * Check to see if this is the last one			 * and remove the entry from '/proc/fs'			 * if it is.			 */			if (jffs_part_dirs == part_dir->next)				remove_proc_entry ("jffs", proc_root_fs);			/* Free memory for entry */			kfree(part_dir);			/* Return happy */			return 0;		}		/* Move to next entry */		prev_part_dir = part_dir;		part_dir = part_dir->next;	}	/* Return unhappy */	return -1;}/* * Read a JFFS partition's `info' file */static int jffs_proc_info_read (char *page, char **start, off_t off,		int count, int *eof, void *data){	struct jffs_control *c = (struct jffs_control *) data;	int len = 0;	/* Get information on the parition */	len += sprintf (page,		"partition size:     %08lX (%u)\n"		"sector size:        %08lX (%u)\n"		"used size:          %08lX (%u)\n"		"dirty size:         %08lX (%u)\n"		"free size:          %08lX (%u)\n\n",		(unsigned long) c->fmc->flash_size, c->fmc->flash_size,		(unsigned long) c->fmc->sector_size, c->fmc->sector_size,		(unsigned long) c->fmc->used_size, c->fmc->used_size,		(unsigned long) c->fmc->dirty_size, c->fmc->dirty_size,		(unsigned long) (c->fmc->flash_size -			(c->fmc->used_size + c->fmc->dirty_size)),		c->fmc->flash_size - (c->fmc->used_size + c->fmc->dirty_size));	/* We're done */	*eof = 1;	/* Return length */	return len;}/* * Read a JFFS partition's `layout' file */static int jffs_proc_layout_read (char *page, char **start, off_t off,		int count, int *eof, void *data){	struct jffs_control *c = (struct jffs_control *) data;	struct jffs_fm *fm = NULL;	struct jffs_fm *last_fm = NULL;	int len = 0;	/* Get the first item in the list */ 	fm = c->fmc->head;	/* Print free space */	if (fm && fm->offset) {		len += sprintf (page, "00000000 %08lX free\n",			(unsigned long) fm->offset);	}	/* Loop through all of the flash control structures */	while (fm && (len < (off + count))) {		if (fm->nodes) {			len += sprintf (page + len,				"%08lX %08lX ino=%08lX, ver=%08lX\n",				(unsigned long) fm->offset,				(unsigned long) fm->size,				(unsigned long) fm->nodes->node->ino,				(unsigned long) fm->nodes->node->version);		}		else {			len += sprintf (page + len,				"%08lX %08lX dirty\n",				(unsigned long) fm->offset,				(unsigned long) fm->size);		}		last_fm = fm;		fm = fm->next;	}	/* Print free space */	if ((len < (off + count)) && last_fm	    && (last_fm->offset < c->fmc->flash_size)) {		len += sprintf (page + len,			       "%08lX %08lX free\n",			       (unsigned long) last_fm->offset + 				last_fm->size,			       (unsigned long) (c->fmc->flash_size -						    (last_fm->offset + last_fm->size)));	}	/* We're done */	*eof = 1;	/* Return length */	return len;}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?