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

📄 j_intrep.cpp

📁 JFFS的源代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
#include <stdlib.h>
#include <string.h>

//#include "..\..\comm\cmd.h"
#include <io.h>					//livefall
#include "../jffs/jffstypes.h"
#include "../jffs/fs.h"
#include "../jffs/errno.h"
#include "../jffs/stat.h"
#include "../jffs/fcntl.h"
#include "../jffs/jffs.h"
#include "../jffs/jffs_fm.h"
#include "../jffs/j_intrep.h"
#include "../jffs/j_flash.h"
#include "../hdinit/checkfunc.h"

#if defined(JFFS_MEMORY_DEBUG) && JFFS_MEMORY_DEBUG
long no_jffs_file;
long no_jffs_node;
long no_jffs_control;
long no_jffs_raw_inode;
long no_jffs_node_ref;
long no_jffs_fm;
long no_jffs_fmcontrol;
long no_hash;
long no_name;
#endif

#if defined(CONFIG_JFFS_FS_VERBOSE) && CONFIG_JFFS_FS_VERBOSE
#define D(x) x
#define ASSERT(x) x
#else
#define D(x)
#define ASSERT(x)
#endif
#define D1(x)
#define D2(x)
#define D3(x)



#define printk printf

extern unsigned long CURRENT_TIME;
extern struct inode I_FLASH;	/*需填写*/


static struct jffs_control *jffs_create_control(kdev_t dev);
void jffs_cleanup_control(struct jffs_control *c);
static int jffs_scan_flash(struct jffs_control *c);
static void jffs_unlink_node_from_version_list(struct jffs_file *f, struct jffs_node *node);
static void jffs_unlink_node_from_range_list(struct jffs_file *f, struct jffs_node *node);
static int jffs_insert_virtual_data(struct jffs_file *f, struct jffs_node *node);
static int jffs_insert_data(struct jffs_file *f, struct jffs_node *node);
static int jffs_delete_data(struct jffs_file *f, struct jffs_node *node);
static struct jffs_file *jffs_create_file(struct jffs_control *c,
		 const struct jffs_raw_inode *raw_inode);
static int jffs_add_virtual_root(struct jffs_control *c);
static int jffs_update_file(struct jffs_file *f, struct jffs_node *node);

/* This is where the file system is built and initialized.  */
int jffs_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;

	//启动热点: 1380ms
	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;
		}
	}
	/*!!!: 在j_inode.c中直接填充I_FLASH*/

#if 1 /*???*/
	while (c->delete_list) {
		struct jffs_file *f;
		struct jffs_delete_list *delete_list_element;

		if ((f = jffs_find_file(c, c->delete_list->ino))) {
			f->deleted = 1;
		}
		delete_list_element = c->delete_list;
		c->delete_list = c->delete_list->next;
		free(delete_list_element);	/*???*/
	}
#endif

	/* Remove deleted nodes.  */
	if ((err = jffs_foreach_file(c, jffs_possibly_delete_file)) < 0) {
		D1(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) {
		D1(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) {
		D1(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;
}

/* Find a file in a directory.  We are comparing the names.  */
struct jffs_file *jffs_find_child(struct jffs_file *dir, const char *name, int len)
{
	struct jffs_file *f;

	D3(printk("jffs_find_child()\n"));

	for (f = dir->children; f; f = f->sibling_next) {
		if (f->name
		    && !strncmp(f->name, name, len)
		    && f->name[len] == '\0') {
			break;
		}
	}

/*	D3(if (f) {
		printk("jffs_find_child(): Found \"%s\".\n", f->name);
	}
	else {
		char *copy = (char *) kmalloc(len + 1, GFP_KERNEL);
		if (copy) {
			memcpy(copy, name, len);
			copy[len] = '\0';
		}
		printk("jffs_find_child(): Didn't find the file \"%s\".\n",
		       (copy ? copy : ""));
		if (copy) {
			free(copy);
		}
	});*/

	return f;
}



/* Write a raw inode that takes up a certain amount of space in the flash
   memory.  At the end of the flash device, there is often space that is
   impossible to use.  At these times we want to mark this space as not
   used.  In the cases when the amount of space is greater or equal than
   a struct jffs_raw_inode, we write a "dummy node" that takes up this
   space.  The space after the raw inode, if it exists, is left as it is.
   Since this space after the raw inode contains JFFS_EMPTY_BITMASK bytes,
   we can compute the checksum of it; we don't have to manipulate it any
   further.

   If the space left on the device is less than the size of a struct
   jffs_raw_inode, this space is filled with JFFS_DIRTY_BITMASK bytes.
   No raw inode is written this time.  */
static int jffs_write_dummy_node(struct jffs_control *c, struct jffs_fm *dirty_fm)
{
	struct jffs_fmcontrol *fmc = c->fmc;
	int err;

	D1(printk("jffs_write_dummy_node(): dirty_fm->offset = 0x%08x, "
		  "dirty_fm->size = %u\n",
		  dirty_fm->offset, dirty_fm->size));

	if (dirty_fm->size >= sizeof(struct jffs_raw_inode)) {
		struct jffs_raw_inode raw_inode;
		memset(&raw_inode, 0, sizeof(struct jffs_raw_inode));
		raw_inode.magic = JFFS_MAGIC_BITMASK;
		raw_inode.dsize = dirty_fm->size
				  - sizeof(struct jffs_raw_inode);
		raw_inode.dchksum = raw_inode.dsize * 0xff;
		raw_inode.chksum
		= jffs_checksum(&raw_inode, sizeof(struct jffs_raw_inode));

		if ((err = flash_safe_write(fmc->flash_part,
					    (unsigned char *)dirty_fm->offset,
					    (unsigned char *)&raw_inode,
					    sizeof(struct jffs_raw_inode)))
		    < 0) {
			/*printk(KERN_ERR "JFFS: jffs_write_dummy_node: "
			       "flash_safe_write failed!\n");*/
			return err;
		}
	}
	else {
		flash_safe_acquire(fmc->flash_part);
		flash_memset((unsigned char *) dirty_fm->offset, 0,
			     dirty_fm->size);
		flash_safe_release(fmc->flash_part);
	}

	D3(printk("jffs_write_dummy_node(): Leaving...\n"));
	return 0;
}


/* Write a raw inode, possibly its name and possibly some data.  */
int
jffs_write_node(struct jffs_control *c, struct jffs_node *node,
		struct jffs_raw_inode *raw_inode,
		const char *name, const unsigned char *data)
{
	struct jffs_fmcontrol *fmc = c->fmc;
	struct jffs_fm *fm;
	unsigned char *pos;
	int err;
	__u32 total_name_size = raw_inode->nsize
				+ JFFS_GET_PAD_BYTES(raw_inode->nsize);
	__u32 total_data_size = raw_inode->dsize
				+ JFFS_GET_PAD_BYTES(raw_inode->dsize);
	__u32 total_size = sizeof(struct jffs_raw_inode)
			   + total_name_size + total_data_size;

	/* Fire the retrorockets and shoot the fruiton torpedoes, sir!  */

	ASSERT(if (!node) {
		printk("jffs_write_node(): node = NULL\n");
		return -EINVAL;
	});
	ASSERT(if (raw_inode && raw_inode->nsize && !name) {
		printk("*** jffs_write_node(): nsize = %u but name == NULL\n",
		       raw_inode->nsize);
		return -EINVAL;
	});

	D1(printk("jffs_write_node(): filename = \"%s\", ino = %u, "
		  "version = %u, total_size = %u\n",
		  (name ? name : ""), raw_inode->ino,
		  raw_inode->version, total_size));

	/* First try to allocate some flash memory.  */
	if ((err = jffs_fmalloc(fmc, total_size, node, &fm)) < 0) {
		D(printk("jffs_write_node(): jffs_fmalloc(0x%p, %u) "
			 "failed!\n", fmc, total_size));
		return err;
	}
	else if (!fm->nodes) {
		/* The jffs_fm struct that we got is not good enough.
		   Make that space dirty.  */
		if ((err = jffs_write_dummy_node(c, fm)) < 0) {
			D(printk("jffs_write_node(): "
				 "jffs_write_dummy_node(): Failed!\n"));
			free(fm);
			DJM(no_jffs_fm--);
			return err;
		}
		/* Get a new one.  */
		if ((err = jffs_fmalloc(fmc, total_size, node, &fm)) < 0) {
			D(printk("jffs_write_node(): Second "
				 "jffs_fmalloc(0x%p, %u) failed!\n",
				 fmc, total_size));
			return err;
		}
	}
	node->fm = fm;

	ASSERT(if (fm->nodes == 0) {
		printk("jffs_write_node(): fm->nodes == 0\n");
	});

	pos = (unsigned char *) node->fm->offset;

	/* Compute the checksum for the data and name chunks.  */
	raw_inode->dchksum = jffs_checksum(data, raw_inode->dsize);
	raw_inode->nchksum = jffs_checksum(name, raw_inode->nsize);

	/* The checksum is calculated without the chksum and accurate
	   fields so set them to zero first.  */
	raw_inode->accurate = 0;
	raw_inode->chksum = 0;
	raw_inode->chksum = jffs_checksum(raw_inode,
					  sizeof(struct jffs_raw_inode));
	raw_inode->accurate = 0xff;

	D3(printk("jffs_write_node(): About to write this raw inode to the "
		  "flash at pos 0x%p:\n", pos));
	D3(jffs_print_raw_inode(raw_inode));

	/* Step 1: Write the raw jffs inode to the flash.  */
	if ((err = flash_safe_write(fmc->flash_part, pos,
				    (unsigned char *)raw_inode,
				    sizeof(struct jffs_raw_inode))) < 0) {
		jffs_fmfree_partly(fmc, fm,
				   total_name_size + total_data_size);
		D(printk("JFFS: jffs_write_node: Failed to write "
		       "raw_inode.\n"));
		return err;
	}
	pos += sizeof(struct jffs_raw_inode);

	/* Step 2: Write the name, if there is any.  */
	if (raw_inode->nsize) {
		if ((err = flash_safe_write(fmc->flash_part, pos,
					    (unsigned char *)name,
					    raw_inode->nsize)) < 0) {
			jffs_fmfree_partly(fmc, fm, total_data_size);
			D(printk("JFFS: jffs_write_node: Failed to "
			       "write the name.\n"));
			return err;
		}
		pos += total_name_size;
	}

	/* Step 3: Append the actual data, if any.  */
	if (raw_inode->dsize) {
		if ((err = flash_safe_write(fmc->flash_part, pos, data,
					    raw_inode->dsize)) < 0) {
			jffs_fmfree_partly(fmc, fm, 0);
			D(printk("JFFS: jffs_write_node: Failed to "
			       "write the data.\n"));
			return err;
		}
	}

	D3(printk("jffs_write_node(): Leaving...\n"));
	return raw_inode->dsize;
} /* jffs_write_node()  */

/* Insert any kind of node into the file system.  Take care of data
   insertions and deletions.  Also remove redundant information. The
   memory allocated for the `name' is regarded as "given away" in the
   caller's perspective.  */
int jffs_insert_node(struct jffs_control *c, struct jffs_file *f,
		 const struct jffs_raw_inode *raw_inode,
		 const char *name, struct jffs_node *node)
{
	int update_name = 0;
	int insert_into_tree = 0;

	D2(printk("jffs_insert_node(): ino = %u, version = %u, "
		  "name = \"%s\"\n",
		  raw_inode->ino, raw_inode->version,
		  ((name && *name) ? name : "")));

	/* If there doesn't exist an associated jffs_file, then
	   create, initialize and insert one into the file system.  */
	if (!f && !(f = jffs_find_file(c, raw_inode->ino))) {
		if (!(f = jffs_create_file(c, raw_inode))) {
			return -ENOMEM;
		}
		jffs_insert_file_into_hash(f);
		insert_into_tree = 1;
	}

	node->ino = raw_inode->ino;
	node->version = raw_inode->version;
	node->data_size = raw_inode->dsize;
	node->fm_offset = sizeof(struct jffs_raw_inode) + raw_inode->nsize
			  + JFFS_GET_PAD_BYTES(raw_inode->nsize);
	node->name_size = raw_inode->nsize;

	/* Now insert the node at the correct position into the file's
	   version list.  */
	if (!f->version_head) {
		/* This is the first node.  */
		f->version_head = node;
		f->version_tail = node;
		node->version_prev = 0;
		node->version_next = 0;
		f->highest_version = node->version;
		update_name = 1;
		f->mode = raw_inode->mode;
		f->uid = raw_inode->uid;
		f->gid = raw_inode->gid;
		f->atime = raw_inode->atime;
		f->mtime = raw_inode->mtime;
		f->ctime = raw_inode->ctime;
		f->deleted = raw_inode->deleted;
	}
	else if ((f->highest_version < node->version) /*???*/
		 || (node->version == 0)) {
		/* Insert at the end of the list.  I.e. this node is the
		   oldest one so far.  */
		node->version_prev = f->version_tail;
		node->version_next = 0;
		f->version_tail->version_next = node;
		f->version_tail = node;
		f->highest_version = node->version;
		update_name = 1;
		f->pino = raw_inode->pino;
		f->mode = raw_inode->mode;
		f->uid = raw_inode->uid;
		f->gid = raw_inode->gid;
		f->atime = raw_inode->atime;
		f->mtime = raw_inode->mtime;
		f->ctime = raw_inode->ctime;
		f->deleted = raw_inode->deleted;
	}
	else if (f->version_head->version > node->version) {
		/* Insert at the bottom of the list.  */
		node->version_prev = 0;
		node->version_next = f->version_head;
		f->version_head->version_prev = node;
		f->version_head = node;
		if (!f->name) {
			update_name = 1;
		}
		if (raw_inode->deleted) {
			f->deleted = raw_inode->deleted;
		}
	}
	else {
		struct jffs_node *n;
		int newer_name = 0;
		/* Search for the insertion position starting from
		   the tail (newest node).  */
		for (n = f->version_tail; n; n = n->version_prev) {
			if (n->version < node->version) {
				node->version_prev = n;
				node->version_next = n->version_next;
				node->version_next->version_prev = node;
				n->version_next = node;
				if (!newer_name) {
					update_name = 1;
				}
				break;
			}
			if (n->name_size) {
				newer_name = 1;
			}
		}
	}

	/* Perhaps update the name.  */
	if (raw_inode->nsize && update_name && name && *name
	    && (name != f->name)) {

⌨️ 快捷键说明

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