From: Russ D. <ru...@us...> - 2003-01-14 21:10:59
|
Update of /cvsroot/blob/blob/src/blob In directory sc8-pr-cvs1:/tmp/cvs-serv3122 Modified Files: jffs2.c Log Message: make jffs2 loader more error tolerant Index: jffs2.c =================================================================== RCS file: /cvsroot/blob/blob/src/blob/jffs2.c,v retrieving revision 1.4 retrieving revision 1.5 diff -u -d -r1.4 -r1.5 --- jffs2.c 27 Apr 2002 07:32:40 -0000 1.4 +++ jffs2.c 14 Jan 2003 21:10:39 -0000 1.5 @@ -138,30 +138,37 @@ } /* decompress a page from the flash, first contains a linked list of references - * all the nodes of this file, sorted is decending order (newest first) */ -static int jffs2_uncompress_page(char *dest, struct data_strip *first, u32 page) + * all the nodes of this file, sorted is decending order (newest first). Return + * the number of total bytes decompressed (not accurate, because some strips + * overlap, but at least we know we decompressed something) */ +static long jffs2_uncompress_page(char *dest, struct data_strip *first, u32 page) { int i; + long uncompressed = 0; char *src; /* look for the next reference to this page */ - for (; first && first->page != page; first = first->next); - if (!first) return 1; - - /* if we aren't covering what's behind us, uncompress that first */ + for (; first; first = first->next) { + /* This might be a page to uncompress, check that its the right + * page, and that the crc matches */ + if (first->page == page) { + src = ((char *) first->inode) + + sizeof(struct jffs2_raw_inode); + if (first->inode->data_crc == + crc32(0, src, first->inode->csize)) break; + } + } + + /* reached the end of the list without finding any pages */ + if (!first) return 0; + + /* if we aren't covering what's behind us, uncompress that first. + * Note: if the resulting doesn't quite fill the order, we are in + * trouble */ if (first->length != 4096) - if (!(jffs2_uncompress_page(dest, first->next, page))) - return 0; - + uncompressed = jffs2_uncompress_page(dest, first->next, page); dest += first->inode->offset; - src = ((char *) first->inode) + sizeof(struct jffs2_raw_inode); - - if (first->inode->data_crc != crc32(0, src, first->inode->csize)) { - printf("CRC Error!"); - return 0; - } - switch (first->inode->compr) { case JFFS2_COMPR_NONE: memcpy(dest, src, first->length); @@ -181,10 +188,10 @@ zlib_decompress(src, dest, first->inode->csize, first->length); break; default: - /* unknown */ - + /* unknown, attempt to ignore the page */ + return uncompressed; } - return 1; + return first->length + uncompressed; } static int jffs2_check_magic(struct part_info *part) @@ -255,7 +262,7 @@ for (page = 0; page <= size / 4096; page++) { /* Print a '.' every 0x40000 bytes */ if (!(page & 0x3F)) ldr_update_progress(); - if ((jffs2_uncompress_page((char *) dest, first, page)) <= 0) { + if (!jffs2_uncompress_page((char *) dest, first, page)) { UDEBUG("jffs2_uncompress_page failed on page 0x%lx\n", page); return 0; } @@ -357,7 +364,7 @@ } else pino = node->ino; - UDEBUG(" '%s' found at ino %ld\n", curr_name, pino); + UDEBUG(" '%s' found at ino %d\n", curr_name, pino); } while (name[i++] == '/'); return node; |