]> git.sur5r.net Git - u-boot/blobdiff - fs/jffs2/jffs2_1pass.c
Fix problem with symbolic links in JFFS2 code.
[u-boot] / fs / jffs2 / jffs2_1pass.c
index 9acf37bca10c815848adef3857be990f91db7eac..f3a9c53997cd8af9947742b98248ab4ba9206e09 100644 (file)
@@ -182,8 +182,8 @@ static int read_nand_cached(u32 off, u32 size, u_char *buf)
                        if (!nand_cache) {
                                /* This memory never gets freed but 'cause
                                   it's a bootloader, nobody cares */
-                               nand_cache = malloc(NAND_CACHE_SIZE); 
-                               if (!nand_cache) { 
+                               nand_cache = malloc(NAND_CACHE_SIZE);
+                               if (!nand_cache) {
                                        printf("read_nand_cached: can't alloc cache size %d bytes\n",
                                               NAND_CACHE_SIZE);
                                        return -1;
@@ -217,7 +217,8 @@ static void *get_fl_mem(u32 off, u32 size, void *ext_buf)
                return NULL;
        }
        if (read_nand_cached(off, size, buf) < 0) {
-               free(buf);
+               if (!ext_buf)
+                       free(buf);
                return NULL;
        }
 
@@ -241,7 +242,7 @@ static void *get_node_mem(u32 off)
        return ret;
 }
 
-static void put_fl_mem(void *buf) 
+static void put_fl_mem(void *buf)
 {
        free(buf);
 }
@@ -258,7 +259,7 @@ static inline void *get_node_mem(u32 off)
        return (void*)off;
 }
 
-static inline void put_fl_mem(void *buf) 
+static inline void put_fl_mem(void *buf)
 {
 }
 
@@ -414,7 +415,7 @@ static int compare_dirents(struct b_node *new, struct b_node *old)
        struct jffs2_raw_dirent ojOld;
        struct jffs2_raw_dirent *jNew =
                (struct jffs2_raw_dirent *)get_fl_mem(new->offset, sizeof(ojNew), &ojNew);
-       struct jffs2_raw_dirent *jOld = 
+       struct jffs2_raw_dirent *jOld =
                (struct jffs2_raw_dirent *)get_fl_mem(old->offset, sizeof(ojOld), &ojOld);
        int cmp;
 
@@ -511,7 +512,7 @@ jffs2_1pass_read_inode(struct b_lists *pL, u32 inode, char *dest)
         * we will live with it.
         */
        for (b = pL->frag.listHead; b != NULL; b = b->next) {
-               jNode = (struct jffs2_raw_inode *) get_fl_mem(b->offset, 
+               jNode = (struct jffs2_raw_inode *) get_fl_mem(b->offset,
                        sizeof(struct jffs2_raw_inode), NULL);
                if ((inode == jNode->ino)) {
                        /* get actual file length from the newest node */
@@ -756,9 +757,15 @@ jffs2_1pass_list_inodes(struct b_lists * pL, u32 pino)
                        while (b2) {
                                jNode = (struct jffs2_raw_inode *)
                                        get_fl_mem(b2->offset, sizeof(ojNode), &ojNode);
-                               if (jNode->ino == jDir->ino
-                                   && jNode->version >= i_version)
-                                       i = get_fl_mem(b2->offset, sizeof(*i), NULL);
+                               if (jNode->ino == jDir->ino && jNode->version >= i_version) {
+                                       if (i)
+                                               put_fl_mem(i);
+
+                                       if (jDir->type == DT_LNK)
+                                               i = get_node_mem(b2->offset);
+                                       else
+                                               i = get_fl_mem(b2->offset, sizeof(*i), NULL);
+                               }
                                b2 = b2->next;
                        }
 
@@ -874,7 +881,7 @@ jffs2_1pass_resolve_inode(struct b_lists * pL, u32 ino)
        while (b2) {
                jNode = (struct jffs2_raw_inode *) get_node_mem(b2->offset);
                if (jNode->ino == jDirFoundIno) {
-                       src = (unsigned char *) (b2->offset + sizeof(struct jffs2_raw_inode));
+                       src = (unsigned char *)jNode + sizeof(struct jffs2_raw_inode);
 
 #if 0
                        putLabeledWord("\t\t dsize = ", jNode->dsize);