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

📄 intrep.c

📁 elinux jffs初始版本 具体了解JFFS的文件系统!
💻 C
📖 第 1 页 / 共 5 页
字号:
				flash_safe_release(fmc->flash_part);				return -ENOMEM;			}			DJM(no_jffs_node++);		}		/* Read the next raw inode.  */		memcpy(&raw_inode, pos, 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%p "			  "on the flash:\n", 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) {			goto bad_inode;		}		/* The node's data segment should not exceed a		   certain length.  */		if (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) {			memcpy(name, pos, 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 in order to be sure it matches the		   checksum.  */		checksum = jffs_checksum(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--);				flash_safe_release(fmc->flash_part);				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;			}			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);	D3(printk("jffs_scan_flash(): Leaving...\n"));	flash_safe_release(fmc->flash_part);	return 0;} /* jffs_scan_flash()  */#else/* Scan the whole flash memory in order to find all nodes in the   file systems.  */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 buffer_head *bh;	kdev_t dev = c->sb->s_dev;	__u32 block = 0;	__u32 last_block = c->fmc->flash_size / BLOCK_SIZE - 1;	__u32 block_offset = 0;	__u32 read_size;	__u32 checksum;	__u32 offset; /* Offset relative to the start of the flash memory.  */	__u8 tmp_accurate;	__u32 tmp_chksum;	__u32 size;	D(printk("jffs_scan_flash()\n"));	if (!(bh = bread(dev, block, BLOCK_SIZE))) {		D(printk("jffs_scan_flash(): First bread() failed.\n"));		return -1;	}	/* Start the scan.  */	while (block <= last_block) {		if (block_offset >= BLOCK_SIZE) {			brelse(bh);			if (block == last_block) {				bh = 0;				goto end_of_scan;			}			if (!(bh = bread(dev, ++block, BLOCK_SIZE))) {				return -1;			}			block_offset = 0;		}		offset = block * BLOCK_SIZE + block_offset;		D(printk("jffs_scan_flash(): offset = %u\n", offset));		switch (*(__u32 *)&bh->b_data[block_offset]) {		case JFFS_EMPTY_BITMASK:			/* We have found 0xff on this block.  We have to			   scan the rest of the block to be sure it is			   filled with 0xff.  */			D(printk("jffs_scan_flash(): 0xff on block %u, "				 "block_offset %u.\n", block, block_offset));			block_offset += 4;			while (block <= last_block) {				for (; block_offset < BLOCK_SIZE;				     block_offset += 4) {					if (JFFS_EMPTY_BITMASK					    != *(__u32 *)&bh->b_data[block_offset]) {						goto ff_scan_end;					}				}				brelse(bh);				block_offset = 0;				if (block >= last_block) {					bh = 0;					D(printk("jffs_scan_flash(): "						 "0xff size: %d\n",						 (last_block + 1) * BLOCK_SIZE						 - offset));					goto end_of_scan;				}				if (!(bh = bread(dev, ++block, BLOCK_SIZE))) {					return -1;				}			}		ff_scan_end:			D(printk("jffs_scan_flash(): 0xff size: %d\n",				 block * BLOCK_SIZE + block_offset - offset));			continue;		case JFFS_DIRTY_BITMASK:			/* We have found 0x00 on this block.  We have to			   scan as far as possible to find out how much			   is dirty.  */			D(printk("jffs_scan_flash(): 0x00 on block %u, "				 "block_offset %u.\n",				 block, block_offset));			block_offset += 4;			while (block < last_block) {				for (; block_offset < BLOCK_SIZE;				     block_offset += 4) {					if (*(__u32 *)&bh->b_data[block_offset]					    != JFFS_DIRTY_BITMASK) {						goto zero_scan_end;					}				}				brelse(bh);				if (!(bh = bread(dev, ++block, BLOCK_SIZE))) {					return -1;				}				block_offset = 0;			}		zero_scan_end:			D(printk("jffs_scan_flash(): 0x00 size: %d\n",				 block * BLOCK_SIZE + block_offset - offset));			jffs_fmalloced(c->fmc, offset,				       block * BLOCK_SIZE + block_offset				       - offset, 0);			continue;		case JFFS_MAGIC_BITMASK:			/* We have probably found a new raw inode.  */			break;		default:			/* We're f*cked.  This is not solved yet.  We have			   to scan for the magic pattern.  */			D(printk("jffs_scan_flash(): Block #%u at "				 "block_offset %u is dirty!\n",				 block, block_offset));			D(printk("  offset: %u\n", offset));			D(printk("  data: %u\n",				 *(__u32 *)&bh->b_data[block_offset]));			jffs_fmalloced(c->fmc, offset,				       BLOCK_SIZE - block_offset, 0);			block_offset = BLOCK_SIZE;			continue;		}		/* We have found the beginning of an inode.  Create a		   node for it.  */		if (!node) {			if (!(node = (struct jffs_node *)				     kmalloc(sizeof(struct jffs_node),					     GFP_KERNEL))) {				brelse(bh);				return -ENOMEM;			}			DJM(no_jffs_node++);		}		/* Read the next raw inode.  */		read_size = jffs_min(BLOCK_SIZE - block_offset,				     sizeof(struct jffs_raw_inode));		memcpy(&raw_inode, &bh->b_data[block_offset], read_size);		D(printk("jffs_scan_flash(): block_offset: %u, "			 "read_size: %u\n", block_offset, read_size));		block_offset += read_size;		if (read_size < sizeof(struct jffs_raw_inode)) {			brelse(bh);			if (!(bh = bread(dev, ++block, BLOCK_SIZE))) {				return -1;			}			block_offset = sizeof(struct jffs_raw_inode) - read_size;			memcpy((void *)&raw_inode + read_size, bh->b_data,			       block_offset);		}		/* 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;		D(printk("*** We have found this raw inode at pos 0x%08x "			 "on the flash:\n", offset));		jffs_print_raw_inode(&raw_inode);		if (block_offset == BLOCK_SIZE) {			brelse(bh);			if (block == last_block) {				bh = 0;				goto check_node;			}			if (!(bh = bread(dev, ++block, BLOCK_SIZE))) {				return -1;			}			block_offset = 0;		}		/* Read the name.  */		*name = 0;		if (raw_inode.nsize) {			read_size = jffs_min(BLOCK_SIZE - block_offset,					     raw_inode.nsize);			memcpy(name, &bh->b_data[block_offset], read_size);			block_offset += read_size;			if (read_size < raw_inode.nsize) {				/* We haven't read the whole name.  */				brelse(bh);				if (!(bh = bread(dev, ++block, BLOCK_SIZE))) {					return -1;				}				block_offset = raw_inode.nsize - read_size;				memcpy(&name[read_size], bh->b_data, block_offset);			}			block_offset += JFFS_GET_PAD_BYTES(block_offset);			name[raw_inode.nsize] = '\0';			checksum += jffs_checksum(name, raw_inode.nsize);		}		if (block_offset == BLOCK_SIZE) {			brelse(bh);			if (block == last_block) {				bh = 0;				goto check_node;			}			if (!(bh = bread(dev, ++block, BLOCK_SIZE))) {				return -1;			}			block_offset = 0;		}		/* Read the data in order to be sure it matches the		   checksum.  */		if (raw_inode.dsize) {			__u32 chunk_size = jffs_min(BLOCK_SIZE - block_offset,						    raw_inode.dsize);			__u32 data_read = chunk_size;			checksum += jffs_checksum(&bh->b_data[block_offset],						  data_read);			block_offset += chunk_size;			while (data_read < raw_inode.dsize) {				brelse(bh);				if (!(bh = bread(dev, ++block, BLOCK_SIZE))) {					return -1;				}				chunk_size = jffs_min(BLOCK_SIZE,						      raw_inode.dsize						      - data_read);				data_read += chunk_size;				checksum += jffs_checksum(bh->b_data,							  chunk_size);				block_offset = chunk_size;			}		}		size = sizeof(struct jffs_raw_inode) + raw_inode.nsize		       + raw_inode.dsize;		block_offset += JFFS_GET_PAD_BYTES(block_offset);		/* Make sure the checksums are equal.  */		if (checksum != raw_inode.chksum) {			/* Something was wrong with the node.  The node			   has to be discarded.  */			D(printk("jffs_scan_flash(): checksum == %u, "				 "raw_inode.chksum == %u\n",				 checksum, raw_inode.chksum));			jffs_fmalloced(c->fmc, offset, size, 0);			/* Reuse this unused struct jffs_node.  */			continue;		}		/* 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;		}		check_node:		if (raw_inode.accurate) {			node->data_offset = raw_inode.offset;			node->data_size = raw_inode.dsize;			node->removed_size = raw_inode.rsize;			node->fm_offset = sizeof(struct jffs_raw_inode)					  + raw_inode.nsize					  + JFFS_GET_PAD_BYTES(raw_inode.nsize);			node->fm = jffs_fmalloced(c->fmc, offset, size, node);			if (!node->fm) {				D(printk("jffs_scan_flash(): !node->fm\n"));				kfree(node);				DJM(no_jffs_node--);				brelse(bh);				return -ENOMEM;			}			jffs_insert_node(c, 0, &raw_inode, name, node);			jffs_print_node(node);			node = 0; /* Don't free the node!  */		}		else {			jffs_fmalloced(c->fmc, offset, size, 0);			D(printk("jffs_scan_flash(): Just found an obsolete "				 "raw_inode. Continuing the scan...\n"));			/* Reuse this unused struct jffs_node.  */		}	}	end_of_scan:	brelse(bh);	if (node) {		kfree(node);		DJM(no_jffs_node--);	}	jffs_build_end(c->fmc);	D(printk("jffs_scan_flash(): Leaving...\n"));	return 0;} /* jffs_scan_flash()  */#endif/* 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\"\n",		  raw_inode->ino, raw_inode->version,		  ((name && *name) ? name : "")));	/* 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;	}

⌨️ 快捷键说明

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