1
0
Fork 0

Revert "ext4fs: Add ext4 extent cache for read operations"

This reverts commit fc0fc50f38.

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>
utp
Tom Rini 2014-02-26 08:18:58 -05:00
parent a7e8c15f71
commit 715b56fe2b
3 changed files with 74 additions and 131 deletions

View 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,100 +1407,43 @@ void ext4fs_allocate_blocks(struct ext2_inode *file_inode,
#endif
static void ext4fs_extent_cache_insert(struct ext4_extent_node *new)
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)
{
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)
{
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;
if (ext4fs_devread((lbaint_t)block << log2_blksz, 0, blksz,
buf))
ext_block = (struct ext4_extent_header *)buf;
else
return 0;
}
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);
}
}
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
@ -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;
node = ext4fs_extent_cache_get(fileblock);
if (!node) {
printf("Extent Error\n");
return -1;
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;
}
return fileblock - node->block + node->start;
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;
}
printf("Extent Error\n");
free(buf);
return -1;
}
/* Direct blocks. */

View 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);

View 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;
}