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

📄 intrep.c

📁 mtd最新cvs jffs文件系统分析
💻 C
📖 第 1 页 / 共 5 页
字号:
		}		jffs_remove_redundant_nodes(f);		jffs_garbage_collect_trigger(c);		D3(printk("jffs_insert_node(): ---------------------------"			  "------------------------------------------- 2\n"));	}	return 0;} /* jffs_insert_node()  *//* Unlink a jffs_node from the version list it is in.  */static inline voidjffs_unlink_node_from_version_list(struct jffs_file *f,				   struct jffs_node *node){	if (node->version_prev) {		node->version_prev->version_next = node->version_next;	} else {		f->version_head = node->version_next;	}	if (node->version_next) {		node->version_next->version_prev = node->version_prev;	} else {		f->version_tail = node->version_prev;	}}/* Unlink a jffs_node from the range list it is in.  */static inline voidjffs_unlink_node_from_range_list(struct jffs_file *f, struct jffs_node *node){	if (node->range_prev) {		node->range_prev->range_next = node->range_next;	}	else {		f->range_head = node->range_next;	}	if (node->range_next) {		node->range_next->range_prev = node->range_prev;	}	else {		f->range_tail = node->range_prev;	}}/* Function used by jffs_remove_redundant_nodes() below.  This function   classifies what kind of information a node adds to a file.  */static inline __u8jffs_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.  */intjffs_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);			jffs_free_node(cur);			DJM(no_jffs_node--);		}		else {			node_with_name_later |= (mod_type & JFFS_MODIFY_NAME);		}	}	return 0;}/* Insert a file into the hash table.  */intjffs_insert_file_into_hash(struct jffs_file *f){	int i = f->ino % f->c->hash_len;	D3(printk("jffs_insert_file_into_hash(): f->ino: %u\n", f->ino));	list_add(&f->hash, &f->c->hash[i]);	return 0;}/* Insert a file into the file system tree.  */intjffs_insert_file_into_tree(struct jffs_file *f){	struct jffs_file *parent;	D3(printk("jffs_insert_file_into_tree(): name: \"%s\"\n",		  (f->name ? f->name : "")));	if (!(parent = jffs_find_file(f->c, f->pino))) {		if (f->pino == 0) {			f->c->root = f;			f->parent = 0;			f->sibling_prev = 0;			f->sibling_next = 0;			return 0;		}		else {			D1(printk("jffs_insert_file_into_tree(): Found "				  "inode with no parent and pino == %u\n",				  f->pino));			return -1;		}	}	f->parent = parent;	f->sibling_next = parent->children;	if (f->sibling_next) {		f->sibling_next->sibling_prev = f;	}	f->sibling_prev = 0;	parent->children = f;	return 0;}/* Remove a file from the hash table.  */intjffs_unlink_file_from_hash(struct jffs_file *f){	D3(printk("jffs_unlink_file_from_hash(): f: 0x%p, "		  "ino %u\n", f, f->ino));	list_del(&f->hash);	return 0;}/* Just remove the file from the parent's children.  Don't free   any memory.  */intjffs_unlink_file_from_tree(struct jffs_file *f){	D3(printk("jffs_unlink_file_from_tree(): ino: %d, pino: %d, name: "		  "\"%s\"\n", f->ino, f->pino, (f->name ? f->name : "")));	if (f->sibling_prev) {		f->sibling_prev->sibling_next = f->sibling_next;	}	else if (f->parent) {	        D3(printk("f->parent=%p\n", f->parent));		f->parent->children = f->sibling_next;	}	if (f->sibling_next) {		f->sibling_next->sibling_prev = f->sibling_prev;	}	return 0;}/* Find a file with its inode number.  */struct jffs_file *jffs_find_file(struct jffs_control *c, __u32 ino){	struct jffs_file *f;	int i = ino % c->hash_len;	struct list_head *tmp;	D3(printk("jffs_find_file(): ino: %u\n", ino));	for (tmp = c->hash[i].next; tmp != &c->hash[i]; tmp = tmp->next) {		f = list_entry(tmp, struct jffs_file, hash);		if (ino != f->ino)			continue;		D3(printk("jffs_find_file(): Found file with ino "			       "%u. (name: \"%s\")\n",			       ino, (f->name ? f->name : ""));		);		return f;	}	D3(printk("jffs_find_file(): Didn't find file "			 "with ino %u.\n", ino);	);	return NULL;}/* 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->deleted && 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) {			kfree(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 intjffs_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->mtd,					    dirty_fm->offset,					    (u_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->mtd);		flash_memset(fmc->mtd, dirty_fm->offset, 0, dirty_fm->size);		flash_safe_release(fmc->mtd);	}	D3(printk("jffs_write_dummy_node(): Leaving...\n"));	return 0;}/* Write a raw inode, possibly its name and possibly some data.  */intjffs_write_node(struct jffs_control *c, struct jffs_node *node,		struct jffs_raw_inode *raw_inode,		const char *name, const unsigned char *data,		int recoverable,		struct jffs_file *f){	struct jffs_fmcontrol *fmc = c->fmc;	struct jffs_fm *fm;	struct iovec node_iovec[4];	unsigned long iovec_cnt;	__u32 pos;	int err;	__u32 slack = 0;	__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;		/* If this node isn't something that will eventually let	   GC free even more space, then don't allow it unless	   there's at least max_chunk_size space still available	*/	if (!recoverable)		slack = fmc->max_chunk_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, "		  "total_size = %u\n",		  (name ? name : ""), raw_inode->ino,		  total_size));	jffs_fm_write_lock(fmc);retry:	fm = NULL;	err = 0;	while (!fm) {		/* Deadlocks suck. */		while(fmc->free_size < fmc->min_free_size + total_size + slack) {			jffs_fm_write_unlock(fmc);			if (!JFFS_ENOUGH_SPACE(c, total_size + slack))				return -ENOSPC;			jffs_fm_write_lock(fmc);		}		/* First try to allocate some flash memory.  */		err = jffs_fmalloc(fmc, total_size, node, &fm);				if (err == -ENOSPC) {			/* Just out of space. GC and try again */			if (fmc->dirty_size < fmc->sector_size) {				D(printk("jffs_write_node(): jffs_fmalloc(0x%p, %u) "					 "failed, no dirty space to GC\n", fmc,					 total_size));				return err;			}						D1(printk(KERN_INFO "jffs_write_node(): Calling jffs_garbage_collect_now()\n"));			jffs_fm_write_unlock(fmc);			if ((err = jffs_garbage_collect_now(c))) {				D(printk("jffs_write_node(): jffs_garbage_collect_now() failed\n"));				return err;			}			jffs_fm_write_lock(fmc);			continue;		} 		if (err < 0) {			jffs_fm_write_unlock(fmc);			D(printk("jffs_write_node(): jffs_fmalloc(0x%p, %u) "				 "failed!\n", fmc, total_size));			return err;		}		if (!fm->nodes) {			/* The jffs_fm struct that we got is not good enough.			   Make that space dirty and try again  */			if ((err = jffs_write_dummy_node(c, fm)) < 0) {				kfree(fm);				DJM(no_jffs_fm--);				jffs_fm_write_unlock(fmc);				D(printk("jffs_write_node(): "					 "jffs_write_dummy_node(): Failed!\n"));				return err;			}			fm = NULL;		}	} /* while(!fm) */	node->fm = fm;	ASSERT(if (fm->nodes == 0) {		printk(KERN_ERR "jffs_write_node(): fm->nodes == 0\n");	});	pos = node->fm->offset;	/* Increment the version number here. We can't let the caller	   set it beforehand, because we might have had to do GC on a node	   of this file - and we'd end up reusing version numbers.	*/	if (f) {		raw_inode->version = f->highest_version + 1;		D1(printk (KERN_NOTICE "jffs_write_node(): setting version of %s to %d\n", f->name, raw_inode->version));		/* if the file was deleted, set the deleted bit in the raw inode */		if (f->deleted)			raw_inode->deleted = 1;	}	/* 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%lx:\n", (long)pos));	D3(jffs_print_raw_inode(raw_inode));	/* The actual raw JFFS node */	node_iovec[0].iov_base = (void *) raw_inode;	node_iovec[0].iov_len = (size_t) sizeof(struct jffs_raw_inode);	iovec_cnt = 1;	/* Get name and size if there is one */	if (raw_inode->nsize) {		node_iovec[iovec_cnt].iov_base = (void *) name;		node_iovec[iovec_cnt].iov_len = (size_t) raw_inode->nsize;		iovec_cnt++;		if (JFFS_GET_PAD_BYTES(raw_inode->nsize)) {			static char allff[3]={255,255,255};			/* Add some extra padding if necessary */			node_iovec[iovec_cnt].iov_base = allff;			node_iovec[iovec_cnt].iov_len =				JFFS_GET_PAD_BYTES(raw_inode->nsize);			iovec_cnt++;		}	}

⌨️ 快捷键说明

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