ext4: make xattr inode reads faster
ext4_xattr_inode_read() currently reads each block sequentially while waiting for io operation to complete before moving on to the next block. This prevents request merging in block layer. Add a ext4_bread_batch() function that starts reads for all blocks then optionally waits for them to complete. A similar logic is used in ext4_find_entry(), so update that code to use the new function. Signed-off-by: Tahsin Erdogan <tahsin@google.com> Signed-off-by: Theodore Ts'o <tytso@mit.edu>
This commit is contained in:

committed by
Theodore Ts'o

parent
ec00022030
commit
9699d4f91d
@@ -1342,13 +1342,12 @@ static struct buffer_head * ext4_find_entry (struct inode *dir,
|
||||
struct super_block *sb;
|
||||
struct buffer_head *bh_use[NAMEI_RA_SIZE];
|
||||
struct buffer_head *bh, *ret = NULL;
|
||||
ext4_lblk_t start, block, b;
|
||||
ext4_lblk_t start, block;
|
||||
const u8 *name = d_name->name;
|
||||
int ra_max = 0; /* Number of bh's in the readahead
|
||||
size_t ra_max = 0; /* Number of bh's in the readahead
|
||||
buffer, bh_use[] */
|
||||
int ra_ptr = 0; /* Current index into readahead
|
||||
size_t ra_ptr = 0; /* Current index into readahead
|
||||
buffer */
|
||||
int num = 0;
|
||||
ext4_lblk_t nblocks;
|
||||
int i, namelen, retval;
|
||||
struct ext4_filename fname;
|
||||
@@ -1411,31 +1410,17 @@ restart:
|
||||
if (ra_ptr >= ra_max) {
|
||||
/* Refill the readahead buffer */
|
||||
ra_ptr = 0;
|
||||
b = block;
|
||||
for (ra_max = 0; ra_max < NAMEI_RA_SIZE; ra_max++) {
|
||||
/*
|
||||
* Terminate if we reach the end of the
|
||||
* directory and must wrap, or if our
|
||||
* search has finished at this block.
|
||||
*/
|
||||
if (b >= nblocks || (num && block == start)) {
|
||||
bh_use[ra_max] = NULL;
|
||||
break;
|
||||
}
|
||||
num++;
|
||||
bh = ext4_getblk(NULL, dir, b++, 0);
|
||||
if (IS_ERR(bh)) {
|
||||
if (ra_max == 0) {
|
||||
ret = bh;
|
||||
goto cleanup_and_exit;
|
||||
}
|
||||
break;
|
||||
}
|
||||
bh_use[ra_max] = bh;
|
||||
if (bh)
|
||||
ll_rw_block(REQ_OP_READ,
|
||||
REQ_META | REQ_PRIO,
|
||||
1, &bh);
|
||||
if (block < start)
|
||||
ra_max = start - block;
|
||||
else
|
||||
ra_max = nblocks - block;
|
||||
ra_max = min(ra_max, ARRAY_SIZE(bh_use));
|
||||
retval = ext4_bread_batch(dir, block, ra_max,
|
||||
false /* wait */, bh_use);
|
||||
if (retval) {
|
||||
ret = ERR_PTR(retval);
|
||||
ra_max = 0;
|
||||
goto cleanup_and_exit;
|
||||
}
|
||||
}
|
||||
if ((bh = bh_use[ra_ptr++]) == NULL)
|
||||
|
Reference in New Issue
Block a user