Revert "ext4fs: Add ext4 extent cache for read operations"
authorTom Rini <trini@ti.com>
Wed, 26 Feb 2014 13:18:58 +0000 (08:18 -0500)
committerTom Rini <trini@ti.com>
Wed, 26 Feb 2014 13:18:58 +0000 (08:18 -0500)
This reverts commit fc0fc50f38a4d7d0554558076a79dfe8b0d78cd5.

The author has asked on the mailing list that we revert this for now as
it breaks write support.

Reported-by: Ɓukasz Majewski <l.majewski@samsung.com>
Signed-off-by: Tom Rini <trini@ti.com>
fs/ext4/ext4_common.c
fs/ext4/ext4_common.h
fs/ext4/ext4fs.c

index 6584892..02da75c 100644 (file)
@@ -26,7 +26,6 @@
 #include <stddef.h>
 #include <linux/stat.h>
 #include <linux/time.h>
-#include <linux/list.h>
 #include <asm/byteorder.h>
 #include "ext4_common.h"
 
@@ -45,14 +44,6 @@ int ext4fs_indir3_blkno = -1;
 struct ext2_inode *g_parent_inode;
 static int symlinknest;
 
-struct ext4_extent_node {
-       uint32_t block;
-       uint16_t len;
-       uint64_t start;
-       struct list_head lh;
-};
-static LIST_HEAD(ext4_extent_lh);
-
 #if defined(CONFIG_EXT4_WRITE)
 uint32_t ext4fs_div_roundup(uint32_t size, uint32_t n)
 {
@@ -1416,102 +1407,45 @@ void ext4fs_allocate_blocks(struct ext2_inode *file_inode,
 
 #endif
 
-static void ext4fs_extent_cache_insert(struct ext4_extent_node *new)
-{
-       struct ext4_extent_node *node;
-
-       list_for_each_entry(node, &ext4_extent_lh, lh)
-               if (node->block > new->block) {
-                       list_add_tail(&new->lh, &node->lh);
-                       return;
-               }
-       list_add_tail(&new->lh, &ext4_extent_lh);
-}
-
-static int __ext4fs_build_extent_cache(struct ext2_data *data,
-               struct ext4_extent_header *ext_block)
+static struct ext4_extent_header *ext4fs_get_extent_block
+       (struct ext2_data *data, char *buf,
+               struct ext4_extent_header *ext_block,
+               uint32_t fileblock, int log2_blksz)
 {
-       int blksz = EXT2_BLOCK_SIZE(data);
-       int log2_blksz = LOG2_BLOCK_SIZE(data)
-               - get_fs()->dev_desc->log2blksz;
-       struct ext4_extent_node *node;
        struct ext4_extent_idx *index;
-       struct ext4_extent *extent;
        unsigned long long block;
-       char *buf;
-       int i, err;
+       int blksz = EXT2_BLOCK_SIZE(data);
+       int i;
 
-       if (le16_to_cpu(ext_block->eh_magic) != EXT4_EXT_MAGIC)
-               return -EINVAL;
+       while (1) {
+               index = (struct ext4_extent_idx *)(ext_block + 1);
 
-       if (ext_block->eh_depth == 0) {
-               extent = (struct ext4_extent *)(ext_block + 1);
-               for (i = 0; i < le16_to_cpu(ext_block->eh_entries); i++) {
-                       node = malloc(sizeof(*node));
-                       if (!node)
-                               return -ENOMEM;
-                       node->block = le32_to_cpu(extent[i].ee_block);
-                       node->len = le16_to_cpu(extent[i].ee_len);
-                       node->start = le16_to_cpu(extent[i].ee_start_hi);
-                       node->start = (node->start << 32) +
-                               le32_to_cpu(extent[i].ee_start_lo);
-                       ext4fs_extent_cache_insert(node);
-               }
-               return 0;
-       }
+               if (le16_to_cpu(ext_block->eh_magic) != EXT4_EXT_MAGIC)
+                       return 0;
 
-       index = (struct ext4_extent_idx *)(ext_block + 1);
-       for (i = 0; i < le16_to_cpu(ext_block->eh_entries); i++) {
-               buf = malloc(blksz);
-               if (!buf)
-                       return -ENOMEM;
+               if (ext_block->eh_depth == 0)
+                       return ext_block;
+               i = -1;
+               do {
+                       i++;
+                       if (i >= le16_to_cpu(ext_block->eh_entries))
+                               break;
+               } while (fileblock >= le32_to_cpu(index[i].ei_block));
+
+               if (--i < 0)
+                       return 0;
 
                block = le16_to_cpu(index[i].ei_leaf_hi);
                block = (block << 32) + le32_to_cpu(index[i].ei_leaf_lo);
 
-               if (!ext4fs_devread(block << log2_blksz, 0, blksz, buf)) {
-                       free(buf);
-                       return -EIO;
-               }
-
-               err = __ext4fs_build_extent_cache(data,
-                               (struct ext4_extent_header *) buf);
-               free(buf);
-               if (err < 0)
-                       return err;
-       }
-
-       return 0;
-}
-
-int ext4fs_build_extent_cache(struct ext2_inode *inode)
-{
-       return __ext4fs_build_extent_cache(ext4fs_root,
-                       (struct ext4_extent_header *)
-                       inode->b.blocks.dir_blocks);
-}
-
-void ext4fs_free_extent_cache(void)
-{
-       struct ext4_extent_node *node, *tmp;
-
-       list_for_each_entry_safe(node, tmp, &ext4_extent_lh, lh) {
-               list_del(&node->lh);
-               free(node);
+               if (ext4fs_devread((lbaint_t)block << log2_blksz, 0, blksz,
+                                  buf))
+                       ext_block = (struct ext4_extent_header *)buf;
+               else
+                       return 0;
        }
 }
 
-static struct ext4_extent_node *ext4fs_extent_cache_get(uint32_t block)
-{
-       struct ext4_extent_node *node;
-
-       list_for_each_entry(node, &ext4_extent_lh, lh)
-               if (block >= node->block && block < node->block + node->len)
-                       return node;
-
-       return NULL;
-}
-
 static int ext4fs_blockgroup
        (struct ext2_data *data, int group, struct ext2_block_group *blkgrp)
 {
@@ -1574,22 +1508,54 @@ long int read_allocated_block(struct ext2_inode *inode, int fileblock)
        long int rblock;
        long int perblock_parent;
        long int perblock_child;
-
+       unsigned long long start;
        /* get the blocksize of the filesystem */
        blksz = 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) {
-               struct ext4_extent_node *node;
+               char *buf = zalloc(blksz);
+               if (!buf)
+                       return -ENOMEM;
+               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);
+               if (!ext_block) {
+                       printf("invalid extent block\n");
+                       free(buf);
+                       return -EINVAL;
+               }
 
-               node = ext4fs_extent_cache_get(fileblock);
-               if (!node) {
-                       printf("Extent Error\n");
-                       return -1;
+               extent = (struct ext4_extent *)(ext_block + 1);
+
+               do {
+                       i++;
+                       if (i >= le16_to_cpu(ext_block->eh_entries))
+                               break;
+               } while (fileblock >= le32_to_cpu(extent[i].ee_block));
+               if (--i >= 0) {
+                       fileblock -= le32_to_cpu(extent[i].ee_block);
+                       if (fileblock >= le16_to_cpu(extent[i].ee_len)) {
+                               free(buf);
+                               return 0;
+                       }
+
+                       start = le16_to_cpu(extent[i].ee_start_hi);
+                       start = (start << 32) +
+                                       le32_to_cpu(extent[i].ee_start_lo);
+                       free(buf);
+                       return fileblock + start;
                }
 
-               return fileblock - node->block + node->start;
+               printf("Extent Error\n");
+               free(buf);
+               return -1;
        }
 
        /* Direct blocks. */
index a9fd8c6..5fa1719 100644 (file)
@@ -57,9 +57,6 @@ int ext4fs_find_file(const char *path, struct ext2fs_node *rootnode,
 int ext4fs_iterate_dir(struct ext2fs_node *dir, char *name,
                        struct ext2fs_node **fnode, int *ftype);
 
-int ext4fs_build_extent_cache(struct ext2_inode *inode);
-void ext4fs_free_extent_cache(void);
-
 #if defined(CONFIG_EXT4_WRITE)
 uint32_t ext4fs_div_roundup(uint32_t size, uint32_t n);
 int ext4fs_checksum_update(unsigned int i);
index 4f1b4c8..417ce7b 100644 (file)
@@ -63,14 +63,6 @@ int ext4fs_read_file(struct ext2fs_node *node, int pos,
        char *delayed_buf = NULL;
        short status;
 
-       if (le32_to_cpu(node->inode.flags) & EXT4_EXTENTS_FL) {
-               if (ext4fs_build_extent_cache(&node->inode)) {
-                       printf("Error building extent cache!\n");
-                       len = -1;
-                       goto out_exit;
-               }
-       }
-
        /* Adjust len so it we can't read past the end of the file. */
        if (len > filesize)
                len = filesize;
@@ -83,10 +75,8 @@ int ext4fs_read_file(struct ext2fs_node *node, int pos,
                int blockend = blocksize;
                int skipfirst = 0;
                blknr = read_allocated_block(&(node->inode), i);
-               if (blknr < 0) {
-                       len = -1;
-                       goto out_exit;
-               }
+               if (blknr < 0)
+                       return -1;
 
                blknr = blknr << log2_fs_blocksize;
 
@@ -116,10 +106,8 @@ int ext4fs_read_file(struct ext2fs_node *node, int pos,
                                                        delayed_skipfirst,
                                                        delayed_extent,
                                                        delayed_buf);
-                                       if (status == 0) {
-                                               len = -1;
-                                               goto out_exit;
-                                       }
+                                       if (status == 0)
+                                               return -1;
                                        previous_block_number = blknr;
                                        delayed_start = blknr;
                                        delayed_extent = blockend;
@@ -144,10 +132,8 @@ int ext4fs_read_file(struct ext2fs_node *node, int pos,
                                                        delayed_skipfirst,
                                                        delayed_extent,
                                                        delayed_buf);
-                               if (status == 0) {
-                                       len = -1;
-                                       goto out_exit;
-                               }
+                               if (status == 0)
+                                       return -1;
                                previous_block_number = -1;
                        }
                        memset(buf, 0, blocksize - skipfirst);
@@ -159,17 +145,11 @@ int ext4fs_read_file(struct ext2fs_node *node, int pos,
                status = ext4fs_devread(delayed_start,
                                        delayed_skipfirst, delayed_extent,
                                        delayed_buf);
-               if (status == 0) {
-                       len = -1;
-                       goto out_exit;
-               }
+               if (status == 0)
+                       return -1;
                previous_block_number = -1;
        }
 
-
-out_exit:
-       ext4fs_free_extent_cache();
-
        return len;
 }