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

📄 j_intrep.cpp

📁 JFFS的源代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
				}
				virtual_node->version_next = n;
				break;
			}
		}

		D1(jffs_print_node(virtual_node));
	return 0;
}

/* Insert some data into a file.  Prior to the call to this function,
   jffs_delete_data should be called.  */
static int jffs_insert_data(struct jffs_file *f, struct jffs_node *node)
{
	D3(printk("jffs_insert_data(): node->data_offset = %u, "
		  "node->data_size = %u, f->size = %u\n",
		  node->data_offset, node->data_size, f->size));

	/* Find the position where we should insert data.  */
	//retry:
	if (node->data_offset == f->size) {
		/* A simple append.  This is the most common operation.  */
		node->range_next = 0;
		node->range_prev = f->range_tail;
		if (node->range_prev) {
			node->range_prev->range_next = node;
		}
		f->range_tail = node;
		f->size += node->data_size;
		if (!f->range_head) {
			f->range_head = node;
		}
	}
	else if (node->data_offset < f->size) {
		/* Trying to insert data into the middle of the file.  This
		   means no problem because jffs_delete_data() has already
		   prepared the range list for us.  */
		struct jffs_node *n;

		/* Find the correct place for the insertion and then insert
		   the node.  */
		for (n = f->range_head; n; n = n->range_next) {
			D1(printk("Cool stuff's happening!\n"));

			if (n->data_offset == node->data_offset) {
				node->range_prev = n->range_prev;
				if (node->range_prev) {
					node->range_prev->range_next = node;
				}
				else {
					f->range_head = node;
				}
				node->range_next = n;
				n->range_prev = node;
				break;
			}
			ASSERT(else if (n->data_offset + n->data_size >
					node->data_offset) {
				printk("jffs_insert_data(): "
				       "Couldn't find a place to insert "
				       "the data!\n");
				return -1;
			});
		}

		/* Adjust later nodes' offsets etc.  */
		n = node->range_next;
		while (n) {
			n->data_offset += node->data_size;
			n = n->range_next;
		}
		f->size += node->data_size;
	}
	else if (node->data_offset > f->size) 
	{
	//转为jffs_insert_virtual_data
	}

	D3(printk("jffs_insert_data(): f->size = %d\n", f->size));
	return 0;
}

/* See if a file is deleted. If so, mark that file's nodes as obsolete.  */
int jffs_possibly_delete_file(struct jffs_file *f)
{
	struct jffs_node *n;

	D3(printk("jffs_possibly_delete_file(): ino: %u\n", f->ino));

	ASSERT(if (!f) {
		/*printk(KERN_ERR "jffs_possibly_delete_file(): f == NULL\n");*/
		return -1;
	});

	if (f->deleted) {
		/* First try to remove all older versions.  Commence with
		   the oldest node.  */
		for (n = f->version_head; n; n = n->version_next) {
			if (!n->fm) {
				continue;
			}
			if (jffs_fmfree(f->c->fmc, n->fm, n) < 0) {
				break;
			}
		}
		/* Unlink the file from the filesystem.  */
		if (!f->c->building_fs) {
			jffs_unlink_file_from_tree(f);
		}
		jffs_unlink_file_from_hash(f);
		jffs_free_node_list(f);
		jffs_free_file(f);
	}
	return 0;
}

/* Function used by jffs_remove_redundant_nodes() below.  This function
   classifies what kind of information a node adds to a file.  */
static __u8 jffs_classify_node(struct jffs_node *node)
{
	__u8 mod_type = JFFS_MODIFY_INODE;

	if (node->name_size) {
		mod_type |= JFFS_MODIFY_NAME;
	}
	if (node->data_size || node->removed_size) {
		mod_type |= JFFS_MODIFY_DATA;
	}
	return mod_type;
}

/* Remove redundant nodes from a file.  Mark the on-flash memory as dirty.  */
int jffs_remove_redundant_nodes(struct jffs_file *f)
{
	struct jffs_node *newest_node;
	struct jffs_node *cur;
	struct jffs_node *prev;
	__u8 newest_type;
	__u8 mod_type;
	__u8 node_with_name_later = 0;

	if (!(newest_node = f->version_tail)) {
		return 0;
	}

	/* What does the `newest_node' modify?  */
	newest_type = jffs_classify_node(newest_node);
	node_with_name_later = newest_type & JFFS_MODIFY_NAME;

	D3(printk("jffs_remove_redundant_nodes(): ino: %u, name: \"%s\", "
		  "newest_type: %u\n", f->ino, (f->name ? f->name : ""),
		  newest_type));

	/* Traverse the file's nodes and determine which of them that are
	   superfluous.  Yeah, this might look very complex at first
	   glance but it is actually very simple.  */
	for (cur = newest_node->version_prev; cur; cur = prev) {
		prev = cur->version_prev;
		mod_type = jffs_classify_node(cur);
		if ((mod_type <= JFFS_MODIFY_INODE) //不起修改作用
		    || ((newest_type & JFFS_MODIFY_NAME)//仅仅修改名
			&& (mod_type
			    <= (JFFS_MODIFY_INODE + JFFS_MODIFY_NAME)))
		    || (cur->data_size == 0 && cur->removed_size //只删除数据
			&& !cur->version_prev && node_with_name_later)) {
			/* Yes, this node is redundant. Remove it.  */
			D2(printk("jffs_remove_redundant_nodes(): "
				  "Removing node: ino: %u, version: %u, "
				  "mod_type: %u\n", cur->ino, cur->version,
				  mod_type));
			jffs_unlink_node_from_version_list(f, cur);
			jffs_fmfree(f->c->fmc, cur->fm, cur);
			free(cur);
			DJM(no_jffs_node--);
		}
		else {
			node_with_name_later |= (mod_type & JFFS_MODIFY_NAME);
		}
	}
	return 0;
}

/* 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 *)malloc(s))) {
		D(printk("jffs_control(): c == 0\n"));
		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 **)malloc(s))) {
		D(printk("jffs_control(): c->hash == 0\n"));
		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;*/
	c->delete_list = (struct jffs_delete_list *) 0;
	return c;

fail_fminit:
	D(t = "c->fmc");
fail_hash:
	free(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.  */
void jffs_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) {
		struct jffs_delete_list *delete_list_element;
		delete_list_element = c->delete_list;
		c->delete_list = c->delete_list->next;
		free(delete_list_element);
	}

	/* Free all files and nodes.  */
	if (c->hash) {
		jffs_foreach_file(c, jffs_free_node_list);
		jffs_foreach_file(c, jffs_free_file);
		free(c->hash);
		DJM(no_hash--);
	}
	jffs_cleanup_fmcontrol(c->fmc);
	free(c);
	DJM(no_jffs_control--);
	D3(printk("jffs_cleanup_control(): Leaving...\n"));
}

/* Scan the whole flash memory in order to find all nodes in the
   file systems.  */
static int jffs_scan_flash(struct jffs_control *c)
{
	int i;
	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;
	__u32 deleted_file;
	unsigned char *pos = (unsigned char *) fmc->flash_start;
	unsigned char *start;
	unsigned char *end = (unsigned char *)
			     (fmc->flash_start + fmc->flash_size);

	void record_start_time(char *flag);

	printf("Jffs scan flash...\n");

	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) {
		deleted_file = 0;
		
		clearHW();	//+

		/* Remember the position from where we started this scan.  */
		start = pos;

		switch (*(__u32 *)pos) {
		case JFFS_EMPTY_BITMASK:
			/* We have found 0xff at this position.  We have to
			   scan the rest of the flash till the end or till
			   something else than 0xff is found.  */
			
			D1(printk("jffs_scan_flash(): 0xff at pos 0x%p.\n",
				  pos));
			for (i=0; pos < end
			       && JFFS_EMPTY_BITMASK == *(__u32 *)pos;
			     pos += 4){
			     if(i++ > 16000){ clearHW(); i=0;}
			}
			D1(printk("jffs_scan_flash(): 0xff ended at "
				  "pos 0x%p.\n", pos));
			continue;

		case JFFS_MAGIC_BITMASK:
			/* We have probably found a new raw inode.  */	
			break;

#if 0
		case JFFS_DIRTY_BITMASK:
			/* We have found 0x00 at this position.  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;
#endif

		default:
		bad_inode:
			//防止非法节点导致死循环
			pos += 4; 
			
			/* 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 (i=0; pos < end
			       && JFFS_EMPTY_BITMASK != *(__u32 *)pos
			       && JFFS_MAGIC_BITMASK != *(__u32 *)pos;
			     pos += 4){
		     	if(i++ > 16000){ clearHW(); i=0;}
			}     	

			jffs_fmalloced(fmc, (__u32) start, (__u32) (pos - start), 0);
			
			/*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 unless there already is one available.  */
		if (!node) {
			if (!(node = (struct jffs_node *)
				     malloc(sizeof(struct jffs_node)))) {
				D(printk("jffs_scan_flash(): node == 0\n"));
				flash_safe_release(fmc->flash_part);
				return -ENOMEM;
			}
			DJM(no_jffs_node++);
		}

		/* Read the next raw inode.  */
		memcpy(&raw_inode, pos, sizeof(struct jffs_raw_inode));

		/* When we compute the checksum for the inode, we never
		   count the 'accurate' or the 'checksum' fields.  */
		tmp_accurate = raw_inode.accurate;
		tmp_chksum = raw_inode.chksum;
		raw_inode.accurate = 0;
		raw_inode.chksum = 0;
		checksum = jffs_checksum(&raw_inode,
					 sizeof(struct jffs_raw_inode));
		raw_inode.accurate = tmp_accurate;
		raw_inode.chksum = tmp_chksum;

		D3(printk("*** We have found this raw inode at pos 0x%p "
			  "on the flash:\n", pos));
		D3(jffs_print_raw_inode(&raw_inode));

		if (checksum != raw_inode.chksum) {
			D1(printk("jffs_scan_flash(): Bad checksum: "
				  "checksum = %u, "
				  "raw_inode.chksum = %u\n",
				  checksum, raw_inode.chksum));
			pos += sizeof(struct jffs_raw_inode);
			jffs_fmalloced(fmc, (__u32) start,
				       (__u32) (pos - start), 0);
			/* Reuse the unused jffs_node struct.  */
			continue;
		}

		/* Check the raw inode read so far.  Start with the
		   maximum length of the filename.  */
		if (raw_inode.nsize > JFFS_MAX_NAME_LEN) {
			goto bad_inode;
		}

		if (raw_inode.rename && raw_inode.dsize != sizeof(__u32)) {
			/*printk(KERN_WARNING "jffs_scan_flash: Found a "
			       "rename node with dsize %u.\n",
			       raw_inode.dsize);
			jffs_print_raw_inode(&raw_inode);*/
			goto bad_inode;
		}

		/* The node's data segment should not exceed a
		   certain length.  */
		//与老文件系统兼容
		//if (raw_inode.dsize > fmc->max_chunk_size) {
		if (raw_inode.dsize > (fmc->sector_size/2) ) { 
			printf("WARNING: bad inode for raw_inode.dsize\n");
			goto bad_inode;
		}

		pos += sizeof(struct jffs_raw_inode);

		/* This shouldn't be necessary because a node that
		   violates the flash boundaries shouldn't be written
		   in the first place. */
		if (pos >= end) {
			goto check_node;
		}

		/* Read the name.  */
		*name = 0;
		if (raw_inode.nsize) {
			memcpy(name, pos, raw_inode.nsize);
			name[raw_inode.nsize] = '\0';
			pos += raw_inode.nsize
			       + JFFS_GET_PAD_BYTES(raw_inode.nsize);
			D3(printk("name == \"%s\"\n", name));
			checksum = jffs_checksum(name, raw_inode.nsize);
			if (checksum != raw_inode.nchksum) {
				D1(printk("jffs_scan_flash(): Bad checksum: "
					  "checksum = %u, "
					  "raw_inode.nchksum = %u\n",
					  checksum, raw_inode.nchksum));
				jffs_fmalloced(fmc, (__u32) start,

⌨️ 快捷键说明

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