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

📄 intrep.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
		kfree(root);		DJM(no_jffs_file--);		return -ENOMEM;	}	DJM(no_jffs_node++);	memset(node, 0, sizeof(struct jffs_node));	node->ino = JFFS_MIN_INO;	memset(root, 0, sizeof(struct jffs_file));	root->ino = JFFS_MIN_INO;	root->mode = S_IFDIR | S_IRWXU | S_IRGRP		     | S_IXGRP | S_IROTH | S_IXOTH;	root->atime = root->mtime = root->ctime = CURRENT_TIME;	root->nlink = 1;	root->c = c;	root->version_head = root->version_tail = node;	jffs_insert_file_into_hash(root);	return 0;}/* This is where the file system is built and initialized.  */intjffs_build_fs(struct super_block *sb){	struct jffs_control *c;	int err = 0;	D2(printk("jffs_build_fs()\n"));	if (!(c = jffs_create_control(sb->s_dev))) {		return -ENOMEM;	}	c->building_fs = 1;	c->sb = sb;	if ((err = jffs_scan_flash(c)) < 0) {		goto jffs_build_fs_fail;	}	/* Add a virtual root node if no one exists.  */	if (!jffs_find_file(c, JFFS_MIN_INO)) {		if ((err = jffs_add_virtual_root(c)) < 0) {			goto jffs_build_fs_fail;		}	}	while (c->delete_list) {		struct jffs_file *f;		struct jffs_delete_list *delete_list_element;		if ((f = jffs_find_file(c, c->delete_list->ino))) {			f->deleted = 1;		}		delete_list_element = c->delete_list;		c->delete_list = c->delete_list->next;		kfree(delete_list_element);	}	/* Remove deleted nodes.  */	if ((err = jffs_foreach_file(c, jffs_possibly_delete_file)) < 0) {		printk(KERN_ERR "JFFS: Failed to remove deleted nodes.\n");		goto jffs_build_fs_fail;	}	/* Remove redundant nodes.  (We are not interested in the	   return value in this case.)  */	jffs_foreach_file(c, jffs_remove_redundant_nodes);	/* Try to build a tree from all the nodes.  */	if ((err = jffs_foreach_file(c, jffs_insert_file_into_tree)) < 0) {		printk("JFFS: Failed to build tree.\n");		goto jffs_build_fs_fail;	}	/* Compute the sizes of all files in the filesystem.  Adjust if	   necessary.  */	if ((err = jffs_foreach_file(c, jffs_build_file)) < 0) {		printk("JFFS: Failed to build file system.\n");		goto jffs_build_fs_fail;	}	sb->u.generic_sbp = (void *)c;	c->building_fs = 0;	D1(jffs_print_hash_table(c));	D1(jffs_print_tree(c->root, 0));	return 0;jffs_build_fs_fail:	jffs_cleanup_control(c);	return err;} /* jffs_build_fs()  *//* Scan the whole flash memory in order to find all nodes in the   file systems.  */static intjffs_scan_flash(struct jffs_control *c){	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;	loff_t pos = fmc->flash_start;	loff_t start;	loff_t end = fmc->flash_start + fmc->flash_size;	__u8 *read_buf;	int i, len, retlen;	D1(printk("jffs_scan_flash(): start pos = 0x%lx, end = 0x%lx\n",		  (long)pos, (long)end));	flash_safe_acquire(fmc->mtd);	/* Allocate read buffer */	read_buf = (__u8 *) kmalloc (sizeof(__u8) * 4096, GFP_KERNEL);	/* Start the scan.  */	while (pos < end) {		deleted_file = 0;		/* Remember the position from where we started this scan.  */		start = pos;		switch (flash_read_u32(fmc->mtd, 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%lx.\n",				  (long)pos));			len = end - pos < 4096 ? end - pos : 4096;			retlen = flash_safe_read(fmc->mtd, pos,						 &read_buf[0], len);			retlen &= ~3;			for (i=0 ; i < retlen ; i+=4, pos += 4) {				if(*((__u32 *) &read_buf[i]) !=						JFFS_EMPTY_BITMASK)					break;			}			if (i == retlen)				continue;			D1(printk("jffs_scan_flash(): 0xff ended at "				  "pos 0x%lx.\n", (long)pos));			/* If some free space ends in the middle of a sector,				treat it as dirty rather than clean.			   This is to handle the case where one thread 			   allocated space for a node, but didn't get to			   actually _write_ it before power was lost, leaving			   a gap in the log. Shifting all node writes into			   a single kernel thread will fix the original problem.			*/			if ((__u32) pos % fmc->sector_size) {				/* If there was free space in previous 				   sectors, don't mark that dirty too - 				   only from the beginning of this sector				   (or from start) 				*/				if (start < (pos & ~(fmc->sector_size-1))) {					D1(printk("Reducing start to 0x%x from 0x%x\n", pos & ~(fmc->sector_size-1), start));					start = pos & ~(fmc->sector_size-1);				}				D1(printk("Dirty space: 0x%x for 0x%x bytes\n", start, (pos - start)));				jffs_fmalloced(fmc, (__u32) start,					       (__u32) (pos - start), 0);			}			continue;		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%lx.\n",				  (long)pos));			for (; pos < end			       && JFFS_DIRTY_BITMASK == flash_read_u32(fmc->mtd, pos);			     pos += 4);			D1(printk("jffs_scan_flash(): 0x00 ended at "				  "pos 0x%lx.\n", (long)pos));			jffs_fmalloced(fmc, (__u32) start,				       (__u32) (pos - start), 0);			continue;		case JFFS_MAGIC_BITMASK:			/* We have probably found a new raw inode.  */			break;		default:		bad_inode:			/* 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%lx, len = 128):\n",				  (long)pos));			D1(jffs_hexdump(fmc->mtd, pos, 128));		cont_dirty:			for (pos += 4; pos < end; pos += 4) {				switch (flash_read_u32(fmc->mtd, pos)) {				case JFFS_MAGIC_BITMASK:					jffs_fmalloced(fmc, (__u32) start,						       (__u32) (pos - start),						       0);					goto cont_scan;				case JFFS_EMPTY_BITMASK:					/* First, mark as dirty the region					   which really does contain crap. */					jffs_fmalloced(fmc, (__u32) start,						       (__u32) (pos - start),						       0);					/* Then, scan the region which looks free.					   Depending on how large it is, we may					   mark it dirty too.					*/					start = pos;					for (; pos < end ; pos += 4) {						switch (flash_read_u32(fmc->mtd, pos)) {						case JFFS_MAGIC_BITMASK:							if (pos - start < fmc->max_chunk_size) {								/* Not much free space. Mark it dirty. */								jffs_fmalloced(fmc, (__u32)start,									       (__u32)pos-start, 0);							}							goto cont_scan;						case JFFS_EMPTY_BITMASK:							/* More empty space */							continue;										default: 							/* i.e. more dirt */							if (pos - start < fmc->max_chunk_size) {								/* There wasn't much before the dirt								   started again. Just mark it all dirty								*/								goto cont_dirty;							}							/* There was quite a lot of free space. Leave it							   free.							*/							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 *)				     kmalloc(sizeof(struct jffs_node),					     GFP_KERNEL))) {				/* Free read buffer */				kfree (read_buf);				/* Release the flash device */				flash_safe_release(fmc->mtd);					return -ENOMEM;			}			DJM(no_jffs_node++);		}		/* Read the next raw inode.  */		flash_safe_read(fmc->mtd, pos, (u_char *) &raw_inode,				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%lx "			  "on the flash:\n", (long)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 this unused struct jffs_node.  */			continue;		}		/* Check the raw inode read so far.  Start with the		   maximum length of the filename.  */		if (raw_inode.nsize > JFFS_MAX_NAME_LEN) {			printk(KERN_WARNING "jffs_scan_flash: Found a "			       "JFFS node with name too large\n");			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) {			printk(KERN_WARNING "jffs_scan_flash: Found a "			       "JFFS node with dsize (0x%x) > max_chunk_size (0x%x)\n",			       raw_inode.dsize, fmc->max_chunk_size);			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) {		        flash_safe_read(fmc->mtd, pos, name, 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,					       (__u32) (pos - start), 0);				/* Reuse this unused struct jffs_node.  */				continue;			}			if (pos >= end) {				goto check_node;			}		}		/* Read the data, if it exists, in order to be sure it		   matches the checksum.  */		if (raw_inode.dsize) {			if (raw_inode.rename) {				deleted_file = flash_read_u32(fmc->mtd, pos);			}			checksum = jffs_checksum_flash(fmc->mtd, pos, raw_inode.dsize);			pos += raw_inode.dsize			       + JFFS_GET_PAD_BYTES(raw_inode.dsize);			if (checksum != raw_inode.dchksum) {				D1(printk("jffs_scan_flash(): Bad checksum: "					  "checksum = %u, "					  "raw_inode.dchksum = %u\n",					  checksum, raw_inode.dchksum));				jffs_fmalloced(fmc, (__u32) start,					       (__u32) (pos - start), 0);				/* Reuse this unused struct jffs_node.  */				continue;			}		}		check_node:		/* Remember the highest inode number in the whole file		   system.  This information will be used when assigning		   new files new inode numbers.  */		if (c->next_ino <= raw_inode.ino) {			c->next_ino = raw_inode.ino + 1;		}		if (raw_inode.accurate) {			int err;			node->data_offset = raw_inode.offset;			node->data_size = raw_inode.dsize;			node->removed_size = raw_inode.rsize;			/* Compute the offset to the actual data in the			   on-flash node.  */			node->fm_offset			= sizeof(struct jffs_raw_inode)			  + raw_inode.nsize			  + JFFS_GET_PAD_BYTES(raw_inode.nsize);			node->fm = jffs_fmalloced(fmc, (__u32) start,						  (__u32) (pos - start),						  node);			if (!node->fm) {				D(printk("jffs_scan_flash(): !node->fm\n"));				kfree(node);				DJM(no_jffs_node--);				/* Free read buffer */				kfree (read_buf);				/* Release the flash device */				flash_safe_release(fmc->mtd);				return -ENOMEM;			}			if ((err = jffs_insert_node(c, 0, &raw_inode,						    name, node)) < 0) {				printk("JFFS: Failed to handle raw inode. "				       "(err = %d)\n", err);				break;			}			if (raw_inode.rename) {				struct jffs_delete_list *dl				= (struct jffs_delete_list *)				  kmalloc(sizeof(struct jffs_delete_list),					  GFP_KERNEL);				if (!dl) {					D(printk("jffs_scan_flash: !dl\n"));					kfree(node);					DJM(no_jffs_node--);					/* Release the flash device */					flash_safe_release(fmc->flash_part);					/* Free read buffer */					kfree (read_buf);					return -ENOMEM;				}				dl->ino = deleted_file;				dl->next = c->delete_list;				c->delete_list = dl;				node->data_size = 0;			}			D3(jffs_print_node(node));			node = 0; /* Don't free the node!  */		}		else {			jffs_fmalloced(fmc, (__u32) start,				       (__u32) (pos - start), 0);			D3(printk("jffs_scan_flash(): Just found an obsolete "				  "raw_inode. Continuing the scan...\n"));			/* Reuse this unused struct jffs_node.  */		}	}	if (node) {		kfree(node);		DJM(no_jffs_node--);	}	jffs_build_end(fmc);	/* Free read buffer */	kfree (read_buf);	/* Return happy */	D3(printk("jffs_scan_flash(): Leaving...\n"));	flash_safe_release(fmc->mtd);	return 0;} /* jffs_scan_flash()  *//* Insert any kind of node into the file system.  Take care of data   insertions and deletions.  Also remove redundant information. The   memory allocated for the `name' is regarded as "given away" in the   caller's perspective.  */intjffs_insert_node(struct jffs_control *c, struct jffs_file *f,		 const struct jffs_raw_inode *raw_inode,		 const char *name, struct jffs_node *node){	int update_name = 0;	int insert_into_tree = 0;	D2(printk("jffs_insert_node(): ino = %u, version = %u, "

⌨️ 快捷键说明

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