|
@@ -549,7 +549,7 @@ add_node(struct b_list *list)
|
|
|
}
|
|
|
|
|
|
static struct b_node *
|
|
|
-insert_node(struct b_list *list, u32 offset)
|
|
|
+insert_node(struct b_list *list)
|
|
|
{
|
|
|
struct b_node *new;
|
|
|
|
|
@@ -557,7 +557,6 @@ insert_node(struct b_list *list, u32 offset)
|
|
|
putstr("add_node failed!\r\n");
|
|
|
return NULL;
|
|
|
}
|
|
|
- new->offset = offset;
|
|
|
new->next = NULL;
|
|
|
|
|
|
if (list->listTail != NULL)
|
|
@@ -575,18 +574,7 @@ insert_node(struct b_list *list, u32 offset)
|
|
|
*/
|
|
|
static int compare_inodes(struct b_node *new, struct b_node *old)
|
|
|
{
|
|
|
- /*
|
|
|
- * Only read in the version info from flash, not the entire inode.
|
|
|
- * This can make a big difference to speed if flash is slow.
|
|
|
- */
|
|
|
- u32 new_version;
|
|
|
- u32 old_version;
|
|
|
- get_fl_mem(new->offset + offsetof(struct jffs2_raw_inode, version),
|
|
|
- sizeof(new_version), &new_version);
|
|
|
- get_fl_mem(old->offset + offsetof(struct jffs2_raw_inode, version),
|
|
|
- sizeof(old_version), &old_version);
|
|
|
-
|
|
|
- return new_version > old_version;
|
|
|
+ return new->version > old->version;
|
|
|
}
|
|
|
|
|
|
/* Sort directory entries so all entries in the same directory
|
|
@@ -683,7 +671,7 @@ jffs2_1pass_read_inode(struct b_lists *pL, u32 inode, char *dest)
|
|
|
uchar *src;
|
|
|
int i;
|
|
|
u32 counter = 0;
|
|
|
-#ifdef CONFIG_SYS_JFFS2_SORT_FRAGMENTS
|
|
|
+
|
|
|
/* Find file size before loading any data, so fragments that
|
|
|
* start past the end of file can be ignored. A fragment
|
|
|
* that is partially in the file is loaded, so extra data may
|
|
@@ -691,35 +679,40 @@ jffs2_1pass_read_inode(struct b_lists *pL, u32 inode, char *dest)
|
|
|
* This shouldn't cause trouble when loading kernel images, so
|
|
|
* we will live with it.
|
|
|
*/
|
|
|
+ int latestOffset = -1;
|
|
|
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), pL->readbuf);
|
|
|
- if ((inode == jNode->ino)) {
|
|
|
+ if (inode == b->ino) {
|
|
|
/* get actual file length from the newest node */
|
|
|
- if (jNode->version >= latestVersion) {
|
|
|
- totalSize = jNode->isize;
|
|
|
- latestVersion = jNode->version;
|
|
|
+ if (b->version >= latestVersion) {
|
|
|
+ latestVersion = b->version;
|
|
|
+ latestOffset = b->offset;
|
|
|
}
|
|
|
}
|
|
|
+ }
|
|
|
+
|
|
|
+ if (latestOffset >= 0) {
|
|
|
+ jNode = (struct jffs2_raw_inode *)get_fl_mem(latestOffset,
|
|
|
+ sizeof(struct jffs2_raw_inode), pL->readbuf);
|
|
|
+ totalSize = jNode->isize;
|
|
|
put_fl_mem(jNode, pL->readbuf);
|
|
|
}
|
|
|
+
|
|
|
/*
|
|
|
* If no destination is provided, we are done.
|
|
|
* Just return the total size.
|
|
|
*/
|
|
|
if (!dest)
|
|
|
return totalSize;
|
|
|
-#endif
|
|
|
|
|
|
for (b = pL->frag.listHead; b != NULL; b = b->next) {
|
|
|
- /*
|
|
|
- * Copy just the node and not the data at this point,
|
|
|
- * since we don't yet know if we need this data.
|
|
|
- */
|
|
|
- jNode = (struct jffs2_raw_inode *)get_fl_mem(b->offset,
|
|
|
- sizeof(struct jffs2_raw_inode),
|
|
|
- pL->readbuf);
|
|
|
- if (inode == jNode->ino) {
|
|
|
+ if (inode == b->ino) {
|
|
|
+ /*
|
|
|
+ * Copy just the node and not the data at this point,
|
|
|
+ * since we don't yet know if we need this data.
|
|
|
+ */
|
|
|
+ jNode = (struct jffs2_raw_inode *)get_fl_mem(b->offset,
|
|
|
+ sizeof(struct jffs2_raw_inode),
|
|
|
+ pL->readbuf);
|
|
|
#if 0
|
|
|
putLabeledWord("\r\n\r\nread_inode: totlen = ", jNode->totlen);
|
|
|
putLabeledWord("read_inode: inode = ", jNode->ino);
|
|
@@ -733,14 +726,6 @@ jffs2_1pass_read_inode(struct b_lists *pL, u32 inode, char *dest)
|
|
|
putLabeledWord("read_inode: flags = ", jNode->flags);
|
|
|
#endif
|
|
|
|
|
|
-#ifndef CONFIG_SYS_JFFS2_SORT_FRAGMENTS
|
|
|
- /* get actual file length from the newest node */
|
|
|
- if (jNode->version >= latestVersion) {
|
|
|
- totalSize = jNode->isize;
|
|
|
- latestVersion = jNode->version;
|
|
|
- }
|
|
|
-#endif
|
|
|
-
|
|
|
if(dest) {
|
|
|
/*
|
|
|
* Now that the inode has been checked,
|
|
@@ -804,9 +789,9 @@ jffs2_1pass_read_inode(struct b_lists *pL, u32 inode, char *dest)
|
|
|
#if 0
|
|
|
putLabeledWord("read_inode: totalSize = ", totalSize);
|
|
|
#endif
|
|
|
+ put_fl_mem(jNode, pL->readbuf);
|
|
|
}
|
|
|
counter++;
|
|
|
- put_fl_mem(jNode, pL->readbuf);
|
|
|
}
|
|
|
|
|
|
#if 0
|
|
@@ -953,13 +938,14 @@ jffs2_1pass_list_inodes(struct b_lists * pL, u32 pino)
|
|
|
struct jffs2_raw_dirent *jDir;
|
|
|
|
|
|
for (b = pL->dir.listHead; b; b = b->next) {
|
|
|
- jDir = (struct jffs2_raw_dirent *) get_node_mem(b->offset,
|
|
|
- pL->readbuf);
|
|
|
- if (pino == jDir->pino) {
|
|
|
+ if (pino == b->pino) {
|
|
|
u32 i_version = 0;
|
|
|
- struct jffs2_raw_inode *jNode, *i = NULL;
|
|
|
+ int i_offset = -1;
|
|
|
+ struct jffs2_raw_inode *jNode = NULL;
|
|
|
struct b_node *b2;
|
|
|
|
|
|
+ jDir = (struct jffs2_raw_dirent *)
|
|
|
+ get_node_mem(b->offset, pL->readbuf);
|
|
|
#ifdef CONFIG_SYS_JFFS2_SORT_FRAGMENTS
|
|
|
/* Check for more recent versions of this file */
|
|
|
int match;
|
|
@@ -991,30 +977,27 @@ jffs2_1pass_list_inodes(struct b_lists * pL, u32 pino)
|
|
|
}
|
|
|
|
|
|
for (b2 = pL->frag.listHead; b2; b2 = b2->next) {
|
|
|
- jNode = (struct jffs2_raw_inode *)
|
|
|
- get_fl_mem(b2->offset, sizeof(*jNode),
|
|
|
- NULL);
|
|
|
- if (jNode->ino == jDir->ino &&
|
|
|
- jNode->version >= i_version) {
|
|
|
- i_version = jNode->version;
|
|
|
- if (i)
|
|
|
- put_fl_mem(i, NULL);
|
|
|
-
|
|
|
- if (jDir->type == DT_LNK)
|
|
|
- i = get_node_mem(b2->offset,
|
|
|
- NULL);
|
|
|
- else
|
|
|
- i = get_fl_mem(b2->offset,
|
|
|
- sizeof(*i),
|
|
|
- NULL);
|
|
|
+ if (b2->ino == jDir->ino &&
|
|
|
+ b2->version >= i_version) {
|
|
|
+ i_version = b2->version;
|
|
|
+ i_offset = b2->offset;
|
|
|
}
|
|
|
- put_fl_mem(jNode, NULL);
|
|
|
}
|
|
|
|
|
|
- dump_inode(pL, jDir, i);
|
|
|
- put_fl_mem(i, NULL);
|
|
|
+ if (i_version >= 0) {
|
|
|
+ if (jDir->type == DT_LNK)
|
|
|
+ jNode = get_node_mem(i_offset, NULL);
|
|
|
+ else
|
|
|
+ jNode = get_fl_mem(i_offset,
|
|
|
+ sizeof(*jNode),
|
|
|
+ NULL);
|
|
|
+ }
|
|
|
+
|
|
|
+ dump_inode(pL, jDir, jNode);
|
|
|
+ put_fl_mem(jNode, NULL);
|
|
|
+
|
|
|
+ put_fl_mem(jDir, pL->readbuf);
|
|
|
}
|
|
|
- put_fl_mem(jDir, pL->readbuf);
|
|
|
}
|
|
|
return pino;
|
|
|
}
|
|
@@ -1266,7 +1249,7 @@ static int jffs2_sum_process_sum_data(struct part_info *part, uint32_t offset,
|
|
|
{
|
|
|
void *sp;
|
|
|
int i, pass;
|
|
|
- void *ret;
|
|
|
+ struct b_node *b;
|
|
|
|
|
|
for (pass = 0; pass < 2; pass++) {
|
|
|
sp = summary->sum;
|
|
@@ -1281,13 +1264,17 @@ static int jffs2_sum_process_sum_data(struct part_info *part, uint32_t offset,
|
|
|
if (pass) {
|
|
|
spi = sp;
|
|
|
|
|
|
- ret = insert_node(&pL->frag,
|
|
|
- (u32)part->offset +
|
|
|
+ b = insert_node(&pL->frag);
|
|
|
+ if (!b)
|
|
|
+ return -1;
|
|
|
+ b->offset = (u32)part->offset +
|
|
|
offset +
|
|
|
sum_get_unaligned32(
|
|
|
- &spi->offset));
|
|
|
- if (ret == NULL)
|
|
|
- return -1;
|
|
|
+ &spi->offset);
|
|
|
+ b->version = sum_get_unaligned32(
|
|
|
+ &spi->version);
|
|
|
+ b->ino = sum_get_unaligned32(
|
|
|
+ &spi->inode);
|
|
|
}
|
|
|
|
|
|
sp += JFFS2_SUMMARY_INODE_SIZE;
|
|
@@ -1298,13 +1285,17 @@ static int jffs2_sum_process_sum_data(struct part_info *part, uint32_t offset,
|
|
|
struct jffs2_sum_dirent_flash *spd;
|
|
|
spd = sp;
|
|
|
if (pass) {
|
|
|
- ret = insert_node(&pL->dir,
|
|
|
- (u32) part->offset +
|
|
|
+ b = insert_node(&pL->dir);
|
|
|
+ if (!b)
|
|
|
+ return -1;
|
|
|
+ b->offset = (u32)part->offset +
|
|
|
offset +
|
|
|
sum_get_unaligned32(
|
|
|
- &spd->offset));
|
|
|
- if (ret == NULL)
|
|
|
- return -1;
|
|
|
+ &spd->offset);
|
|
|
+ b->version = sum_get_unaligned32(
|
|
|
+ &spd->version);
|
|
|
+ b->pino = sum_get_unaligned32(
|
|
|
+ &spd->pino);
|
|
|
}
|
|
|
|
|
|
sp += JFFS2_SUMMARY_DIRENT_SIZE(
|
|
@@ -1508,6 +1499,7 @@ jffs2_1pass_build_lists(struct part_info * part)
|
|
|
/* Indicates a sector with a CLEANMARKER was found */
|
|
|
int clean_sector = 0;
|
|
|
struct jffs2_unknown_node crcnode;
|
|
|
+ struct b_node *b;
|
|
|
|
|
|
/* Set buf_size to maximum length */
|
|
|
buf_size = DEFAULT_EMPTY_SCAN_SIZE;
|
|
@@ -1715,12 +1707,15 @@ jffs2_1pass_build_lists(struct part_info * part)
|
|
|
if (!inode_crc((struct jffs2_raw_inode *)node))
|
|
|
break;
|
|
|
|
|
|
- if (insert_node(&pL->frag, (u32) part->offset +
|
|
|
- ofs) == NULL) {
|
|
|
+ b = insert_node(&pL->frag);
|
|
|
+ if (!b) {
|
|
|
free(buf);
|
|
|
jffs2_free_cache(part);
|
|
|
return 0;
|
|
|
}
|
|
|
+ b->offset = (u32)part->offset + ofs;
|
|
|
+ b->version = node->i.version;
|
|
|
+ b->ino = node->i.ino;
|
|
|
if (max_totlen < node->u.totlen)
|
|
|
max_totlen = node->u.totlen;
|
|
|
break;
|
|
@@ -1750,12 +1745,15 @@ jffs2_1pass_build_lists(struct part_info * part)
|
|
|
break;
|
|
|
if (! (counterN%100))
|
|
|
puts ("\b\b. ");
|
|
|
- if (insert_node(&pL->dir, (u32) part->offset +
|
|
|
- ofs) == NULL) {
|
|
|
+ b = insert_node(&pL->dir);
|
|
|
+ if (!b) {
|
|
|
free(buf);
|
|
|
jffs2_free_cache(part);
|
|
|
return 0;
|
|
|
}
|
|
|
+ b->offset = (u32)part->offset + ofs;
|
|
|
+ b->version = node->d.version;
|
|
|
+ b->pino = node->d.pino;
|
|
|
if (max_totlen < node->u.totlen)
|
|
|
max_totlen = node->u.totlen;
|
|
|
counterN++;
|