⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 intrep.c

📁 mtd最新cvs jffs文件系统分析
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * JFFS -- Journaling Flash File System, Linux implementation. * * Copyright (C) 1999, 2000  Axis Communications, Inc. * * Created by Finn Hakansson <finn@axis.com>. * * 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. * * $Id: intrep.c,v 1.105 2003/07/02 20:39:55 acurtis Exp $ * * Ported to Linux 2.3.x and MTD: * Copyright (C) 2000  Alexander Larsson (alex@cendio.se), Cendio Systems AB * *//* This file contains the code for the internal structure of the   Journaling Flash File System, JFFS.  *//* * Todo list: * * memcpy_to_flash() and memcpy_from_flash() functions. * * Implementation of hard links. * * Organize the source code in a better way. Against the VFS we could * have jffs_ext.c, and against the block device jffs_int.c. * A better file-internal organization too. * * A better checksum algorithm. * * Consider endianness stuff. ntohl() etc. * * Are we handling the atime, mtime, ctime members of the inode right? * * Remove some duplicated code. Take a look at jffs_write_node() and * jffs_rewrite_data() for instance. * * Implement more meaning of the nlink member in various data structures. * nlink could be used in conjunction with hard links for instance. * * Better memory management. Allocate data structures in larger chunks * if possible. * * If too much meta data is stored, a garbage collect should be issued. * We have experienced problems with too much meta data with for instance * log files. * * Improve the calls to jffs_ioctl(). We would like to retrieve more * information to be able to debug (or to supervise) JFFS during run-time. * */#define __NO_VERSION__#include <linux/config.h>#include <linux/types.h>#include <linux/slab.h>#include <linux/jffs.h>#include <linux/fs.h>#include <linux/stat.h>#include <linux/pagemap.h>#include <linux/locks.h>#include <asm/semaphore.h>#include <asm/byteorder.h>#include <linux/version.h>#include <linux/smp_lock.h>#include <linux/sched.h>#include <linux/ctype.h>#include <linux/mtd/compatmac.h>#include "intrep.h"#include "jffs_fm.h"long no_jffs_node = 0;long no_jffs_file = 0;#if defined(JFFS_MEMORY_DEBUG) && JFFS_MEMORY_DEBUGlong no_jffs_control = 0;long no_jffs_raw_inode = 0;long no_jffs_node_ref = 0;long no_jffs_fm = 0;long no_jffs_fmcontrol = 0;long no_hash = 0;long no_name = 0;#endifstatic int jffs_scan_flash(struct jffs_control *c);static int jffs_update_file(struct jffs_file *f, struct jffs_node *node);#if CONFIG_JFFS_FS_VERBOSE > 0static __u8flash_read_u8(struct mtd_info *mtd, loff_t from){	size_t retlen;	__u8 ret;	int res;	res = MTD_READ(mtd, from, 1, &retlen, &ret);	if (retlen != 1) {		printk("Didn't read a byte in flash_read_u8(). Returned %d\n", res);		return 0;	}	return ret;}static voidjffs_hexdump(struct mtd_info *mtd, loff_t pos, int size){	char line[16];	int j = 0;	while (size > 0) {		int i;		printk("%ld:", (long) pos);		for (j = 0; j < 16; j++) {			line[j] = flash_read_u8(mtd, pos++);		}		for (i = 0; i < j; i++) {			if (!(i & 1)) {				printk(" %.2x", line[i] & 0xff);			}			else {				printk("%.2x", line[i] & 0xff);			}		}		/* Print empty space */		for (; i < 16; i++) {			if (!(i & 1)) {				printk("   ");			}			else {				printk("  ");			}		}		printk("  ");		for (i = 0; i < j; i++) {			if (isgraph(line[i])) {				printk("%c", line[i]);			}			else {				printk(".");			}		}		printk("\n");		size -= 16;	}}#endif#define flash_safe_acquire(arg)#define flash_safe_release(arg)static intflash_safe_read(struct mtd_info *mtd, loff_t from,		u_char *buf, size_t count){	size_t retlen;	int res;	D3(printk(KERN_NOTICE "flash_safe_read(%p, %08x, %p, %08x)\n",		  mtd, (unsigned int) from, buf, count));	res = MTD_READ(mtd, from, count, &retlen, buf);	if (retlen != count) {		panic("Didn't read all bytes in flash_safe_read(). Returned %d\n", res);	}	return res?res:retlen;}static __u32flash_read_u32(struct mtd_info *mtd, loff_t from){	size_t retlen;	__u32 ret;	int res;	res = MTD_READ(mtd, from, 4, &retlen, (unsigned char *)&ret);	if (retlen != 4) {		printk("Didn't read all bytes in flash_read_u32(). Returned %d\n", res);		return 0;	}	return ret;}static intflash_safe_write(struct mtd_info *mtd, loff_t to,		 const u_char *buf, size_t count){	size_t retlen;	int res;	D3(printk(KERN_NOTICE "flash_safe_write(%p, %08x, %p, %08x)\n",		  mtd, (unsigned int) to, buf, count));	res = MTD_WRITE(mtd, to, count, &retlen, buf);	if (retlen != count) {		printk("Didn't write all bytes in flash_safe_write(). Returned %d\n", res);	}	return res?res:retlen;}static intflash_safe_writev(struct mtd_info *mtd, const struct iovec *vecs,			unsigned long iovec_cnt, loff_t to){	size_t retlen, retlen_a;	int i;	int res;	D3(printk(KERN_NOTICE "flash_safe_writev(%p, %08x, %p)\n",		  mtd, (unsigned int) to, vecs));		if (mtd->writev) {		res = MTD_WRITEV(mtd, vecs, iovec_cnt, to, &retlen);		return res ? res : retlen;	}	/* Not implemented writev. Repeatedly use write - on the not so	   unreasonable assumption that the mtd driver doesn't care how	   many write cycles we use. */	res=0;	retlen=0;	for (i=0; !res && i<iovec_cnt; i++) {		res = MTD_WRITE(mtd, to, vecs[i].iov_len, &retlen_a, vecs[i].iov_base);		if (retlen_a != vecs[i].iov_len) {			printk("Didn't write all bytes in flash_safe_writev(). Returned %d\n", res);			if (i != iovec_cnt-1)				return -EIO;		}		/* If res is non-zero, retlen_a is undefined, but we don't		   care because in that case it's not going to be 		   returned anyway.		*/		to += retlen_a;		retlen += retlen_a;	}	return res?res:retlen;}static intflash_memset(struct mtd_info *mtd, loff_t to,	     const u_char c, size_t size){	static unsigned char pattern[64];	int i;	/* fill up pattern */	for(i = 0; i < 64; i++)		pattern[i] = c;	/* write as many 64-byte chunks as we can */	while (size >= 64) {		flash_safe_write(mtd, to, pattern, 64);		size -= 64;		to += 64;	}	/* and the rest */	if(size)		flash_safe_write(mtd, to, pattern, size);	return size;}static voidintrep_erase_callback(struct erase_info *done){	wait_queue_head_t *wait_q;	wait_q = (wait_queue_head_t *)done->priv;	wake_up(wait_q);}static intflash_erase_region(struct mtd_info *mtd, loff_t start,		   size_t size){	struct erase_info *erase;	DECLARE_WAITQUEUE(wait, current);	wait_queue_head_t wait_q;	erase = kmalloc(sizeof(struct erase_info), GFP_KERNEL);	if (!erase)		return -ENOMEM;	init_waitqueue_head(&wait_q);	erase->mtd = mtd;	erase->callback = intrep_erase_callback;	erase->addr = start;	erase->len = size;	erase->priv = (u_long)&wait_q;	/* FIXME: Use TASK_INTERRUPTIBLE and deal with being interrupted */	set_current_state(TASK_UNINTERRUPTIBLE);	add_wait_queue(&wait_q, &wait);	if (MTD_ERASE(mtd, erase) < 0) {		set_current_state(TASK_RUNNING);		remove_wait_queue(&wait_q, &wait);		kfree(erase);		printk(KERN_WARNING "flash: erase of region [0x%lx, 0x%lx] "		       "totally failed\n", (long)start, (long)start + size);		return -1;	}	schedule(); /* Wait for flash to finish. */	remove_wait_queue(&wait_q, &wait);	kfree(erase);	return 0;}/* This routine calculates checksums in JFFS.  */__u32jffs_checksum(const void *data, int size){	__u32 sum = 0;	__u8 *ptr = (__u8 *)data;	while (size-- > 0) {		sum += *ptr++;	}	D3(printk(", result: 0x%08x\n", sum));	return sum;}intjffs_checksum_flash(struct mtd_info *mtd, loff_t start, int size, __u32 *result){	__u32 sum = 0;	loff_t ptr = start;	__u8 *read_buf;	int i, length;	/* Allocate read buffer */	read_buf = (__u8 *) kmalloc (sizeof(__u8) * 4096, GFP_KERNEL);	if (!read_buf) {		printk(KERN_NOTICE "kmalloc failed in jffs_checksum_flash()\n");		return -ENOMEM;	}	/* Loop until checksum done */	while (size) {		/* Get amount of data to read */		if (size < 4096)			length = size;		else			length = 4096;		/* Perform flash read */		D3(printk(KERN_NOTICE "jffs_checksum_flash\n"));		flash_safe_read(mtd, ptr, &read_buf[0], length);		/* Compute checksum */		for (i=0; i < length ; i++)			sum += read_buf[i];		/* Update pointer and size */		size -= length;		ptr += length;	}	/* Free read buffer */	kfree (read_buf);	/* Return result */	D3(printk("checksum result: 0x%08x\n", sum));	*result = sum;	return 0;}static __inline__ void jffs_fm_write_lock(struct jffs_fmcontrol *fmc){  //	down(&fmc->wlock);}static __inline__ void jffs_fm_write_unlock(struct jffs_fmcontrol *fmc){  //	up(&fmc->wlock);}/* Create and initialize a new struct jffs_file.  */static struct jffs_file *jffs_create_file(struct jffs_control *c,		 const struct jffs_raw_inode *raw_inode){	struct jffs_file *f;	if (!(f = (struct jffs_file *)kmalloc(sizeof(struct jffs_file),					      GFP_KERNEL))) {		D(printk("jffs_create_file(): Failed!\n"));		return 0;	}	no_jffs_file++;	memset(f, 0, sizeof(struct jffs_file));	f->ino = raw_inode->ino;	f->pino = raw_inode->pino;	f->nlink = raw_inode->nlink;	f->deleted = raw_inode->deleted;	f->c = c;	return f;}/* Build a control block for the file system.  */static struct jffs_control *jffs_create_control(kdev_t dev){	struct jffs_control *c;	register int s = sizeof(struct jffs_control);	int i;	D(char *t = 0);	D2(printk("jffs_create_control()\n"));	if (!(c = (struct jffs_control *)kmalloc(s, GFP_KERNEL))) {		goto fail_control;	}	DJM(no_jffs_control++);	c->root = 0;	c->gc_task = 0;	c->hash_len = JFFS_HASH_SIZE;	s = sizeof(struct list_head) * c->hash_len;	if (!(c->hash = (struct list_head *)kmalloc(s, GFP_KERNEL))) {		goto fail_hash;	}	DJM(no_hash++);	for (i = 0; i < c->hash_len; i++)		INIT_LIST_HEAD(&c->hash[i]);	if (!(c->fmc = jffs_build_begin(c, dev))) {		goto fail_fminit;	}	c->next_ino = JFFS_MIN_INO + 1;	c->delete_list = (struct jffs_delete_list *) 0;	return c;fail_fminit:	D(t = "c->fmc");fail_hash:	kfree(c);	DJM(no_jffs_control--);	D(t = t ? t : "c->hash");fail_control:	D(t = t ? t : "control");	D(printk("jffs_create_control(): Allocation failed: (%s)\n", t));	return (struct jffs_control *)0;}/* Clean up all data structures associated with the file system.  */voidjffs_cleanup_control(struct jffs_control *c){	D2(printk("jffs_cleanup_control()\n"));	if (!c) {		D(printk("jffs_cleanup_control(): c == NULL !!!\n"));		return;	}	while (c->delete_list) {

⌨️ 快捷键说明

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