mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-24 21:54:01 +00:00
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>
This commit is contained in:
parent
a7e8c15f71
commit
715b56fe2b
3 changed files with 74 additions and 131 deletions
|
@ -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)
|
||||
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;
|
||||
|
||||
while (1) {
|
||||
index = (struct ext4_extent_idx *)(ext_block + 1);
|
||||
|
||||
if (le16_to_cpu(ext_block->eh_magic) != EXT4_EXT_MAGIC)
|
||||
return -EINVAL;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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
|
||||
(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;
|
||||
|
||||
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. */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue