return buf;
}
-static void *get_node_mem_nand(u32 off)
+static void *get_node_mem_nand(u32 off, void *ext_buf)
{
struct jffs2_unknown_node node;
void *ret = NULL;
if (!(ret = get_fl_mem_nand(off, node.magic ==
JFFS2_MAGIC_BITMASK ? node.totlen : sizeof(node),
- NULL))) {
+ ext_buf))) {
printf("off = %#x magic %#x type %#x node.totlen = %d\n",
off, node.magic, node.nodetype, node.totlen);
}
return buf;
}
-static void *get_node_mem_onenand(u32 off)
+static void *get_node_mem_onenand(u32 off, void *ext_buf)
{
struct jffs2_unknown_node node;
void *ret = NULL;
ret = get_fl_mem_onenand(off, node.magic ==
JFFS2_MAGIC_BITMASK ? node.totlen : sizeof(node),
- NULL);
+ ext_buf);
if (!ret) {
printf("off = %#x magic %#x type %#x node.totlen = %d\n",
off, node.magic, node.nodetype, node.totlen);
* NOR flash memory is mapped in processor's address space,
* just return address.
*/
-static inline void *get_fl_mem_nor(u32 off)
+static inline void *get_fl_mem_nor(u32 off, u32 size, void *ext_buf)
{
u32 addr = off;
struct mtdids *id = current_part->dev->id;
flash_info_t *flash = &flash_info[id->num];
addr += flash->start[0];
+ if (ext_buf) {
+ memcpy(ext_buf, (void *)addr, size);
+ return ext_buf;
+ }
return (void*)addr;
}
-static inline void *get_fl_mem_nor_copy(u32 off, u32 size, void *ext_buf)
+static inline void *get_node_mem_nor(u32 off, void *ext_buf)
{
- memcpy(ext_buf, get_fl_mem_nor(off), size);
- return ext_buf;
-}
+ struct jffs2_unknown_node *pNode;
-static inline void *get_node_mem_nor(u32 off)
-{
- return (void*)get_fl_mem_nor(off);
+ /* pNode will point directly to flash - don't provide external buffer
+ and don't care about size */
+ pNode = get_fl_mem_nor(off, 0, NULL);
+ return (void *)get_fl_mem_nor(off, pNode->magic == JFFS2_MAGIC_BITMASK ?
+ pNode->totlen : sizeof(*pNode), ext_buf);
}
#endif
#if defined(CONFIG_CMD_FLASH)
if (id->type == MTD_DEV_TYPE_NOR) {
- if (ext_buf)
- return get_fl_mem_nor_copy(off, size, ext_buf);
- return get_fl_mem_nor(off);
+ return get_fl_mem_nor(off, size, ext_buf);
}
#endif
return (void*)off;
}
-static inline void *get_node_mem(u32 off)
+static inline void *get_node_mem(u32 off, void *ext_buf)
{
struct mtdids *id = current_part->dev->id;
#if defined(CONFIG_CMD_FLASH)
if (id->type == MTD_DEV_TYPE_NOR)
- return get_node_mem_nor(off);
+ return get_node_mem_nor(off, ext_buf);
#endif
#if defined(CONFIG_JFFS2_NAND) && \
defined(CONFIG_CMD_NAND)
if (id->type == MTD_DEV_TYPE_NAND)
- return get_node_mem_nand(off);
+ return get_node_mem_nand(off, ext_buf);
#endif
#if defined(CONFIG_CMD_ONENAND)
if (id->type == MTD_DEV_TYPE_ONENAND)
- return get_node_mem_onenand(off);
+ return get_node_mem_onenand(off, ext_buf);
#endif
printf("get_node_mem: unknown device type, using raw offset!\n");
return (void*)off;
}
-static inline void put_fl_mem(void *buf)
+static inline void put_fl_mem(void *buf, void *ext_buf)
{
struct mtdids *id = current_part->dev->id;
+ /* If buf is the same as ext_buf, it was provided by the caller -
+ we shouldn't free it then. */
+ if (buf == ext_buf)
+ return;
switch (id->type) {
#if defined(CONFIG_JFFS2_NAND) && defined(CONFIG_CMD_NAND)
case MTD_DEV_TYPE_NAND:
pL = (struct b_lists *)part->jffs2_priv;
free_nodes(&pL->frag);
free_nodes(&pL->dir);
+ free(pL->readbuf);
free(pL);
}
}
*/
for (b = pL->frag.listHead; b != NULL; b = b->next) {
jNode = (struct jffs2_raw_inode *) get_fl_mem(b->offset,
- sizeof(struct jffs2_raw_inode), NULL);
+ sizeof(struct jffs2_raw_inode), pL->readbuf);
if ((inode == jNode->ino)) {
/* get actual file length from the newest node */
if (jNode->version >= latestVersion) {
latestVersion = jNode->version;
}
}
- put_fl_mem(jNode);
+ put_fl_mem(jNode, pL->readbuf);
}
#endif
for (b = pL->frag.listHead; b != NULL; b = b->next) {
- jNode = (struct jffs2_raw_inode *) get_node_mem(b->offset);
+ jNode = (struct jffs2_raw_inode *) get_node_mem(b->offset,
+ pL->readbuf);
if ((inode == jNode->ino)) {
#if 0
putLabeledWord("\r\n\r\nread_inode: totlen = ", jNode->totlen);
src = ((uchar *) jNode) + sizeof(struct jffs2_raw_inode);
/* ignore data behind latest known EOF */
if (jNode->offset > totalSize) {
- put_fl_mem(jNode);
+ put_fl_mem(jNode, pL->readbuf);
continue;
}
if (!data_crc(jNode)) {
- put_fl_mem(jNode);
+ put_fl_mem(jNode, pL->readbuf);
continue;
}
default:
/* unknown */
putLabeledWord("UNKOWN COMPRESSION METHOD = ", jNode->compr);
- put_fl_mem(jNode);
+ put_fl_mem(jNode, pL->readbuf);
return -1;
break;
}
#endif
}
counter++;
- put_fl_mem(jNode);
+ put_fl_mem(jNode, pL->readbuf);
}
#if 0
counter = 0;
/* we need to search all and return the inode with the highest version */
for(b = pL->dir.listHead; b; b = b->next, counter++) {
- jDir = (struct jffs2_raw_dirent *) get_node_mem(b->offset);
+ jDir = (struct jffs2_raw_dirent *) get_node_mem(b->offset,
+ pL->readbuf);
if ((pino == jDir->pino) && (len == jDir->nsize) &&
(jDir->ino) && /* 0 for unlink */
(!strncmp((char *)jDir->name, name, len))) { /* a match */
if (jDir->version < version) {
- put_fl_mem(jDir);
+ put_fl_mem(jDir, pL->readbuf);
continue;
}
putLabeledWord("b = ", (u32) b);
putLabeledWord("counter = ", counter);
#endif
- put_fl_mem(jDir);
+ put_fl_mem(jDir, pL->readbuf);
}
return inode;
}
struct jffs2_raw_dirent *jDir;
for (b = pL->dir.listHead; b; b = b->next) {
- jDir = (struct jffs2_raw_dirent *) get_node_mem(b->offset);
+ jDir = (struct jffs2_raw_dirent *) get_node_mem(b->offset,
+ pL->readbuf);
if ((pino == jDir->pino) && (jDir->ino)) { /* ino=0 -> unlink */
u32 i_version = 0;
struct jffs2_raw_inode ojNode;
if (jNode->ino == jDir->ino && jNode->version >= i_version) {
i_version = jNode->version;
if (i)
- put_fl_mem(i);
+ put_fl_mem(i, NULL);
if (jDir->type == DT_LNK)
- i = get_node_mem(b2->offset);
+ i = get_node_mem(b2->offset,
+ NULL);
else
- i = get_fl_mem(b2->offset, sizeof(*i), NULL);
+ i = get_fl_mem(b2->offset,
+ sizeof(*i),
+ NULL);
}
b2 = b2->next;
}
dump_inode(pL, jDir, i);
- put_fl_mem(i);
+ put_fl_mem(i, NULL);
}
- put_fl_mem(jDir);
+ put_fl_mem(jDir, pL->readbuf);
}
return pino;
}
/* we need to search all and return the inode with the highest version */
for(b = pL->dir.listHead; b; b = b->next) {
- jDir = (struct jffs2_raw_dirent *) get_node_mem(b->offset);
+ jDir = (struct jffs2_raw_dirent *) get_node_mem(b->offset,
+ pL->readbuf);
if (ino == jDir->ino) {
if (jDir->version < version) {
- put_fl_mem(jDir);
+ put_fl_mem(jDir, pL->readbuf);
continue;
}
jDirFoundPino = jDir->pino;
version = jDir->version;
}
- put_fl_mem(jDir);
+ put_fl_mem(jDir, pL->readbuf);
}
/* now we found the right entry again. (shoulda returned inode*) */
if (jDirFoundType != DT_LNK)
/* 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);
+ jNode = (struct jffs2_raw_inode *) get_node_mem(b2->offset,
+ pL->readbuf);
if (jNode->ino == jDirFoundIno) {
src = (unsigned char *)jNode + sizeof(struct jffs2_raw_inode);
#endif
strncpy(tmp, (char *)src, jNode->dsize);
tmp[jNode->dsize] = '\0';
- put_fl_mem(jNode);
+ put_fl_mem(jNode, pL->readbuf);
break;
}
b2 = b2->next;
- put_fl_mem(jNode);
+ put_fl_mem(jNode, pL->readbuf);
}
/* 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 */
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);
+ jDir = (struct jffs2_raw_dirent *) get_node_mem(b->offset,
+ pL->readbuf);
putstr("\r\n");
putnstr(jDir->name, jDir->nsize);
putLabeledWord("\r\n\tbuild_list: magic = ", jDir->magic);
putLabeledWord("\tbuild_list: name_crc = ", jDir->name_crc);
putLabeledWord("\tbuild_list: offset = ", b->offset); /* FIXME: ? [RS] */
b = b->next;
- put_fl_mem(jDir);
+ put_fl_mem(jDir, pL->readbuf);
}
}
#endif
u32 counter4 = 0;
u32 counterF = 0;
u32 counterN = 0;
+ u32 max_totlen = 0;
u32 buf_size = DEFAULT_EMPTY_SCAN_SIZE;
char *buf;
if (insert_node(&pL->frag, (u32) part->offset +
ofs) == NULL)
return 0;
+ if (max_totlen < node->totlen)
+ max_totlen = node->totlen;
break;
case JFFS2_NODETYPE_DIRENT:
if (buf_ofs + buf_len < ofs + sizeof(struct
if (insert_node(&pL->dir, (u32) part->offset +
ofs) == NULL)
return 0;
+ if (max_totlen < node->totlen)
+ max_totlen = node->totlen;
counterN++;
break;
case JFFS2_NODETYPE_CLEANMARKER:
free(buf);
putstr("\b\b done.\r\n"); /* close off the dots */
+
+ /* We don't care if malloc failed - then each read operation will
+ * allocate its own buffer as necessary (NAND) or will read directly
+ * from flash (NOR).
+ */
+ pL->readbuf = malloc(max_totlen);
+
/* turn the lcd back on. */
/* splash(); */