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

📄 intrep.c

📁 mtd最新cvs jffs文件系统分析
💻 C
📖 第 1 页 / 共 5 页
字号:
					    */ 				           num_free_space++;				           D1(printk("Free space accepted: Starting 0x%x for 0x%x bytes\n",						     (unsigned int) start, (unsigned int) (pos - start)));					   if (largest_hole < pos - start) {						   						   D3(printk("was hole = %x end_offset = %x\n",						          largest_hole, hole_end_offset));						   if (fmc->head){							   largest_hole    = pos - start;							   hole_end_offset = pos;							}						   D3(printk("now = %x end_offset = %x\n",						          largest_hole, hole_end_offset));						}				 }else{				         num_free_spc_not_accp++;					 D1(printk("Free space (#%i) found but *Not* accepted: Starting "						   "0x%x for 0x%x bytes\n", num_free_spc_not_accp, 						   (unsigned int) start, 						   (unsigned int) (pos - start)));					 					 /* Mark this space as dirty. We already have our free space. */					 D1(printk("Dirty space: Starting 0x%x for 0x%x bytes\n",						   (unsigned int) start, (unsigned int) (pos - start)));					 jffs_fmalloced(fmc, (__u32) start,							(__u32) (pos - start), 0);				           				}				 			}			if(num_free_space > NUMFREEALLOWED){			         printk(KERN_WARNING "jffs_scan_flash(): Found free space "					"number %i. Only %i free space is allowed.\n",					num_free_space, NUMFREEALLOWED);			      			}			continue;		case JFFS_DIRTY_BITMASK:			/* We have found 0x00000000 at this position.  Scan as far			   as possible to find out how much is dirty.  */			D1(printk("jffs_scan_flash(): 0x00000000 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 = %d):\n",				  (long)pos,				  end - pos > 128 ? 128 : end - pos));			D1(jffs_hexdump(fmc->mtd, pos,			                end - pos > 128 ? 128 : end - pos));			for (pos += 4; pos < end; pos += 4) {				switch (flash_read_u32(fmc->mtd, pos)) {				case JFFS_MAGIC_BITMASK:				case JFFS_EMPTY_BITMASK:					/* handle these in the main switch() loop */					goto cont_scan;				default:					break;				}			}			cont_scan:			/* First, mark as dirty the region			   which really does contain crap. */			jffs_fmalloced(fmc, (__u32) start,				       (__u32) (pos - start),				       0);						continue;		}/* switch */		/* We have found the beginning of an inode.  Create a		   node for it unless there already is one available.  */		if (!node) {			if (!(node = jffs_alloc_node())) {				/* 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);			}			if (jffs_checksum_flash(fmc->mtd, pos, raw_inode.dsize, &checksum)) {				printk("jffs_checksum_flash() failed to calculate a checksum\n");				jffs_fmalloced(fmc, (__u32) start,					       (__u32) (pos - start), 0);				/* Reuse this unused struct jffs_node.  */				continue;			}							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"));				jffs_free_node(node);				DJM(no_jffs_node--);				/* Free read buffer */				kfree (read_buf);				/* Release the flash device */				flash_safe_release(fmc->mtd);				return -ENOMEM;			}			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"));					jffs_free_node(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;			}			if ((err = jffs_insert_node(c, 0, &raw_inode,						    name, node)) < 0) {				printk("JFFS: Failed to handle raw inode. "				       "(err = %d)\n", err);				break;			}			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) {		jffs_free_node(node);		DJM(no_jffs_node--);	}	if (fmc->head && fmc->tail_extra &&	    fmc->head->offset + fmc->flash_size -			fmc->tail_extra->offset - fmc->tail_extra->size > largest_hole) {		head_offset = fmc->head->offset;	}	else {		head_offset = hole_end_offset;	}		if (jffs_build_end(fmc, head_offset) < 0) {		D(printk("jffs_build_end() failed\n"));		return -ENOMEM;	}	/* Free read buffer */	kfree (read_buf);	if(!num_free_space){	        printk(KERN_WARNING "jffs_scan_flash(): Did not find even a single "		       "chunk of free space. This is BAD!\n");	}	/* Return happy */	D3(printk("jffs_scan_flash(): Leaving...\n"));	flash_safe_release(fmc->mtd);	/* This is to trap the "free size accounting screwed error. */	free_chunk_size1 = jffs_free_size1(fmc);	free_chunk_size2 = jffs_free_size2(fmc);	if (free_chunk_size1 + free_chunk_size2 != fmc->free_size) {		printk(KERN_WARNING "jffs_scan_falsh():Free size accounting screwed\n");		printk(KERN_WARNING "jfffs_scan_flash():free_chunk_size1 == 0x%x, "		       "free_chunk_size2 == 0x%x, fmc->free_size == 0x%x\n", 		       free_chunk_size1, free_chunk_size2, fmc->free_size);		return -1; /* Do NOT mount f/s so that we can inspect what happened.			      Mounting this  screwed up f/s will screw us up anyway.			    */	}		return 0; /* as far as we are concerned, we are happy! */} /* 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, "		  "name = \"%s\", deleted = %d\n",		  raw_inode->ino, raw_inode->version,		  ((name && *name) ? name : ""), raw_inode->deleted));	/* If there doesn't exist an associated jffs_file, then	   create, initialize and insert one into the file system.  */	if (!f && !(f = jffs_find_file(c, raw_inode->ino))) {		if (!(f = jffs_create_file(c, raw_inode))) {			return -ENOMEM;		}		jffs_insert_file_into_hash(f);		insert_into_tree = 1;	}	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;	}	else if ((f->highest_version < node->version)		 || (node->version == 0)) {		/* Insert at the end of the list.  I.e. this node is the		   newest 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;	}	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;		}	}	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;			}		}	}	/* Deletion is irreversible. If any 'deleted' node is ever	   written, the file is deleted */	if (raw_inode->deleted)		f->deleted = raw_inode->deleted;	/* Perhaps update the name.  */	if (raw_inode->nsize && update_name && name && *name && (name != f->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);		}		/* Once upon a time, we would call jffs_possibly_delete_file()		   here. That causes an oops if someone's still got the file		   open, so now we only do it in jffs_delete_inode()		   -- dwmw2		*/		if (node->data_size || node->removed_size) {			jffs_update_file(f, node);

⌨️ 快捷键说明

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