Merge branch 'master' of git://git.denx.de/u-boot-video
[oweals/u-boot.git] / fs / ext4 / ext4_common.c
index 33d69c9c71f07819c73678c2efc7abc175a8c607..84fba767c1ad71e3a5df53c8bbd0696e2f690f81 100644 (file)
@@ -22,7 +22,9 @@
 #include <common.h>
 #include <ext_common.h>
 #include <ext4fs.h>
+#include <inttypes.h>
 #include <malloc.h>
+#include <memalign.h>
 #include <stddef.h>
 #include <linux/stat.h>
 #include <linux/time.h>
@@ -73,35 +75,26 @@ void put_ext4(uint64_t off, void *buf, uint32_t size)
        if ((startblock + (size >> log2blksz)) >
            (part_offset + fs->total_sect)) {
                printf("part_offset is " LBAFU "\n", part_offset);
-               printf("total_sector is %llu\n", fs->total_sect);
+               printf("total_sector is %" PRIu64 "\n", fs->total_sect);
                printf("error: overflow occurs\n");
                return;
        }
 
        if (remainder) {
-               if (fs->dev_desc->block_read) {
-                       fs->dev_desc->block_read(fs->dev_desc->dev,
-                                                startblock, 1, sec_buf);
-                       temp_ptr = sec_buf;
-                       memcpy((temp_ptr + remainder),
-                              (unsigned char *)buf, size);
-                       fs->dev_desc->block_write(fs->dev_desc->dev,
-                                                 startblock, 1, sec_buf);
-               }
+               blk_dread(fs->dev_desc, startblock, 1, sec_buf);
+               temp_ptr = sec_buf;
+               memcpy((temp_ptr + remainder), (unsigned char *)buf, size);
+               blk_dwrite(fs->dev_desc, startblock, 1, sec_buf);
        } else {
                if (size >> log2blksz != 0) {
-                       fs->dev_desc->block_write(fs->dev_desc->dev,
-                                                 startblock,
-                                                 size >> log2blksz,
-                                                 (unsigned long *)buf);
+                       blk_dwrite(fs->dev_desc, startblock, size >> log2blksz,
+                                  (unsigned long *)buf);
                } else {
-                       fs->dev_desc->block_read(fs->dev_desc->dev,
-                                                startblock, 1, sec_buf);
+                       blk_dread(fs->dev_desc, startblock, 1, sec_buf);
                        temp_ptr = sec_buf;
                        memcpy(temp_ptr, buf, size);
-                       fs->dev_desc->block_write(fs->dev_desc->dev,
-                                                 startblock, 1,
-                                                 (unsigned long *)sec_buf);
+                       blk_dwrite(fs->dev_desc, startblock, 1,
+                                  (unsigned long *)sec_buf);
                }
        }
 }
@@ -613,8 +606,7 @@ static int parse_path(char **arr, char *dirname)
        arr[i] = zalloc(strlen("/") + 1);
        if (!arr[i])
                return -ENOMEM;
-
-       arr[i++] = "/";
+       memcpy(arr[i++], "/", strlen("/"));
 
        /* add each path entry after root */
        while (token != NULL) {
@@ -744,6 +736,11 @@ end:
 fail:
        free(depth_dirname);
        free(parse_dirname);
+       for (i = 0; i < depth; i++) {
+               if (!ptr[i])
+                       break;
+               free(ptr[i]);
+       }
        free(ptr);
        free(parent_inode);
        free(first_inode);
@@ -764,6 +761,7 @@ static int check_filename(char *filename, unsigned int blknr)
        struct ext2_dirent *previous_dir = NULL;
        char *ptr = NULL;
        struct ext_filesystem *fs = get_fs();
+       int ret = -1;
 
        /* get the first block of root */
        first_block_no_of_root = blknr;
@@ -817,12 +815,12 @@ static int check_filename(char *filename, unsigned int blknr)
                if (ext4fs_put_metadata(root_first_block_addr,
                                        first_block_no_of_root))
                        goto fail;
-               return inodeno;
+               ret = inodeno;
        }
 fail:
        free(root_first_block_buffer);
 
-       return -1;
+       return ret;
 }
 
 int ext4fs_filename_check(char *filename)
@@ -1280,11 +1278,11 @@ static void alloc_triple_indirect_block(struct ext2_inode *file_inode,
                ti_gp_blockno = ext4fs_get_new_blk_no();
                if (ti_gp_blockno == -1) {
                        printf("no block left to assign\n");
-                       goto fail;
+                       return;
                }
                ti_gp_buff = zalloc(fs->blksz);
                if (!ti_gp_buff)
-                       goto fail;
+                       return;
 
                ti_gp_buff_start_addr = ti_gp_buff;
                (*no_blks_reqd)++;
@@ -1314,11 +1312,11 @@ static void alloc_triple_indirect_block(struct ext2_inode *file_inode,
                                ti_child_blockno = ext4fs_get_new_blk_no();
                                if (ti_child_blockno == -1) {
                                        printf("no block left assign\n");
-                                       goto fail;
+                                       goto fail1;
                                }
                                ti_child_buff = zalloc(fs->blksz);
                                if (!ti_child_buff)
-                                       goto fail;
+                                       goto fail1;
 
                                ti_cbuff_start_addr = ti_child_buff;
                                *ti_parent_buff = ti_child_blockno;
@@ -1334,7 +1332,8 @@ static void alloc_triple_indirect_block(struct ext2_inode *file_inode,
                                            ext4fs_get_new_blk_no();
                                        if (actual_block_no == -1) {
                                                printf("no block left\n");
-                                               goto fail;
+                                               free(ti_cbuff_start_addr);
+                                               goto fail1;
                                        }
                                        *ti_child_buff = actual_block_no;
                                        debug("TIAB %ld: %u\n", actual_block_no,
@@ -1366,7 +1365,11 @@ static void alloc_triple_indirect_block(struct ext2_inode *file_inode,
                put_ext4(((uint64_t) ((uint64_t)ti_gp_blockno * (uint64_t)fs->blksz)),
                         ti_gp_buff_start_addr, fs->blksz);
                file_inode->b.blocks.triple_indir_block = ti_gp_blockno;
+               free(ti_gp_buff_start_addr);
+               return;
        }
+fail1:
+       free(ti_pbuff_start_addr);
 fail:
        free(ti_gp_buff_start_addr);
 }
@@ -1891,6 +1894,7 @@ int ext4fs_iterate_dir(struct ext2fs_node *dir, char *name,
 {
        unsigned int fpos = 0;
        int status;
+       loff_t actread;
        struct ext2fs_node *diro = (struct ext2fs_node *) dir;
 
 #ifdef DEBUG
@@ -1908,10 +1912,15 @@ int ext4fs_iterate_dir(struct ext2fs_node *dir, char *name,
 
                status = ext4fs_read_file(diro, fpos,
                                           sizeof(struct ext2_dirent),
-                                          (char *) &dirent);
-               if (status < 1)
+                                          (char *)&dirent, &actread);
+               if (status < 0)
                        return 0;
 
+               if (dirent.direntlen == 0) {
+                       printf("Failed to iterate over directory %s\n", name);
+                       return 0;
+               }
+
                if (dirent.namelen != 0) {
                        char filename[dirent.namelen + 1];
                        struct ext2fs_node *fdiro;
@@ -1920,8 +1929,9 @@ int ext4fs_iterate_dir(struct ext2fs_node *dir, char *name,
                        status = ext4fs_read_file(diro,
                                                  fpos +
                                                  sizeof(struct ext2_dirent),
-                                                 dirent.namelen, filename);
-                       if (status < 1)
+                                                 dirent.namelen, filename,
+                                                 &actread);
+                       if (status < 0)
                                return 0;
 
                        fdiro = zalloc(sizeof(struct ext2fs_node));
@@ -2003,8 +2013,8 @@ int ext4fs_iterate_dir(struct ext2fs_node *dir, char *name,
                                        printf("< ? > ");
                                        break;
                                }
-                               printf("%10d %s\n",
-                                       __le32_to_cpu(fdiro->inode.size),
+                               printf("%10u %s\n",
+                                      __le32_to_cpu(fdiro->inode.size),
                                        filename);
                        }
                        free(fdiro);
@@ -2019,6 +2029,7 @@ static char *ext4fs_read_symlink(struct ext2fs_node *node)
        char *symlink;
        struct ext2fs_node *diro = node;
        int status;
+       loff_t actread;
 
        if (!diro->inode_read) {
                status = ext4fs_read_inode(diro->data, diro->ino, &diro->inode);
@@ -2035,8 +2046,8 @@ static char *ext4fs_read_symlink(struct ext2fs_node *node)
        } else {
                status = ext4fs_read_file(diro, 0,
                                           __le32_to_cpu(diro->inode.size),
-                                          symlink);
-               if (status == 0) {
+                                          symlink, &actread);
+               if ((status < 0) || (actread == 0)) {
                        free(symlink);
                        return 0;
                }
@@ -2169,11 +2180,10 @@ int ext4fs_find_file(const char *path, struct ext2fs_node *rootnode,
        return 1;
 }
 
-int ext4fs_open(const char *filename)
+int ext4fs_open(const char *filename, loff_t *len)
 {
        struct ext2fs_node *fdiro = NULL;
        int status;
-       int len;
 
        if (ext4fs_root == NULL)
                return -1;
@@ -2190,10 +2200,10 @@ int ext4fs_open(const char *filename)
                if (status == 0)
                        goto fail;
        }
-       len = __le32_to_cpu(fdiro->inode.size);
+       *len = __le32_to_cpu(fdiro->inode.size);
        ext4fs_file = fdiro;
 
-       return len;
+       return 0;
 fail:
        ext4fs_free_node(fdiro, &ext4fs_root->diropen);