]> git.kernelconcepts.de Git - karo-tx-uboot.git/blobdiff - fs/ext4/ext4_common.c
fs/ext4: Support device block sizes != 512 bytes
[karo-tx-uboot.git] / fs / ext4 / ext4_common.c
index d6d55b9fff3707f1d9d8e47a4a4d12e89375f5f5..58880b467fbf678e029e793d1e26811675adf70e 100644 (file)
@@ -56,7 +56,7 @@ int ext4fs_indir3_blkno = -1;
 struct ext2_inode *g_parent_inode;
 static int symlinknest;
 
-#if defined(CONFIG_CMD_EXT4_WRITE)
+#if defined(CONFIG_EXT4_WRITE)
 uint32_t ext4fs_div_roundup(uint32_t size, uint32_t n)
 {
        uint32_t res = size / n;
@@ -71,18 +71,18 @@ void put_ext4(uint64_t off, void *buf, uint32_t size)
        uint64_t startblock;
        uint64_t remainder;
        unsigned char *temp_ptr = NULL;
-       ALLOC_CACHE_ALIGN_BUFFER(unsigned char, sec_buf, SECTOR_SIZE);
        struct ext_filesystem *fs = get_fs();
+       int log2blksz = fs->dev_desc->log2blksz;
+       ALLOC_CACHE_ALIGN_BUFFER(unsigned char, sec_buf, fs->dev_desc->blksz);
 
-       startblock = off / (uint64_t)SECTOR_SIZE;
+       startblock = off >> log2blksz;
        startblock += part_offset;
-       remainder = off % (uint64_t)SECTOR_SIZE;
-       remainder &= SECTOR_SIZE - 1;
+       remainder = off & (uint64_t)(fs->dev_desc->blksz - 1);
 
        if (fs->dev_desc == NULL)
                return;
 
-       if ((startblock + (size / SECTOR_SIZE)) >
+       if ((startblock + (size >> log2blksz)) >
            (part_offset + fs->total_sect)) {
                printf("part_offset is %lu\n", part_offset);
                printf("total_sector is %llu\n", fs->total_sect);
@@ -101,10 +101,10 @@ void put_ext4(uint64_t off, void *buf, uint32_t size)
                                                  startblock, 1, sec_buf);
                }
        } else {
-               if (size / SECTOR_SIZE != 0) {
+               if (size >> log2blksz != 0) {
                        fs->dev_desc->block_write(fs->dev_desc->dev,
                                                  startblock,
-                                                 size / SECTOR_SIZE,
+                                                 size >> log2blksz,
                                                  (unsigned long *)buf);
                } else {
                        fs->dev_desc->block_read(fs->dev_desc->dev,
@@ -378,7 +378,6 @@ void ext4fs_update_parent_dentry(char *filename, int *p_ino, int file_type)
        struct ext_filesystem *fs = get_fs();
        /* directory entry */
        struct ext2_dirent *dir;
-       char *ptr = NULL;
        char *temp_dir = NULL;
 
        zero_buffer = zalloc(fs->blksz);
@@ -415,7 +414,6 @@ restart:
        if (ext4fs_log_journal(root_first_block_buffer, first_block_no_of_root))
                goto fail;
        dir = (struct ext2_dirent *)root_first_block_buffer;
-       ptr = (char *)dir;
        totalbytes = 0;
        while (dir->direntlen > 0) {
                /*
@@ -483,14 +481,12 @@ restart:
                        break;
 
                dir = (struct ext2_dirent *)((char *)dir + templength);
-               ptr = (char *)dir;
        }
 
        /* make a pointer ready for creating next directory entry */
        templength = dir->direntlen;
        totalbytes = totalbytes + templength;
        dir = (struct ext2_dirent *)((char *)dir + templength);
-       ptr = (char *)dir;
 
        /* get the next available inode number */
        inodeno = ext4fs_get_new_inode_no();
@@ -1200,6 +1196,11 @@ static void alloc_double_indirect_block(struct ext2_inode *file_inode,
                status = ext4fs_devread(di_blockno_parent *
                                        fs->sect_perblk, 0,
                                        fs->blksz, (char *)di_parent_buffer);
+
+               if (!status) {
+                       printf("%s: Device read error!\n", __func__);
+                       goto fail;
+               }
                memset(di_parent_buffer, '\0', fs->blksz);
 
                /*
@@ -1227,6 +1228,11 @@ static void alloc_double_indirect_block(struct ext2_inode *file_inode,
                                                fs->sect_perblk, 0,
                                                fs->blksz,
                                                (char *)di_child_buff);
+
+                       if (!status) {
+                               printf("%s: Device read error!\n", __func__);
+                               goto fail;
+                       }
                        memset(di_child_buff, '\0', fs->blksz);
                        /* filling of actual datablocks for each child */
                        for (j = 0; j < (fs->blksz / sizeof(int)); j++) {
@@ -1453,6 +1459,7 @@ static int ext4fs_blockgroup
 {
        long int blkno;
        unsigned int blkoff, desc_per_blk;
+       int log2blksz = get_fs()->dev_desc->log2blksz;
 
        desc_per_blk = EXT2_BLOCK_SIZE(data) / sizeof(struct ext2_block_group);
 
@@ -1463,7 +1470,7 @@ static int ext4fs_blockgroup
        debug("ext4fs read %d group descriptor (blkno %ld blkoff %u)\n",
              group, blkno, blkoff);
 
-       return ext4fs_devread(blkno << LOG2_EXT2_BLOCK_SIZE(data),
+       return ext4fs_devread(blkno << (LOG2_BLOCK_SIZE(data) - log2blksz),
                              blkoff, sizeof(struct ext2_block_group),
                              (char *)blkgrp);
 }
@@ -1473,6 +1480,7 @@ int ext4fs_read_inode(struct ext2_data *data, int ino, struct ext2_inode *inode)
        struct ext2_block_group blkgrp;
        struct ext2_sblock *sblock = &data->sblock;
        struct ext_filesystem *fs = get_fs();
+       int log2blksz = get_fs()->dev_desc->log2blksz;
        int inodes_per_block, status;
        long int blkno;
        unsigned int blkoff;
@@ -1489,7 +1497,8 @@ int ext4fs_read_inode(struct ext2_data *data, int ino, struct ext2_inode *inode)
            (ino % __le32_to_cpu(sblock->inodes_per_group)) / inodes_per_block;
        blkoff = (ino % inodes_per_block) * fs->inodesz;
        /* Read the inode. */
-       status = ext4fs_devread(blkno << LOG2_EXT2_BLOCK_SIZE(data), blkoff,
+       status = ext4fs_devread(blkno << (LOG2_BLOCK_SIZE(data) - log2blksz),
+                               blkoff,
                                sizeof(struct ext2_inode), (char *)inode);
        if (status == 0)
                return 0;
@@ -1509,7 +1518,9 @@ long int read_allocated_block(struct ext2_inode *inode, int fileblock)
        unsigned long long start;
        /* get the blocksize of the filesystem */
        blksz = EXT2_BLOCK_SIZE(ext4fs_root);
-       log2_blksz = LOG2_EXT2_BLOCK_SIZE(ext4fs_root);
+       log2_blksz = LOG2_BLOCK_SIZE(ext4fs_root)
+               - get_fs()->dev_desc->log2blksz;
+
        if (le32_to_cpu(inode->flags) & EXT4_EXTENTS_FL) {
                char *buf = zalloc(blksz);
                if (!buf)
@@ -1517,11 +1528,11 @@ long int read_allocated_block(struct ext2_inode *inode, int fileblock)
                struct ext4_extent_header *ext_block;
                struct ext4_extent *extent;
                int i = -1;
-               ext_block = ext4fs_get_extent_block(ext4fs_root, buf,
-                                                   (struct ext4_extent_header
-                                                    *)inode->b.
-                                                   blocks.dir_blocks,
-                                                   fileblock, log2_blksz);
+               ext_block =
+                       ext4fs_get_extent_block(ext4fs_root, buf,
+                                               (struct ext4_extent_header *)
+                                               inode->b.blocks.dir_blocks,
+                                               fileblock, log2_blksz);
                if (!ext_block) {
                        printf("invalid extent block\n");
                        free(buf);
@@ -1833,7 +1844,7 @@ long int read_allocated_block(struct ext2_inode *inode, int fileblock)
                blknr = __le32_to_cpu(ext4fs_indir3_block
                                      [rblock % perblock_child]);
        }
-       debug("ext4fs_read_block %ld\n", blknr);
+       debug("read_allocated_block %ld\n", blknr);
 
        return blknr;
 }
@@ -2187,13 +2198,12 @@ int ext4fs_mount(unsigned part_length)
        struct ext2_data *data;
        int status;
        struct ext_filesystem *fs = get_fs();
-       data = zalloc(sizeof(struct ext2_data));
+       data = zalloc(SUPERBLOCK_SIZE);
        if (!data)
                return 0;
 
        /* Read the superblock. */
-       status = ext4fs_devread(1 * 2, 0, sizeof(struct ext2_sblock),
-                               (char *)&data->sblock);
+       status = ext4_read_superblock((char *)&data->sblock);
 
        if (status == 0)
                goto fail;