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

📄 intrep.c

📁 elinux jffs初始版本 具体了解JFFS的文件系统!
💻 C
📖 第 1 页 / 共 5 页
字号:
	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) {		if (f->name) {			kfree(f->name);			DJM(no_name--);		}		if (!(f->name = (char *) kmalloc(raw_inode->nsize + 1,						 GFP_KERNEL))) {			return -ENOMEM;		}		DJM(no_name++);		memcpy(f->name, name, raw_inode->nsize);		f->name[raw_inode->nsize] = '\0';		f->nsize = raw_inode->nsize;		D3(printk("jffs_insert_node(): Updated the name of "			  "the file to \"%s\".\n", name));	}	if (!c->building_fs) {		D3(printk("jffs_insert_node(): ---------------------------"			  "------------------------------------------- 1\n"));		if (insert_into_tree) {			jffs_insert_file_into_tree(f);		}		if (f->deleted) {			/* Mark all versions of the node as obsolete.  */			jffs_possibly_delete_file(f);		}		else {			if (node->data_size || node->removed_size) {				jffs_update_file(f, node);			}			jffs_remove_redundant_nodes(f);		}#ifdef USE_GC		if (!c->fmc->no_call_gc) {			jffs_garbage_collect(c);		}#endif		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);			kfree(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));	f->hash_next = f->c->hash[i];	if (f->hash_next) {		f->hash_next->hash_prev = f;	}	f->hash_prev = 0;	f->c->hash[i] = f;	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));	if (f->hash_next) {		f->hash_next->hash_prev = f->hash_prev;	}	if (f->hash_prev) {		f->hash_prev->hash_next = f->hash_next;	}	else {		f->c->hash[f->ino % f->c->hash_len] = f->hash_next;	}	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, name: "		  "\"%s\"\n", f->ino, (f->name ? f->name : "")));	if (f->sibling_prev) {		f->sibling_prev->sibling_next = f->sibling_next;	}	else {		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;	D3(printk("jffs_find_file(): ino: %u\n", ino));	for (f = c->hash[i]; f && (ino != f->ino); f = f->hash_next);	D3(if (f) {		printk("jffs_find_file(): Found file with ino "		       "%u. (name: \"%s\")\n",		       ino, (f->name ? f->name : ""));	}	else {		printk("jffs_find_file(): Didn't find file "			 "with ino %u.\n", ino);	});	return f;}/* 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) {			kfree(copy);		}	});	return f;}#if !defined(JFFS_FLASH_SHORTCUT) || ! JFFS_FLASH_SHORTCUTstruct buffer_head *jffs_get_write_buffer(kdev_t dev, int block){	struct buffer_head *bh;	D3(printk("jffs_get_write_buffer(): block = %u\n", block));	if (!(bh = bread(dev, block, BLOCK_SIZE))) {		D(printk("jffs_get_write_buffer(): bread() failed. "			 "(block == %u)\n", block));	}	D3(printk("jffs_get_write_buffer(): bh = 0x%08x\n", bh));	return bh;}voidjffs_put_write_buffer(struct buffer_head *bh){	D3(printk("jffs_put_write_buffer(): bh = 0x%08x\n", bh));	mark_buffer_dirty(bh, 1);	ll_rw_block(WRITE, 1, &bh);	wait_on_buffer(bh);	brelse(bh);}/* Structure used by jffs_write_chunk() and jffs_write_node().  */struct jffs_write_task{	struct buffer_head *bh;	__u32 block;	__u32 block_offset;};/* Write a chunk of data to the flash memory.  This is a helper routine   to jffs_write_node().  */intjffs_write_chunk(struct jffs_control *c, struct jffs_write_task *wt,		 const unsigned char *data, __u32 size){	int write_len = 0;	int len;	int buf_pos = 0;	D3(printk("jffs_write_chunk(): size = %u\n", size));	ASSERT(if (!wt) {		printk("jffs_write_chunk(): wt == NULL\n");		return -1;	});	if (size == 0) {		return 0;	}	if (wt->block_offset == BLOCK_SIZE) {		if (wt->bh) {			jffs_put_write_buffer(wt->bh);			wt->bh = 0;		}		wt->block++;		wt->block_offset = 0;	}	if (!wt->bh	    && !(wt->bh = jffs_get_write_buffer(c->sb->s_dev, wt->block))) {		return -1;	}	while (write_len < size) {		len = jffs_min(size - write_len,			       BLOCK_SIZE - wt->block_offset);		memcpy(&wt->bh->b_data[wt->block_offset],		       &data[buf_pos], len);		write_len += len;		wt->block_offset += len;		D3(printk("  write_len: %u\n", write_len));		D3(printk("  len: %u\n", len));		D3(printk("  size: %u\n", size));		if (write_len < size) {			jffs_put_write_buffer(wt->bh);			wt->block++;			wt->block_offset = 0;			wt->bh = 0;			if (!(wt->bh = jffs_get_write_buffer(c->sb->s_dev,							     wt->block))) {				return write_len;			}			buf_pos += len;		}

⌨️ 快捷键说明

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