mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-11 14:53:56 +08:00
nilfs2: add btree get block function with readahead option
This adds __nilfs_btree_get_block() function that can issue a series of read-ahead requests for sibling btree nodes. This read-ahead needs parent node block, so nilfs_btree_readahead_info structure is added to pass the information that __nilfs_btree_get_block() needs. This also replaces the previous nilfs_btree_get_block() implementation with a wrapper function of __nilfs_btree_get_block(). Signed-off-by: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
This commit is contained in:
parent
26dfdd8e29
commit
464ece8863
@ -66,32 +66,6 @@ static void nilfs_btree_free_path(struct nilfs_btree_path *path)
|
|||||||
/*
|
/*
|
||||||
* B-tree node operations
|
* B-tree node operations
|
||||||
*/
|
*/
|
||||||
static int nilfs_btree_get_block(const struct nilfs_bmap *btree, __u64 ptr,
|
|
||||||
struct buffer_head **bhp)
|
|
||||||
{
|
|
||||||
struct address_space *btnc = &NILFS_BMAP_I(btree)->i_btnode_cache;
|
|
||||||
struct buffer_head *bh;
|
|
||||||
sector_t pbn = 0;
|
|
||||||
int err;
|
|
||||||
|
|
||||||
err = nilfs_btnode_submit_block(btnc, ptr, pbn, READ, bhp, &pbn);
|
|
||||||
if (err)
|
|
||||||
return err == -EEXIST ? 0 : err;
|
|
||||||
|
|
||||||
bh = *bhp;
|
|
||||||
wait_on_buffer(bh);
|
|
||||||
if (!buffer_uptodate(bh)) {
|
|
||||||
brelse(bh);
|
|
||||||
return -EIO;
|
|
||||||
}
|
|
||||||
if (nilfs_btree_broken_node_block(bh)) {
|
|
||||||
clear_buffer_uptodate(bh);
|
|
||||||
brelse(bh);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int nilfs_btree_get_new_block(const struct nilfs_bmap *btree,
|
static int nilfs_btree_get_new_block(const struct nilfs_bmap *btree,
|
||||||
__u64 ptr, struct buffer_head **bhp)
|
__u64 ptr, struct buffer_head **bhp)
|
||||||
{
|
{
|
||||||
@ -452,6 +426,74 @@ nilfs_btree_bad_node(struct nilfs_btree_node *node, int level)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct nilfs_btree_readahead_info {
|
||||||
|
struct nilfs_btree_node *node; /* parent node */
|
||||||
|
int max_ra_blocks; /* max nof blocks to read ahead */
|
||||||
|
int index; /* current index on the parent node */
|
||||||
|
int ncmax; /* nof children in the parent node */
|
||||||
|
};
|
||||||
|
|
||||||
|
static int __nilfs_btree_get_block(const struct nilfs_bmap *btree, __u64 ptr,
|
||||||
|
struct buffer_head **bhp,
|
||||||
|
const struct nilfs_btree_readahead_info *ra)
|
||||||
|
{
|
||||||
|
struct address_space *btnc = &NILFS_BMAP_I(btree)->i_btnode_cache;
|
||||||
|
struct buffer_head *bh, *ra_bh;
|
||||||
|
sector_t submit_ptr = 0;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = nilfs_btnode_submit_block(btnc, ptr, 0, READ, &bh, &submit_ptr);
|
||||||
|
if (ret) {
|
||||||
|
if (ret != -EEXIST)
|
||||||
|
return ret;
|
||||||
|
goto out_check;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ra) {
|
||||||
|
int i, n;
|
||||||
|
__u64 ptr2;
|
||||||
|
|
||||||
|
/* read ahead sibling nodes */
|
||||||
|
for (n = ra->max_ra_blocks, i = ra->index + 1;
|
||||||
|
n > 0 && i < ra->ncmax; n--, i++) {
|
||||||
|
ptr2 = nilfs_btree_node_get_ptr(ra->node, i, ra->ncmax);
|
||||||
|
|
||||||
|
ret = nilfs_btnode_submit_block(btnc, ptr2, 0, READA,
|
||||||
|
&ra_bh, &submit_ptr);
|
||||||
|
if (likely(!ret || ret == -EEXIST))
|
||||||
|
brelse(ra_bh);
|
||||||
|
else if (ret != -EBUSY)
|
||||||
|
break;
|
||||||
|
if (!buffer_locked(bh))
|
||||||
|
goto out_no_wait;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
wait_on_buffer(bh);
|
||||||
|
|
||||||
|
out_no_wait:
|
||||||
|
if (!buffer_uptodate(bh)) {
|
||||||
|
brelse(bh);
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
out_check:
|
||||||
|
if (nilfs_btree_broken_node_block(bh)) {
|
||||||
|
clear_buffer_uptodate(bh);
|
||||||
|
brelse(bh);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
*bhp = bh;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int nilfs_btree_get_block(const struct nilfs_bmap *btree, __u64 ptr,
|
||||||
|
struct buffer_head **bhp)
|
||||||
|
{
|
||||||
|
return __nilfs_btree_get_block(btree, ptr, bhp, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
static int nilfs_btree_do_lookup(const struct nilfs_bmap *btree,
|
static int nilfs_btree_do_lookup(const struct nilfs_bmap *btree,
|
||||||
struct nilfs_btree_path *path,
|
struct nilfs_btree_path *path,
|
||||||
__u64 key, __u64 *ptrp, int minlevel)
|
__u64 key, __u64 *ptrp, int minlevel)
|
||||||
|
Loading…
Reference in New Issue
Block a user