📄 jffs2_1pass.c
字号:
version = jDir->version; } put_fl_mem(jDir); } /* 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. */ b2 = pL->frag.listHead; while (b2) { jNode = (struct jffs2_raw_inode *) get_node_mem(b2->offset); if (jNode->ino == jDirFoundIno) { src = (unsigned char *)jNode + sizeof(struct jffs2_raw_inode);#if 0 putLabeledWord("\t\t dsize = ", jNode->dsize); putstr("\t\t target = "); putnstr(src, jNode->dsize); putstr("\r\n");#endif strncpy(tmp, src, jNode->dsize); tmp[jNode->dsize] = '\0'; put_fl_mem(jNode); break; } b2 = b2->next; put_fl_mem(jNode); } /* 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; }#if defined(CONFIG_JFFS2_NAND) && (CONFIG_COMMANDS & CFG_CMD_NAND) if (nanddev != (int)part->usr_priv - 1) { DEBUGF ("rescan: nand device changed\n"); return -1; }#endif /* defined(CONFIG_JFFS2_NAND) && (CONFIG_COMMANDS & CFG_CMD_NAND) */ /* 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; } 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 u32jffs2_1pass_build_lists(struct part_info * part){ struct b_lists *pL; struct jffs2_unknown_node *node; u32 offset, oldoffset = 0; u32 max = part->size - sizeof(struct jffs2_raw_inode); u32 counter = 0; u32 counter4 = 0; u32 counterF = 0; u32 counterN = 0;#if defined(CONFIG_JFFS2_NAND) && (CONFIG_COMMANDS & CFG_CMD_NAND) nanddev = (int)part->usr_priv - 1;#endif /* defined(CONFIG_JFFS2_NAND) && (CONFIG_COMMANDS & CFG_CMD_NAND) */ /* turn off the lcd. Refreshing the lcd adds 50% overhead to the */ /* jffs2 list building enterprise nope. in newer versions the overhead is */ /* only about 5 %. not enough to inconvenience people for. */ /* lcd_off(); */ /* 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; offset = 0; puts ("Scanning JFFS2 FS: "); /* start at the beginning of the partition */ while (offset < max) { if ((oldoffset >> SPIN_BLKSIZE) != (offset >> SPIN_BLKSIZE)) { printf("\b\b%c ", spinner[counter++ % sizeof(spinner)]); oldoffset = offset; } node = (struct jffs2_unknown_node *) get_node_mem((u32)part->offset + offset); if (node->magic == JFFS2_MAGIC_BITMASK && hdr_crc(node)) { /* if its a fragment add it */ if (node->nodetype == JFFS2_NODETYPE_INODE && inode_crc((struct jffs2_raw_inode *) node)) { if (insert_node(&pL->frag, (u32) part->offset + offset) == NULL) { put_fl_mem(node); 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_node(&pL->dir, (u32) part->offset + offset) == NULL) { put_fl_mem(node); 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); counterF++; } else if (node->magic == JFFS2_EMPTY_BITMASK && node->nodetype == JFFS2_EMPTY_BITMASK) { offset = jffs2_scan_empty(offset, part); } else { /* if we know nothing, we just step and look. */ offset += 4; counter4++; }/* printf("unknown node magic %4.4x %4.4x @ %lx\n", node->magic, node->nodetype, (unsigned long)node); */ put_fl_mem(node); } putstr("\b\b done.\r\n"); /* close off the dots */ /* turn the lcd back on. */ /* splash(); */#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 */ 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; } 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)) < 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 + -