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

📄 intrep.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
		 * collection.		 *		 * If this is the case, don't let f->size go negative.		 * Bad things would happen :)		 */		f->size = node->data_offset;	} else {		f->size -= node->removed_size;	}	D3(printk("jffs_delete_data(): f->size = %d\n", f->size));	return 0;} /* jffs_delete_data()  *//* Insert some data into a file.  Prior to the call to this function,   jffs_delete_data should be called.  */static intjffs_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) {			D2(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 -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) {		/* Okay.  This is tricky.  This means that we want to insert		   data at a place that is beyond the limits of the file as		   it is constructed right now.  This is actually a common		   event that for instance could occur during the mounting		   of the file system if a large file have been truncated,		   rewritten and then only partially garbage collected.  */		struct jffs_node *n;		/* We need a place holder for the data that is missing in		   front of this insertion.  This "virtual node" will not		   be associated with any space on the flash device.  */		struct jffs_node *virtual_node;		if (!(virtual_node = (struct jffs_node *)				     kmalloc(sizeof(struct jffs_node),					     GFP_KERNEL))) {			return -ENOMEM;		}		D(printk("jffs_insert_data: Inserting a virtual node.\n"));		D(printk("  node->data_offset = %u\n", node->data_offset));		D(printk("  f->size = %u\n", f->size));		virtual_node->ino = node->ino;		virtual_node->version = node->version;		virtual_node->removed_size = 0;		virtual_node->fm_offset = 0;		virtual_node->name_size = 0;		virtual_node->fm = 0; /* This is a virtual data holder.  */		virtual_node->version_prev = 0;		virtual_node->version_next = 0;		virtual_node->range_next = 0;		/* Are there any data at all in the file yet?  */		if (f->range_head) {			virtual_node->data_offset			= f->range_tail->data_offset			  + f->range_tail->data_size;			virtual_node->data_size			= node->data_offset - virtual_node->data_offset;			virtual_node->range_prev = f->range_tail;			f->range_tail->range_next = virtual_node;		}		else {			virtual_node->data_offset = 0;			virtual_node->data_size = node->data_offset;			virtual_node->range_prev = 0;			f->range_head = virtual_node;		}		f->range_tail = virtual_node;		f->size += virtual_node->data_size;		/* Insert this virtual node in the version list as well.  */		for (n = f->version_head; n ; n = n->version_next) {			if (n->version == virtual_node->version) {				virtual_node->version_prev = n->version_prev;				n->version_prev = virtual_node;				if (virtual_node->version_prev) {					virtual_node->version_prev					->version_next = virtual_node;				}				else {					f->version_head = virtual_node;				}				virtual_node->version_next = n;				break;			}		}		D(jffs_print_node(virtual_node));		/* Make a new try to insert the node.  */		goto retry;	}	D3(printk("jffs_insert_data(): f->size = %d\n", f->size));	return 0;}/* 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){	int err;	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  */			if ((err = jffs_delete_data(f, node)) < 0) {				return err;			}		}	}	else {		/* data_offset == X  */		/* data_size != 0  */		/* remove_size == Y  */		if ((err = jffs_delete_data(f, node)) < 0) {			return err;		}		if ((err = jffs_insert_data(f, node)) < 0) {			return err;		}	}	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 ? n->fm->offset : 0)));	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("        0x%p, /* version_tail  */\n", f->version_tail));	D(printk("}\n"));	return 0;}voidjffs_print_hash_table(struct jffs_control *c){	int i;	printk("JFFS: Dumping the file system's hash table...\n");	for (i = 0; i < c->hash_len; i++) {		struct list_head *p;		for (p = c->hash[i].next; p != &c->hash[i]; p = p->next) {			struct jffs_file *f=list_entry(p,struct jffs_file,hash);			printk("*** c->hash[%u]: \"%s\" "			       "(ino: %u, pino: %u)\n",			       i, (f->name ? f->name : ""),			       f->ino, f->pino);		}	}}voidjffs_print_tree(struct jffs_file *first_file, int indent){	struct jffs_file *f;	char *space;	int dir;	if (!first_file) {		return;	}	if (!(space = (char *) kmalloc(indent + 1, GFP_KERNEL))) {		printk("jffs_print_tree(): Out of memory!\n");		return;	}	memset(space, ' ', indent);	space[indent] = '\0';	for (f = first_file; f; f = f->sibling_next) {		dir = S_ISDIR(f->mode);		printk("%s%s%s (ino: %u, highest_version: %u, size: %u)\n",		       space, (f->name ? f->name : ""), (dir ? "/" : ""),		       f->ino, f->highest_version, f->size);		if (dir) {			jffs_print_tree(f->children, indent + 2);		}	}	kfree(space);}#if defined(JFFS_MEMORY_DEBUG) && JFFS_MEMORY_DEBUGvoidjffs_print_memory_allocation_statistics(void){	static long printout = 0;	printk("________ Memory printout #%ld ________\n", ++printout);	printk("no_jffs_file = %ld\n", no_jffs_file);	printk("no_jffs_node = %ld\n", no_jffs_node);	printk("no_jffs_control = %ld\n", no_jffs_control);	printk("no_jffs_raw_inode = %ld\n", no_jffs_raw_inode);	printk("no_jffs_node_ref = %ld\n", no_jffs_node_ref);	printk("no_jffs_fm = %ld\n", no_jffs_fm);	printk("no_jffs_fmcontrol = %ld\n", no_jffs_fmcontrol);	printk("no_hash = %ld\n", no_hash);	printk("no_name = %ld\n", no_name);	printk("\n");}#endif/* Rewrite `size' bytes, and begin at `node'.  */intjffs_rewrite_data(struct jffs_file *f, struct jffs_node *node, int size){	struct jffs_control *c = f->c;	struct jffs_fmcontrol *fmc = c->fmc;	struct jffs_raw_inode raw_inode;	struct jffs_node *new_node;	struct jffs_fm *fm;	__u32 pos;	__u32 pos_dchksum;	__u32 total_name_size;	__u32 total_data_size;	__u32 total_size;	int err;	D1(printk("***jffs_rewrite_data(): node: %u, name: \"%s\", size: %u\n",		  f->ino, (f->name ? f->name : "(null)"), size));	/* Create and initialize the new node.  */	if (!(new_node = (struct jffs_node *)			 kmalloc(sizeof(struct jffs_node), GFP_KERNEL))) {		D(printk("jffs_rewrite_data(): "			 "Failed to allocate node.\n"));		return -ENOMEM;	}	DJM(no_jffs_node++);	new_node->data_offset = node->data_offset;	new_node->removed_size = size;	total_name_size = JFFS_PAD(f->nsize);	total_data_size = JFFS_PAD(size);	total_size = sizeof(struct jffs_raw_inode)		     + total_name_size + total_data_size;	new_node->fm_offset = sizeof(struct jffs_raw_inode)			      + total_name_size;	jffs_fm_write_lock(fmc);	if ((err = jffs_fmalloc(fmc, total_size, new_node, &fm)) < 0) {		DJM(no_jffs_node--);		jffs_fm_write_unlock(fmc);		D(printk("jffs_rewrite_data(): Failed to allocate fm.\n"));		kfree(new_node);		return err;	}	else if (!fm->nodes) {		/* The jffs_fm struct that we got is not big enough.  */		/* This should never happen, because we deal with this case		   in jffs_garbage_collect_next().*/		printk(KERN_WARNING "jffs_rewrite_data(): Allocated node is too small (%d bytes of %d)\n", fm->size, total_size);		if ((err = jffs_write_dummy_node(c, fm)) < 0) {			D(printk("jffs_rewrite_data(): "				 "jffs_write_dummy_node() Failed!\n"));		} else {			err = -ENOSPC;		}		DJM(no_jffs_fm--);		jffs_fm_write_unlock(fmc);		kfree(fm);				return err;	}	new_node->fm = fm;	/* Initialize the raw inode.  */	raw_inode.magic = JFFS_MAGIC_BITMASK;	raw_inode.ino = f->ino;	raw_inode.pino = f->pino;	raw_inode.version = f->highest_version + 1;	raw_inode.mode = f->mode;	raw_inode.uid = f->uid;	raw_inode.gid = f->gid;	raw_inode.atime = f->atime;	raw_inode.mtime = f->mtime;	raw_inode.ctime = f->ctime;	raw_inode.offset = node->data_offset;	raw_inode.dsize = size;	raw_inode.rsize = size;	raw_inode.nsize = f->nsize;	raw_inode.nlink = f->nlink;	raw_inode.spare = 0;	raw_inode.rename = 0;	raw_inode.deleted = 0;	raw_inode.accurate = 0xff;	raw_inode.dchksum = 0;	raw_inode.nchksum = 0;	pos = new_node->fm->offset;	pos_dchksum = pos +JFFS_RAW_INODE_DCHKSUM_OFFSET;	D3(printk("jffs_rewrite_data(): Writing this raw inode "		  "to pos 0x%ul.\n", pos));	D3(jffs_print_raw_inode(&raw_inode));	if ((err = flash_safe_write(fmc->mtd, pos,				    (u_char *) &raw_inode,				    sizeof(struct jffs_raw_inode)				    - sizeof(__u32)				    - sizeof(__u16) - sizeof(__u16))) < 0) {		jffs_fmfree_partly(fmc, fm,				   total_name_size + total_data_size);		jffs_fm_write_unlock(fmc);		printk(KERN_ERR "JFFS: jffs_rewrite_data: Write error during "		       "rewrite. (raw inode)\n");		return err;	}	pos += sizeof(struct jffs_raw_inode);	/* Write the name to the flash memory.  */	if (f->nsize) {		D3(printk("jffs_rewrite_data(): Writing name \"%s\" to "			  "pos 0x%ul.\n", f->name, (long)pos));		if ((err = flash_safe_write(fmc->mtd, pos,					    (u_char *)f->name,					    f->nsize)) < 0) {			jffs_fmfree_partly(fmc, fm, total_data_size);

⌨️ 快捷键说明

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