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

📄 intrep.c

📁 elinux jffs初始版本 具体了解JFFS的文件系统!
💻 C
📖 第 1 页 / 共 5 页
字号:
}/* Used for traversing all nodes in the hash table.  */intjffs_foreach_file(struct jffs_control *c, int (*func)(struct jffs_file *)){	struct jffs_file *f;	struct jffs_file *next_f;	int pos;	int r;	int result = 0;	for (pos = 0; pos < c->hash_len; pos++) {		for (f = c->hash[pos]; f; f = next_f) {			/* We need a reference to the next file in the			   list because `func' might remove the current			   file `f'.  */			next_f = f->hash_next;			if ((r = func(f)) < 0) {				return r;			}			result += r;		}	}	return result;}/* Free all memory associated with a file.  */intjffs_free_node_list(struct jffs_file *f){	struct jffs_node *node;	struct jffs_node *p;	D3(printk("jffs_free_node_list(): f #%u, \"%s\"\n",		  f->ino, (f->name ? f->name : "")));	node = f->version_head;	while (node) {		p = node;		node = node->version_next;		kfree(p);		DJM(no_jffs_node--);	}	return 0;}/* See if a file is deleted. If so, mark that file's nodes as obsolete.  */intjffs_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.  */		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.  */		jffs_unlink_file_from_tree(f);		jffs_unlink_file_from_hash(f);		jffs_free_node_list(f);		if (f->name) {			kfree(f->name);			DJM(no_name--);		}		kfree(f);		DJM(no_jffs_file--);	}	return 0;}/* Used in conjunction with jffs_foreach_file() to count the number   of files in the file system.  */intjffs_file_count(struct jffs_file *f){	return 1;}/* Build up a file's range list from scratch by going through the   version list.  */intjffs_build_file(struct jffs_file *f){	struct jffs_node *n;	D3(printk("jffs_build_file(): ino: %u, name: \"%s\"\n",		  f->ino, (f->name ? f->name : "")));	for (n = f->version_head; n; n = n->version_next) {		jffs_update_file(f, n);	}	return 0;}/* Remove an amount of data from a file. If this amount of data is   zero, that could mean that a node should be split in two parts.   We remove or change the appropriate nodes in the lists.   Starting offset of area to be removed is node->data_offset,   and the length of the area is in node->removed_size.   */static voidjffs_delete_data(struct jffs_file *f, struct jffs_node *node){	struct jffs_node *n;	__u32 offset = node->data_offset;	__u32 remove_size = node->removed_size;	D3(printk("jffs_delete_data(): offset = %u, remove_size = %u\n",		  offset, remove_size));	if (remove_size == 0	    && f->range_tail	    && f->range_tail->data_offset + f->range_tail->data_size	       == offset) {		/* A simple append; nothing to remove or no node to split.  */		return;	}	/* Find the node where we should begin the removal.  */	for (n = f->range_head; n; n = n->range_next) {		if (n->data_offset + n->data_size > offset) {			break;		}	}	if (!n) {		/* If there's no data in the file there's no data to		   remove either.  */		return;	}	if (n->data_offset > offset) {		/* XXX: Not implemented yet.  */		printk(KERN_WARNING "JFFS: An unexpected situation "		       "occurred in jffs_delete_data.\n");	}	else if (n->data_offset < offset) {		/* See if the node has to be split into two parts.  */		if (n->data_offset + n->data_size < offset + remove_size) {			/* Do the split.  */			struct jffs_node *new_node;			D3(printk("jffs_delete_data(): Split node with "				  "version number %u.\n", n->version));			if (!(new_node = (struct jffs_node *)					 kmalloc(sizeof(struct jffs_node),						 GFP_KERNEL))) {				D(printk("jffs_delete_data(): -ENOMEM\n"));				return;			}			DJM(no_jffs_node++);			new_node->ino = n->ino;			new_node->version = n->version;			new_node->data_offset = offset;			new_node->data_size = n->data_size					      - (remove_size						 + (offset - n->data_offset));			new_node->fm_offset = n->fm_offset + n->data_size					      + remove_size;			new_node->name_size = n->name_size;			new_node->fm = n->fm;			new_node->version_prev = n;			new_node->version_next = n->version_next;			if (new_node->version_next) {				new_node->version_next->version_prev				= new_node;			}			else {				f->version_tail = new_node;			}			n->version_next = new_node;			new_node->range_prev = n;			new_node->range_next = n->range_next;			if (new_node->range_next) {				new_node->range_next->range_prev = new_node;			}			else {				f->range_tail = new_node;			}			/* A very interesting can of worms.  */			n->range_next = new_node;			n->data_size = offset - n->data_offset;			jffs_add_node(new_node);			n = new_node->range_next;			remove_size = 0;		}		else {			/* No.  No need to split the node.  Just remove			   the end of the node.  */			int r = jffs_min(n->data_offset + n->data_size					 - offset, remove_size);			n->data_size -= r;			remove_size -= r;			n = n->range_next;		}	}	/* Remove as many nodes as necessary.  */	while (n && remove_size) {		if (n->data_size <= remove_size) {			struct jffs_node *p = n;			remove_size -= n->data_size;			n = n->range_next;			D3(printk("jffs_delete_data(): Removing node: "				  "ino: %u, version: %u\n",				  p->ino, p->version));			if (p->fm) {				jffs_fmfree(f->c->fmc, p->fm, p);			}			jffs_unlink_node_from_range_list(f, p);			jffs_unlink_node_from_version_list(f, p);			kfree(p);			DJM(no_jffs_node--);		}		else {			n->data_size -= remove_size;			n->fm_offset += remove_size;			n->data_offset -= (node->removed_size - remove_size);			n = n->range_next;			break;		}	}	/* Adjust the following nodes' information about offsets etc.  */	while (n && node->removed_size) {		n->data_offset -= node->removed_size;		n = n->range_next;	}	f->size -= node->removed_size;	D3(printk("jffs_delete_data(): f->size = %d\n", f->size));} /* jffs_delete_data()  *//* Insert some data into a file.  Prior to the call to this function,   jffs_delete_data() should be called.  */static voidjffs_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.  */	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(KERN_ERR "jffs_insert_data(): "				       "Couldn't find a place to insert "				       "the data!\n");				return;			});		}		/* 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) {		/* Not implemented yet.  */#if 0		/* Below is some example code for future use if we decide		   to implement it.  */		/* This is code that isn't supported by VFS. So there aren't		   really any reasons to implement it yet.  */		if (!f->range_head) {			if (node->data_offset > f->size) {				if (!(nn = jffs_alloc_node())) {					D(printk("jffs_insert_data(): "						 "Allocation failed.\n"));					return;				}				nn->version = JFFS_MAGIC_BITMASK;				nn->data_offset = 0;				nn->data_size = node->data_offset;				nn->removed_size = 0;				nn->fm_offset = 0;				nn->name_size = 0;				nn->fm = 0; /* This is a virtual data holder.  */				nn->version_prev = 0;				nn->version_next = 0;				nn->range_prev = 0;				nn->range_next = 0;				nh->range_head = nn;				nh->range_tail = nn;			}		}#endif	}	D3(printk("jffs_insert_data(): f->size = %d\n", f->size));}/* A new node (with data) has been added to the file and now the range   list has to be modified.  */static intjffs_update_file(struct jffs_file *f, struct jffs_node *node){	D3(printk("jffs_update_file(): ino: %u, version: %u\n",		  f->ino, node->version));	if (node->data_size == 0) {		if (node->removed_size == 0) {			/* data_offset == X  */			/* data_size == 0  */			/* remove_size == 0  */		}		else {			/* data_offset == X  */			/* data_size == 0  */			/* remove_size != 0  */			jffs_delete_data(f, node);		}	}	else {		/* data_offset == X  */		/* data_size != 0  */		/* remove_size == Y  */		jffs_delete_data(f, node);		jffs_insert_data(f, node);	}	return 0;}/* Print the contents of a node.  */voidjffs_print_node(struct jffs_node *n){	D(printk("jffs_node: 0x%p\n", n));	D(printk("{\n"));	D(printk("        0x%08x, /* version  */\n", n->version));	D(printk("        0x%08x, /* data_offset  */\n", n->data_offset));	D(printk("        0x%08x, /* data_size  */\n", n->data_size));	D(printk("        0x%08x, /* removed_size  */\n", n->removed_size));	D(printk("        0x%08x, /* fm_offset  */\n", n->fm_offset));	D(printk("        0x%02x,       /* name_size  */\n", n->name_size));	D(printk("        0x%p, /* fm,  fm->offset: %u  */\n",		 n->fm, n->fm->offset));	D(printk("        0x%p, /* version_prev  */\n", n->version_prev));	D(printk("        0x%p, /* version_next  */\n", n->version_next));	D(printk("        0x%p, /* range_prev  */\n", n->range_prev));	D(printk("        0x%p, /* range_next  */\n", n->range_next));	D(printk("}\n"));}/* Print the contents of a raw inode.  */voidjffs_print_raw_inode(struct jffs_raw_inode *raw_inode){	D(printk("jffs_raw_inode: inode number: %u\n", raw_inode->ino));	D(printk("{\n"));	D(printk("        0x%08x, /* magic  */\n", raw_inode->magic));	D(printk("        0x%08x, /* ino  */\n", raw_inode->ino));	D(printk("        0x%08x, /* pino  */\n", raw_inode->pino));	D(printk("        0x%08x, /* version  */\n", raw_inode->version));	D(printk("        0x%08x, /* mode  */\n", raw_inode->mode));	D(printk("        0x%04x,     /* uid  */\n", raw_inode->uid));	D(printk("        0x%04x,     /* gid  */\n", raw_inode->gid));	D(printk("        0x%08x, /* atime  */\n", raw_inode->atime));	D(printk("        0x%08x, /* mtime  */\n", raw_inode->mtime));	D(printk("        0x%08x, /* ctime  */\n", raw_inode->ctime));	D(printk("        0x%08x, /* offset  */\n", raw_inode->offset));	D(printk("        0x%08x, /* dsize  */\n", raw_inode->dsize));	D(printk("        0x%08x, /* rsize  */\n", raw_inode->rsize));	D(printk("        0x%02x,       /* nsize  */\n", raw_inode->nsize));	D(printk("        0x%02x,       /* nlink  */\n", raw_inode->nlink));	D(printk("        0x%02x,       /* spare  */\n",		 raw_inode->spare));	D(printk("        %u,          /* rename  */\n",		 raw_inode->rename));	D(printk("        %u,          /* deleted  */\n",		 raw_inode->deleted));	D(printk("        0x%02x,       /* accurate  */\n",		 raw_inode->accurate));	D(printk("        0x%08x, /* dchksum  */\n", raw_inode->dchksum));	D(printk("        0x%04x,     /* nchksum  */\n", raw_inode->nchksum));	D(printk("        0x%04x,     /* chksum  */\n", raw_inode->chksum));	D(printk("}\n"));}/* Print the contents of a file.  */intjffs_print_file(struct jffs_file *f){	D(int i);	D(printk("jffs_file: 0x%p\n", f));	D(printk("{\n"));	D(printk("        0x%08x, /* ino  */\n", f->ino));	D(printk("        0x%08x, /* pino  */\n", f->pino));	D(printk("        0x%08x, /* mode  */\n", f->mode));	D(printk("        0x%04x,     /* uid  */\n", f->uid));	D(printk("        0x%04x,     /* gid  */\n", f->gid));	D(printk("        0x%08x, /* atime  */\n", f->atime));	D(printk("        0x%08x, /* mtime  */\n", f->mtime));	D(printk("        0x%08x, /* ctime  */\n", f->ctime));	D(printk("        0x%02x,       /* nsize  */\n", f->nsize));	D(printk("        0x%02x,       /* nlink  */\n", f->nlink));	D(printk("        0x%02x,       /* deleted  */\n", f->deleted));	D(printk("        \"%s\", ", (f->name ? f->name : "")));	D(for (i = strlen(f->name ? f->name : ""); i < 8; ++i) {		printk(" ");	});	D(printk("/* name  */\n"));	D(printk("        0x%08x, /* size  */\n", f->size));	D(printk("        0x%08x, /* highest_version  */\n",		 f->highest_version));	D(printk("        0x%p, /* c  */\n", f->c));	D(printk("        0x%p, /* parent  */\n", f->parent));	D(printk("        0x%p, /* children  */\n", f->children));	D(printk("        0x%p, /* sibling_prev  */\n", f->sibling_prev));	D(printk("        0x%p, /* sibling_next  */\n", f->sibling_next));	D(printk("        0x%p, /* hash_prev  */\n", f->hash_prev));	D(printk("        0x%p, /* hash_next  */\n", f->hash_next));	D(printk("        0x%p, /* range_head  */\n", f->range_head));	D(printk("        0x%p, /* range_tail  */\n", f->range_tail));	D(printk("        0x%p, /* version_head  */\n", f->version_head));	D(printk("    

⌨️ 快捷键说明

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