summaryrefslogtreecommitdiff
path: root/fs/ext4/ext4_common.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ext4/ext4_common.c')
-rw-r--r--fs/ext4/ext4_common.c45
1 files changed, 27 insertions, 18 deletions
diff --git a/fs/ext4/ext4_common.c b/fs/ext4/ext4_common.c
index 67e2471bd3..29308e3b44 100644
--- a/fs/ext4/ext4_common.c
+++ b/fs/ext4/ext4_common.c
@@ -510,7 +510,8 @@ restart:
restart_read:
/* read the block no allocated to a file */
- first_block_no_of_root = read_allocated_block(g_parent_inode, blk_idx);
+ first_block_no_of_root = read_allocated_block(g_parent_inode, blk_idx,
+ NULL);
if (first_block_no_of_root <= 0)
goto fail;
@@ -646,7 +647,7 @@ static int search_dir(struct ext2_inode *parent_inode, char *dirname)
/* get the block no allocated to a file */
for (blk_idx = 0; blk_idx < directory_blocks; blk_idx++) {
- blknr = read_allocated_block(parent_inode, blk_idx);
+ blknr = read_allocated_block(parent_inode, blk_idx, NULL);
if (blknr <= 0)
goto fail;
@@ -943,7 +944,7 @@ int ext4fs_filename_unlink(char *filename)
/* read the block no allocated to a file */
for (blk_idx = 0; blk_idx < directory_blocks; blk_idx++) {
- blknr = read_allocated_block(g_parent_inode, blk_idx);
+ blknr = read_allocated_block(g_parent_inode, blk_idx, NULL);
if (blknr <= 0)
break;
inodeno = unlink_filename(filename, blknr);
@@ -1522,7 +1523,7 @@ void ext4fs_allocate_blocks(struct ext2_inode *file_inode,
#endif
static struct ext4_extent_header *ext4fs_get_extent_block
- (struct ext2_data *data, char *buf,
+ (struct ext2_data *data, struct ext_block_cache *cache,
struct ext4_extent_header *ext_block,
uint32_t fileblock, int log2_blksz)
{
@@ -1551,12 +1552,10 @@ static struct ext4_extent_header *ext4fs_get_extent_block
block = le16_to_cpu(index[i].ei_leaf_hi);
block = (block << 32) + le32_to_cpu(index[i].ei_leaf_lo);
-
- if (ext4fs_devread((lbaint_t)block << log2_blksz, 0, blksz,
- buf))
- ext_block = (struct ext4_extent_header *)buf;
- else
+ block <<= log2_blksz;
+ if (!ext_cache_read(cache, (lbaint_t)block, blksz))
return NULL;
+ ext_block = (struct ext4_extent_header *)cache->buf;
}
}
@@ -1613,7 +1612,8 @@ int ext4fs_read_inode(struct ext2_data *data, int ino, struct ext2_inode *inode)
return 1;
}
-long int read_allocated_block(struct ext2_inode *inode, int fileblock)
+long int read_allocated_block(struct ext2_inode *inode, int fileblock,
+ struct ext_block_cache *cache)
{
long int blknr;
int blksz;
@@ -1630,20 +1630,26 @@ long int read_allocated_block(struct ext2_inode *inode, int fileblock)
if (le32_to_cpu(inode->flags) & EXT4_EXTENTS_FL) {
long int startblock, endblock;
- char *buf = zalloc(blksz);
- if (!buf)
- return -ENOMEM;
+ struct ext_block_cache *c, cd;
struct ext4_extent_header *ext_block;
struct ext4_extent *extent;
int i;
+
+ if (cache) {
+ c = cache;
+ } else {
+ c = &cd;
+ ext_cache_init(c);
+ }
ext_block =
- ext4fs_get_extent_block(ext4fs_root, buf,
+ ext4fs_get_extent_block(ext4fs_root, c,
(struct ext4_extent_header *)
inode->b.blocks.dir_blocks,
fileblock, log2_blksz);
if (!ext_block) {
printf("invalid extent block\n");
- free(buf);
+ if (!cache)
+ ext_cache_fini(c);
return -EINVAL;
}
@@ -1655,19 +1661,22 @@ long int read_allocated_block(struct ext2_inode *inode, int fileblock)
if (startblock > fileblock) {
/* Sparse file */
- free(buf);
+ if (!cache)
+ ext_cache_fini(c);
return 0;
} else if (fileblock < endblock) {
start = le16_to_cpu(extent[i].ee_start_hi);
start = (start << 32) +
le32_to_cpu(extent[i].ee_start_lo);
- free(buf);
+ if (!cache)
+ ext_cache_fini(c);
return (fileblock - startblock) + start;
}
}
- free(buf);
+ if (!cache)
+ ext_cache_fini(c);
return 0;
}