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

📄 jffs2_nand_1pass.c

📁 OMAP2530 uboot source code
💻 C
📖 第 1 页 / 共 2 页
字号:
	{		strncpy(working_tmp, tmp, c - tmp);		working_tmp[c - tmp] = '\0';#if 0		putstr("search_inode: tmp = ");		putstr(tmp);		putstr("\r\n");		putstr("search_inode: wtmp = ");		putstr(working_tmp);		putstr("\r\n");		putstr("search_inode: c = ");		putstr(c);		putstr("\r\n");#endif		for (i = 0; i < strlen(c) - 1; i++)			tmp[i] = c[i + 1];		tmp[i] = '\0';#if 0		putstr("search_inode: post tmp = ");		putstr(tmp);		putstr("\r\n");#endif		if (!(pino = jffs2_1pass_find_inode(pL, working_tmp, pino))) {			putstr("find_inode failed for name=");			putstr(working_tmp);			putstr("\r\n");			return 0;		}	}	/* this is for the bare filename, directories have already been mapped */	if (!(pino = jffs2_1pass_find_inode(pL, tmp, pino))) {		putstr("find_inode failed for name=");		putstr(tmp);		putstr("\r\n");		return 0;	}	return pino;}static u32jffs2_1pass_resolve_inode(struct b_lists * pL, u32 ino){	struct b_dirent *jDir;	struct b_inode *jNode;	u8 jDirFoundType = 0;	u32 jDirFoundIno = 0;	u32 jDirFoundPino = 0;	char tmp[JFFS2_MAX_NAME_LEN + 1];	u32 version = 0;	u32 pino;	/* we need to search all and return the inode with the highest version */	for (jDir = (struct b_dirent *)pL->dir.listHead; jDir; jDir = jDir->next) {		if (ino == jDir->ino) {			if (jDir->version < version)				continue;			if (jDir->version == version && jDirFoundType) {				/* I'm pretty sure this isn't legal */				putstr(" ** ERROR ** ");/*				putnstr(jDir->name, jDir->nsize); *//*				putLabeledWord(" has dup version (resolve) = ", *//*					version); */			}			jDirFoundType = jDir->type;			jDirFoundIno = jDir->ino;			jDirFoundPino = jDir->pino;			version = jDir->version;		}	}	/* now we found the right entry again. (shoulda returned inode*) */	if (jDirFoundType != DT_LNK)		return jDirFoundIno;	/* it's a soft link so we follow it again. */	for (jNode = (struct b_inode *)pL->frag.listHead; jNode; jNode = jNode->next) {		if (jNode->ino == jDirFoundIno) {			size_t len = jNode->csize;			nand_read(nand, jNode->offset + sizeof(struct jffs2_raw_inode), &len, &tmp);			tmp[jNode->csize] = '\0';			break;		}	}	/* ok so the name of the new file to find is in tmp */	/* if it starts with a slash it is root based else shared dirs */	if (tmp[0] == '/')		pino = 1;	else		pino = jDirFoundPino;	return jffs2_1pass_search_inode(pL, tmp, pino);}static u32jffs2_1pass_search_list_inodes(struct b_lists * pL, const char *fname, u32 pino){	int i;	char tmp[256];	char working_tmp[256];	char *c;	/* discard any leading slash */	i = 0;	while (fname[i] == '/')		i++;	strcpy(tmp, &fname[i]);	working_tmp[0] = '\0';	while ((c = (char *) strchr(tmp, '/')))	/* we are still dired searching */	{		strncpy(working_tmp, tmp, c - tmp);		working_tmp[c - tmp] = '\0';		for (i = 0; i < strlen(c) - 1; i++)			tmp[i] = c[i + 1];		tmp[i] = '\0';		/* only a failure if we arent looking at top level */		if (!(pino = jffs2_1pass_find_inode(pL, working_tmp, pino)) &&		    (working_tmp[0])) {			putstr("find_inode failed for name=");			putstr(working_tmp);			putstr("\r\n");			return 0;		}	}	if (tmp[0] && !(pino = jffs2_1pass_find_inode(pL, tmp, pino))) {		putstr("find_inode failed for name=");		putstr(tmp);		putstr("\r\n");		return 0;	}	/* this is for the bare filename, directories have already been mapped */	if (!(pino = jffs2_1pass_list_inodes(pL, pino))) {		putstr("find_inode failed for name=");		putstr(tmp);		putstr("\r\n");		return 0;	}	return pino;}unsigned charjffs2_1pass_rescan_needed(struct part_info *part){	struct b_node *b;	struct jffs2_unknown_node onode;	struct jffs2_unknown_node *node;	struct b_lists *pL = (struct b_lists *)part->jffs2_priv;	if (part->jffs2_priv == 0){		DEBUGF ("rescan: First time in use\n");		return 1;	}	/* if we have no list, we need to rescan */	if (pL->frag.listCount == 0) {		DEBUGF ("rescan: fraglist zero\n");		return 1;	}	/* or if we are scanning a new partition */	if (pL->partOffset != part->offset) {		DEBUGF ("rescan: different partition\n");		return 1;	}	/* FIXME */#if 0	/* but suppose someone reflashed a partition at the same offset... */	b = pL->dir.listHead;	while (b) {		node = (struct jffs2_unknown_node *) get_fl_mem(b->offset,			sizeof(onode), &onode);		if (node->nodetype != JFFS2_NODETYPE_DIRENT) {			DEBUGF ("rescan: fs changed beneath me? (%lx)\n",					(unsigned long) b->offset);			return 1;		}		b = b->next;	}#endif	return 0;}#ifdef DEBUG_FRAGMENTSstatic voiddump_fragments(struct b_lists *pL){	struct b_node *b;	struct jffs2_raw_inode ojNode;	struct jffs2_raw_inode *jNode;	putstr("\r\n\r\n******The fragment Entries******\r\n");	b = pL->frag.listHead;	while (b) {		jNode = (struct jffs2_raw_inode *) get_fl_mem(b->offset,			sizeof(ojNode), &ojNode);		putLabeledWord("\r\n\tbuild_list: FLASH_OFFSET = ", b->offset);		putLabeledWord("\tbuild_list: totlen = ", jNode->totlen);		putLabeledWord("\tbuild_list: inode = ", jNode->ino);		putLabeledWord("\tbuild_list: version = ", jNode->version);		putLabeledWord("\tbuild_list: isize = ", jNode->isize);		putLabeledWord("\tbuild_list: atime = ", jNode->atime);		putLabeledWord("\tbuild_list: offset = ", jNode->offset);		putLabeledWord("\tbuild_list: csize = ", jNode->csize);		putLabeledWord("\tbuild_list: dsize = ", jNode->dsize);		putLabeledWord("\tbuild_list: compr = ", jNode->compr);		putLabeledWord("\tbuild_list: usercompr = ", jNode->usercompr);		putLabeledWord("\tbuild_list: flags = ", jNode->flags);		putLabeledWord("\tbuild_list: offset = ", b->offset);	/* FIXME: ? [RS] */		b = b->next;	}}#endif#ifdef DEBUG_DIRENTSstatic voiddump_dirents(struct b_lists *pL){	struct b_node *b;	struct jffs2_raw_dirent *jDir;	putstr("\r\n\r\n******The directory Entries******\r\n");	b = pL->dir.listHead;	while (b) {		jDir = (struct jffs2_raw_dirent *) get_node_mem(b->offset);		putstr("\r\n");		putnstr(jDir->name, jDir->nsize);		putLabeledWord("\r\n\tbuild_list: magic = ", jDir->magic);		putLabeledWord("\tbuild_list: nodetype = ", jDir->nodetype);		putLabeledWord("\tbuild_list: hdr_crc = ", jDir->hdr_crc);		putLabeledWord("\tbuild_list: pino = ", jDir->pino);		putLabeledWord("\tbuild_list: version = ", jDir->version);		putLabeledWord("\tbuild_list: ino = ", jDir->ino);		putLabeledWord("\tbuild_list: mctime = ", jDir->mctime);		putLabeledWord("\tbuild_list: nsize = ", jDir->nsize);		putLabeledWord("\tbuild_list: type = ", jDir->type);		putLabeledWord("\tbuild_list: node_crc = ", jDir->node_crc);		putLabeledWord("\tbuild_list: name_crc = ", jDir->name_crc);		putLabeledWord("\tbuild_list: offset = ", b->offset); 	/* FIXME: ? [RS] */		b = b->next;		put_fl_mem(jDir);	}}#endifstatic intjffs2_fill_scan_buf(nand_info_t *nand, unsigned char *buf,		    unsigned ofs, unsigned len){	int ret;	unsigned olen;	olen = len;	ret = nand_read(nand, ofs, &olen, buf);	if (ret) {		printf("nand_read(0x%x bytes from 0x%x) returned %d\n", len, ofs, ret);		return ret;	}	if (olen < len) {		printf("Read at 0x%x gave only 0x%x bytes\n", ofs, olen);		return -1;	}	return 0;}#define	EMPTY_SCAN_SIZE	1024static u32jffs2_1pass_build_lists(struct part_info * part){	struct b_lists *pL;	struct jffs2_unknown_node *node;	unsigned nr_blocks, sectorsize, ofs, offset;	char *buf;	int i;	u32 counter = 0;	u32 counter4 = 0;	u32 counterF = 0;	u32 counterN = 0;	struct mtdids *id = part->dev->id;	nand = nand_info + id->num;	/* if we are building a list we need to refresh the cache. */	jffs_init_1pass_list(part);	pL = (struct b_lists *)part->jffs2_priv;	pL->partOffset = part->offset;	puts ("Scanning JFFS2 FS:   ");	sectorsize = nand->erasesize;	nr_blocks = part->size / sectorsize;	buf = malloc(sectorsize);	if (!buf)		return 0;	for (i = 0; i < nr_blocks; i++) {		printf("\b\b%c ", spinner[counter++ % sizeof(spinner)]);		offset = part->offset + i * sectorsize;		if (nand_block_isbad(nand, offset))			continue;		if (jffs2_fill_scan_buf(nand, buf, offset, EMPTY_SCAN_SIZE))			return 0;		ofs = 0;		/* Scan only 4KiB of 0xFF before declaring it's empty */		while (ofs < EMPTY_SCAN_SIZE && *(uint32_t *)(&buf[ofs]) == 0xFFFFFFFF)			ofs += 4;		if (ofs == EMPTY_SCAN_SIZE)			continue;		if (jffs2_fill_scan_buf(nand, buf + EMPTY_SCAN_SIZE, offset + EMPTY_SCAN_SIZE, sectorsize - EMPTY_SCAN_SIZE))			return 0;		offset += ofs;		while (ofs < sectorsize - sizeof(struct jffs2_unknown_node)) {			node = (struct jffs2_unknown_node *)&buf[ofs];			if (node->magic != JFFS2_MAGIC_BITMASK || !hdr_crc(node)) {				offset += 4;				ofs += 4;				counter4++;				continue;			}			/* if its a fragment add it */			if (node->nodetype == JFFS2_NODETYPE_INODE &&				    inode_crc((struct jffs2_raw_inode *) node)) {				if (insert_inode(&pL->frag, (struct jffs2_raw_inode *) node,						 offset) == NULL) {					return 0;				}			} else if (node->nodetype == JFFS2_NODETYPE_DIRENT &&				   dirent_crc((struct jffs2_raw_dirent *) node)  &&				   dirent_name_crc((struct jffs2_raw_dirent *) node)) {				if (! (counterN%100))					puts ("\b\b.  ");				if (insert_dirent(&pL->dir, (struct jffs2_raw_dirent *) node,						  offset) == NULL) {					return 0;				}				counterN++;			} else if (node->nodetype == JFFS2_NODETYPE_CLEANMARKER) {				if (node->totlen != sizeof(struct jffs2_unknown_node))					printf("OOPS Cleanmarker has bad size "						"%d != %d\n", node->totlen,						sizeof(struct jffs2_unknown_node));			} else if (node->nodetype == JFFS2_NODETYPE_PADDING) {				if (node->totlen < sizeof(struct jffs2_unknown_node))					printf("OOPS Padding has bad size "						"%d < %d\n", node->totlen,						sizeof(struct jffs2_unknown_node));			} else {				printf("Unknown node type: %x len %d "					"offset 0x%x\n", node->nodetype,					node->totlen, offset);			}			offset += ((node->totlen + 3) & ~3);			ofs += ((node->totlen + 3) & ~3);			counterF++;		}	}	putstr("\b\b done.\r\n");		/* close off the dots */#if 0	putLabeledWord("dir entries = ", pL->dir.listCount);	putLabeledWord("frag entries = ", pL->frag.listCount);	putLabeledWord("+4 increments = ", counter4);	putLabeledWord("+file_offset increments = ", counterF);#endif#ifdef DEBUG_DIRENTS	dump_dirents(pL);#endif#ifdef DEBUG_FRAGMENTS	dump_fragments(pL);#endif	/* give visual feedback that we are done scanning the flash */	led_blink(0x0, 0x0, 0x1, 0x1);	/* off, forever, on 100ms, off 100ms */	free(buf);	return 1;}static u32jffs2_1pass_fill_info(struct b_lists * pL, struct b_jffs2_info * piL){	struct b_node *b;	struct jffs2_raw_inode ojNode;	struct jffs2_raw_inode *jNode;	int i;	for (i = 0; i < JFFS2_NUM_COMPR; i++) {		piL->compr_info[i].num_frags = 0;		piL->compr_info[i].compr_sum = 0;		piL->compr_info[i].decompr_sum = 0;	}/*	FIXME	b = pL->frag.listHead;	while (b) {		jNode = (struct jffs2_raw_inode *) get_fl_mem(b->offset,			sizeof(ojNode), &ojNode);		if (jNode->compr < JFFS2_NUM_COMPR) {			piL->compr_info[jNode->compr].num_frags++;			piL->compr_info[jNode->compr].compr_sum += jNode->csize;			piL->compr_info[jNode->compr].decompr_sum += jNode->dsize;		}		b = b->next;	}*/	return 0;}static struct b_lists *jffs2_get_list(struct part_info * part, const char *who){	if (jffs2_1pass_rescan_needed(part)) {		if (!jffs2_1pass_build_lists(part)) {			printf("%s: Failed to scan JFFSv2 file structure\n", who);			return NULL;		}	}	return (struct b_lists *)part->jffs2_priv;}/* Print directory / file contents */u32jffs2_1pass_ls(struct part_info * part, const char *fname){	struct b_lists *pl;	long ret = 0;	u32 inode;	if (! (pl = jffs2_get_list(part, "ls")))		return 0;	if (! (inode = jffs2_1pass_search_list_inodes(pl, fname, 1))) {		putstr("ls: Failed to scan jffs2 file structure\r\n");		return 0;	}#if 0	putLabeledWord("found file at inode = ", inode);	putLabeledWord("read_inode returns = ", ret);#endif	return ret;}/* Load a file from flash into memory. fname can be a full path */u32jffs2_1pass_load(char *dest, struct part_info * part, const char *fname){	struct b_lists *pl;	long ret = 0;	u32 inode;	if (! (pl = jffs2_get_list(part, "load")))		return 0;	if (! (inode = jffs2_1pass_search_inode(pl, fname, 1))) {		putstr("load: Failed to find inode\r\n");		return 0;	}	/* Resolve symlinks */	if (! (inode = jffs2_1pass_resolve_inode(pl, inode))) {		putstr("load: Failed to resolve inode structure\r\n");		return 0;	}	if ((ret = jffs2_1pass_read_inode(pl, inode, dest, NULL)) < 0) {		putstr("load: Failed to read inode\r\n");		return 0;	}	DEBUGF ("load: loaded '%s' to 0x%lx (%ld bytes)\n", fname,				(unsigned long) dest, ret);	return ret;}/* Return information about the fs on this partition */u32jffs2_1pass_info(struct part_info * part){	struct b_jffs2_info info;	struct b_lists *pl;	int i;	if (! (pl = jffs2_get_list(part, "info")))		return 0;	jffs2_1pass_fill_info(pl, &info);	for (i = 0; i < JFFS2_NUM_COMPR; i++) {		printf ("Compression: %s\n"			"\tfrag count: %d\n"			"\tcompressed sum: %d\n"			"\tuncompressed sum: %d\n",			compr_names[i],			info.compr_info[i].num_frags,			info.compr_info[i].compr_sum,			info.compr_info[i].decompr_sum);	}	return 1;}#endif /* CFG_CMD_JFFS2 */

⌨️ 快捷键说明

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