ANDROID: Incremental fs: Optimize get_filled_block
This led to a 20x speed improvement on QEMU. 512 is somewhat
arbitrary - most of the gains are already there reading 64 records
at a time, but since the record size is 10 bytes, 512 is just over
a page and seems a good choice.
Bug: 153170997
Test: incfs_test passes. Adding logging to incfs_get_filled_blocks
to measure performance shows a 20x improvement
Signed-off-by: Paul Lawrence <paullawrence@google.com>
Change-Id: Ifb2da77cfd8c9d653c7047ba1eb7f39d795fa1c2
Git-commit: 5128381d88
Git-repo: https://android.googlesource.com/kernel/common/
Signed-off-by: Sayali Lokhande <sayalil@codeaurora.org>
This commit is contained in:
committed by
Blagovest Kolenichev
parent
5663542e52
commit
aae486b462
@@ -347,13 +347,28 @@ static bool is_data_block_present(struct data_file_block *block)
|
||||
(block->db_stored_size != 0);
|
||||
}
|
||||
|
||||
static void convert_data_file_block(struct incfs_blockmap_entry *bme,
|
||||
struct data_file_block *res_block)
|
||||
{
|
||||
u16 flags = le16_to_cpu(bme->me_flags);
|
||||
|
||||
res_block->db_backing_file_data_offset =
|
||||
le16_to_cpu(bme->me_data_offset_hi);
|
||||
res_block->db_backing_file_data_offset <<= 32;
|
||||
res_block->db_backing_file_data_offset |=
|
||||
le32_to_cpu(bme->me_data_offset_lo);
|
||||
res_block->db_stored_size = le16_to_cpu(bme->me_data_size);
|
||||
res_block->db_comp_alg = (flags & INCFS_BLOCK_COMPRESSED_LZ4) ?
|
||||
COMPRESSION_LZ4 :
|
||||
COMPRESSION_NONE;
|
||||
}
|
||||
|
||||
static int get_data_file_block(struct data_file *df, int index,
|
||||
struct data_file_block *res_block)
|
||||
{
|
||||
struct incfs_blockmap_entry bme = {};
|
||||
struct backing_file_context *bfc = NULL;
|
||||
loff_t blockmap_off = 0;
|
||||
u16 flags = 0;
|
||||
int error = 0;
|
||||
|
||||
if (!df || !res_block)
|
||||
@@ -369,16 +384,7 @@ static int get_data_file_block(struct data_file *df, int index,
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
flags = le16_to_cpu(bme.me_flags);
|
||||
res_block->db_backing_file_data_offset =
|
||||
le16_to_cpu(bme.me_data_offset_hi);
|
||||
res_block->db_backing_file_data_offset <<= 32;
|
||||
res_block->db_backing_file_data_offset |=
|
||||
le32_to_cpu(bme.me_data_offset_lo);
|
||||
res_block->db_stored_size = le16_to_cpu(bme.me_data_size);
|
||||
res_block->db_comp_alg = (flags & INCFS_BLOCK_COMPRESSED_LZ4) ?
|
||||
COMPRESSION_LZ4 :
|
||||
COMPRESSION_NONE;
|
||||
convert_data_file_block(&bme, res_block);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -432,6 +438,7 @@ static int update_file_header_flags(struct data_file *df, u32 bits_to_reset,
|
||||
return result;
|
||||
}
|
||||
|
||||
#define READ_BLOCKMAP_ENTRIES 512
|
||||
int incfs_get_filled_blocks(struct data_file *df,
|
||||
struct incfs_get_filled_blocks_args *arg)
|
||||
{
|
||||
@@ -443,6 +450,9 @@ int incfs_get_filled_blocks(struct data_file *df,
|
||||
u32 end_index =
|
||||
arg->end_index ? arg->end_index : df->df_total_block_count;
|
||||
u32 *size_out = &arg->range_buffer_size_out;
|
||||
int i = READ_BLOCKMAP_ENTRIES - 1;
|
||||
int entries_read = 0;
|
||||
struct incfs_blockmap_entry *bme;
|
||||
|
||||
*size_out = 0;
|
||||
if (end_index > df->df_total_block_count)
|
||||
@@ -474,13 +484,33 @@ int incfs_get_filled_blocks(struct data_file *df,
|
||||
return 0;
|
||||
}
|
||||
|
||||
bme = kzalloc(sizeof(*bme) * READ_BLOCKMAP_ENTRIES, GFP_NOFS);
|
||||
if (!bme)
|
||||
return -ENOMEM;
|
||||
|
||||
for (arg->index_out = arg->start_index; arg->index_out < end_index;
|
||||
++arg->index_out) {
|
||||
struct data_file_block dfb;
|
||||
|
||||
error = get_data_file_block(df, arg->index_out, &dfb);
|
||||
if (error)
|
||||
if (++i == READ_BLOCKMAP_ENTRIES) {
|
||||
entries_read = incfs_read_blockmap_entries(
|
||||
df->df_backing_file_context, bme,
|
||||
arg->index_out, READ_BLOCKMAP_ENTRIES,
|
||||
df->df_blockmap_off);
|
||||
if (entries_read < 0) {
|
||||
error = entries_read;
|
||||
break;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
}
|
||||
|
||||
if (i >= entries_read) {
|
||||
error = -EIO;
|
||||
break;
|
||||
}
|
||||
|
||||
convert_data_file_block(bme + i, &dfb);
|
||||
|
||||
if (is_data_block_present(&dfb) == in_range)
|
||||
continue;
|
||||
@@ -520,6 +550,7 @@ int incfs_get_filled_blocks(struct data_file *df,
|
||||
pr_debug("Marked file full with result %d", result);
|
||||
}
|
||||
|
||||
kfree(bme);
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
@@ -514,8 +514,19 @@ int incfs_read_blockmap_entry(struct backing_file_context *bfc, int block_index,
|
||||
loff_t bm_base_off,
|
||||
struct incfs_blockmap_entry *bm_entry)
|
||||
{
|
||||
return incfs_read_blockmap_entries(bfc, bm_entry, block_index, 1,
|
||||
bm_base_off);
|
||||
int error = incfs_read_blockmap_entries(bfc, bm_entry, block_index, 1,
|
||||
bm_base_off);
|
||||
|
||||
if (error < 0)
|
||||
return error;
|
||||
|
||||
if (error == 0)
|
||||
return -EIO;
|
||||
|
||||
if (error != 1)
|
||||
return -EFAULT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int incfs_read_blockmap_entries(struct backing_file_context *bfc,
|
||||
@@ -539,9 +550,7 @@ int incfs_read_blockmap_entries(struct backing_file_context *bfc,
|
||||
bm_entry_off);
|
||||
if (result < 0)
|
||||
return result;
|
||||
if (result < bytes_to_read)
|
||||
return -EIO;
|
||||
return 0;
|
||||
return result / sizeof(*entries);
|
||||
}
|
||||
|
||||
int incfs_read_file_header(struct backing_file_context *bfc,
|
||||
|
||||
Reference in New Issue
Block a user