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

📄 intrep.c

📁 elinux jffs初始版本 具体了解JFFS的文件系统!
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * JFFS -- Journalling Flash File System, Linux implementation. * * Copyright (C) 1999, 2000  Finn Hakansson, Axis Communications, Inc. * * 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.92 2000/01/11 12:26:06 finn Exp $ * *//* This file contains the code for the internal structure of the   Journalling 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. * * Check all comments beginning with XXX. * * 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. * * Fix the rename stuff. (I.e. if we have two files `a' and `b' and we * do a `mv b a'.) Half of this is already implemented. * */#include <linux/module.h>#include <linux/types.h>#include <linux/malloc.h>#include <linux/jffs.h>#include <linux/fs.h>#include <linux/stat.h>#include <linux/pagemap.h>#include <linux/locks.h>#include <asm/byteorder.h>#include "intrep.h"#include "jffs_fm.h"#if defined(CONFIG_JFFS_FS_VERBOSE) && CONFIG_JFFS_FS_VERBOSE#define D(x) x#else#define D(x)#endif#define D1(x)#define D2(x)#define D3(x)#define ASSERT(x) x#if defined(JFFS_MEMORY_DEBUG) && JFFS_MEMORY_DEBUGlong no_jffs_file = 0;long no_jffs_node = 0;long 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 0#define _U      01#define _L      02#define _N      04#define _S      010#define _P      020#define _C      040#define _X      0100#define _B      0200const unsigned char jffs_ctype_[1 + 256] = {	0,	_C,     _C,     _C,     _C,     _C,     _C,     _C,     _C,	_C,     _C|_S,  _C|_S,  _C|_S,  _C|_S,  _C|_S,  _C,     _C,	_C,     _C,     _C,     _C,     _C,     _C,     _C,     _C,	_C,     _C,     _C,     _C,     _C,     _C,     _C,     _C,	_S|_B,  _P,     _P,     _P,     _P,     _P,     _P,     _P,	_P,     _P,     _P,     _P,     _P,     _P,     _P,     _P,	_N,     _N,     _N,     _N,     _N,     _N,     _N,     _N,	_N,     _N,     _P,     _P,     _P,     _P,     _P,     _P,	_P,     _U|_X,  _U|_X,  _U|_X,  _U|_X,  _U|_X,  _U|_X,  _U,	_U,     _U,     _U,     _U,     _U,     _U,     _U,     _U,	_U,     _U,     _U,     _U,     _U,     _U,     _U,     _U,	_U,     _U,     _U,     _P,     _P,     _P,     _P,     _P,	_P,     _L|_X,  _L|_X,  _L|_X,  _L|_X,  _L|_X,  _L|_X,  _L,	_L,     _L,     _L,     _L,     _L,     _L,     _L,     _L,	_L,     _L,     _L,     _L,     _L,     _L,     _L,     _L,	_L,     _L,     _L,     _P,     _P,     _P,     _P,     _C};#define jffs_isalpha(c)      ((jffs_ctype_+1)[c]&(_U|_L))#define jffs_isupper(c)      ((jffs_ctype_+1)[c]&_U)#define jffs_islower(c)      ((jffs_ctype_+1)[c]&_L)#define jffs_isdigit(c)      ((jffs_ctype_+1)[c]&_N)#define jffs_isxdigit(c)     ((jffs_ctype_+1)[c]&(_X|_N))#define jffs_isspace(c)      ((jffs_ctype_+1)[c]&_S)#define jffs_ispunct(c)      ((jffs_ctype_+1)[c]&_P)#define jffs_isalnum(c)      ((jffs_ctype_+1)[c]&(_U|_L|_N))#define jffs_isprint(c)      ((jffs_ctype_+1)[c]&(_P|_U|_L|_N|_B))#define jffs_isgraph(c)      ((jffs_ctype_+1)[c]&(_P|_U|_L|_N))#define jffs_iscntrl(c)      ((jffs_ctype_+1)[c]&_C)voidjffs_hexdump(const unsigned char* ptr, int size){	char line[16];	int j = 0;	while (size > 0) {		int i;		printk("%p:", ptr);		for (j = 0; j < 16; j++) {			line[j] = *ptr++;		}		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 (jffs_isgraph(line[i])) {				printk("%c", line[i]);			}			else {				printk(".");			}		}		printk("\n");		size -= 16;	}}#endifinline intjffs_min(int a, int b){	return (a < b ? a : b);}inline intjffs_max(int a, int b){	return (a > b ? a : b);}/* This routine calculates checksums in JFFS.  */__u32jffs_checksum(const void *data, int size){	__u32 sum = 0;	__u8 *ptr = (__u8 *)data;	D3(printk("#csum at 0x%p, {0x%08lx, 0x%08lx, ... }, size: %d",		  data, *(long *)data, *((long *)data + 1), size));	while (size-- > 0) {		sum += *ptr++;	}	D3(printk(", result: 0x%08x\n", sum));	return sum;}/* 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;	}	DJM(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);	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->hash_len = JFFS_HASH_SIZE;	s = sizeof(struct jffs_file *) * c->hash_len;	if (!(c->hash = (struct jffs_file **)kmalloc(s, GFP_KERNEL))) {		goto fail_hash;	}	DJM(no_hash++);	memset(c->hash, 0, s);	if (!(c->fmc = jffs_build_begin(c, dev))) {		goto fail_fminit;	}	c->next_ino = JFFS_MIN_INO + 1;	c->rename_lock = 0;	c->rename_wait = (struct wait_queue *)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;	}	/* Free all files and nodes.  */	if (c->hash) {		jffs_foreach_file(c, jffs_free_node_list);		kfree(c->hash);		DJM(no_hash--);	}	jffs_cleanup_fmcontrol(c->fmc);	kfree(c);	DJM(no_jffs_control--);	D3(printk("jffs_cleanup_control(): Leaving...\n"));}/* This function adds a virtual root node to the in-RAM representation.   Called by jffs_build_fs().  */static intjffs_add_virtual_root(struct jffs_control *c){	struct jffs_file *root;	struct jffs_node *node;	D2(printk("jffs_add_virtual_root(): "		  "Creating a virtual root directory.\n"));	if (!(root = (struct jffs_file *)kmalloc(sizeof(struct jffs_file),						 GFP_KERNEL))) {		return -ENOMEM;	}	DJM(no_jffs_file++);	if (!(node = (struct jffs_node *)kmalloc(sizeof(struct jffs_node),						 GFP_KERNEL))) {		kfree(root);		DJM(no_jffs_file--);		return -ENOMEM;	}	DJM(no_jffs_node++);	memset(node, 0, sizeof(struct jffs_node));	node->ino = JFFS_MIN_INO;	memset(root, 0, sizeof(struct jffs_file));	root->ino = JFFS_MIN_INO;	root->mode = S_IFDIR | S_IRWXU | S_IRGRP		     | S_IXGRP | S_IROTH | S_IXOTH;	root->atime = root->mtime = root->ctime = CURRENT_TIME;	root->nlink = 1;	root->c = c;	root->version_head = root->version_tail = node;	jffs_insert_file_into_hash(root);	return 0;}/* This is where the file system is built and initialized.  */intjffs_build_fs(struct super_block *sb){	struct jffs_control *c;	int err = 0;	D2(printk("jffs_build_fs()\n"));	if (!(c = jffs_create_control(sb->s_dev))) {		return -ENOMEM;	}	c->building_fs = 1;	c->sb = sb;	if ((err = jffs_scan_flash(c)) < 0) {		goto jffs_build_fs_fail;	}	/* Add a virtual root node if no one exists.  */	if (!jffs_find_file(c, JFFS_MIN_INO)) {		if ((err = jffs_add_virtual_root(c)) < 0) {			goto jffs_build_fs_fail;		}	}	/* Remove deleted nodes.  */	if ((err = jffs_foreach_file(c, jffs_possibly_delete_file)) < 0) {		printk(KERN_ERR "JFFS: Failed to remove deleted nodes.\n");		goto jffs_build_fs_fail;	}	/* Remove redundant nodes.  (We are not interested in the	   return value in this case.)  */	jffs_foreach_file(c, jffs_remove_redundant_nodes);	/* Try to build a tree from all the nodes.  */	if ((err = jffs_foreach_file(c, jffs_insert_file_into_tree)) < 0) {		printk("JFFS: Failed to build tree.\n");		goto jffs_build_fs_fail;	}	/* Compute the sizes of all files in the filesystem.  Adjust if	   necessary.  */	if ((err = jffs_foreach_file(c, jffs_build_file)) < 0) {		printk("JFFS: Failed to build file system.\n");		goto jffs_build_fs_fail;	}	sb->u.generic_sbp = (void *)c;	c->building_fs = 0;	D1(jffs_print_hash_table(c));	D1(jffs_print_tree(c->root, 0));	return 0;jffs_build_fs_fail:	jffs_cleanup_control(c);	return err;} /* jffs_build_fs()  */#if defined(JFFS_FLASH_SHORTCUT) && JFFS_FLASH_SHORTCUT/* Scan the whole flash memory in order to find all nodes in the   file systems.  */static intjffs_scan_flash(struct jffs_control *c){	char name[JFFS_MAX_NAME_LEN + 2];	struct jffs_raw_inode raw_inode;	struct jffs_node *node = 0;	struct jffs_fmcontrol *fmc = c->fmc;	__u32 checksum;	__u8 tmp_accurate;	__u16 tmp_chksum;	unsigned char *pos = (unsigned char *) fmc->flash_start;	unsigned char *start;	unsigned char *end = (unsigned char *)			     (fmc->flash_start + fmc->flash_size);	D1(printk("jffs_scan_flash(): start pos = 0x%p, end = 0x%p\n",		  pos, end));	flash_safe_acquire(fmc->flash_part);	/* Start the scan.  */	while (pos < end) {		/* Remember the position from where we started this scan.  */		start = pos;		switch (*(__u32 *)pos) {		case JFFS_EMPTY_BITMASK:			/* We have found 0xff on this block.  We have to			   scan the rest of the block to be sure it is			   filled with 0xff.  */			D1(printk("jffs_scan_flash(): 0xff at pos 0x%p.\n",				  pos));			for (; pos < end			       && JFFS_EMPTY_BITMASK == *(__u32 *)pos;			     pos += 4);			D1(printk("jffs_scan_flash(): 0xff ended at "				  "pos 0x%p.\n", pos));			continue;		case JFFS_DIRTY_BITMASK:			/* We have found 0x00 on this block.  We have to			   scan as far as possible to find out how much			   is dirty.  */			D1(printk("jffs_scan_flash(): 0x00 at pos 0x%p.\n",				  pos));			for (; pos < end			       && JFFS_DIRTY_BITMASK == *(__u32 *)pos;			     pos += 4);			D1(printk("jffs_scan_flash(): 0x00 ended at "				  "pos 0x%p.\n", pos));			jffs_fmalloced(fmc, (__u32) start,				       (__u32) (pos - start), 0);			continue;		case JFFS_MAGIC_BITMASK:			/* We have probably found a new raw inode.  */			break;		default:		bad_inode:			/* We're f*cked.  This is not solved yet.  We have			   to scan for the magic pattern.  */			D1(printk("*************** Dirty flash memory or bad inode: "				  "hexdump(pos = 0x%p, len = 128):\n",				  pos));			D1(jffs_hexdump(pos, 128));			for (pos += 4; pos < end; pos += 4) {				switch (*(__u32 *)pos) {				case JFFS_MAGIC_BITMASK:					jffs_fmalloced(fmc, (__u32) start,						       (__u32) (pos - start),						       0);					goto cont_scan;				default:					break;				}			}			cont_scan:			continue;		}		/* We have found the beginning of an inode.  Create a		   node for it.  */		if (!node) {			if (!(node = (struct jffs_node *)				     kmalloc(sizeof(struct jffs_node),					     GFP_KERNEL))) {

⌨️ 快捷键说明

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