aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorRyusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>2010-07-17 21:42:24 -0400
committerRyusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>2010-07-22 21:02:15 -0400
commit464ece88630d0fb715ca942eabb1da825046a534 (patch)
tree254185629ce58cf314c5b22b846969a3c26984ed /fs
parent26dfdd8e29f28c08aa67861b3c83d0f3f7d30cee (diff)
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>
Diffstat (limited to 'fs')
-rw-r--r--fs/nilfs2/btree.c94
1 files changed, 68 insertions, 26 deletions
diff --git a/fs/nilfs2/btree.c b/fs/nilfs2/btree.c
index 4669389bf686..1b5321c0bcac 100644
--- a/fs/nilfs2/btree.c
+++ b/fs/nilfs2/btree.c
@@ -66,32 +66,6 @@ static void nilfs_btree_free_path(struct nilfs_btree_path *path)
66/* 66/*
67 * B-tree node operations 67 * B-tree node operations
68 */ 68 */
69static int nilfs_btree_get_block(const struct nilfs_bmap *btree, __u64 ptr,
70 struct buffer_head **bhp)
71{
72 struct address_space *btnc = &NILFS_BMAP_I(btree)->i_btnode_cache;
73 struct buffer_head *bh;
74 sector_t pbn = 0;
75 int err;
76
77 err = nilfs_btnode_submit_block(btnc, ptr, pbn, READ, bhp, &pbn);
78 if (err)
79 return err == -EEXIST ? 0 : err;
80
81 bh = *bhp;
82 wait_on_buffer(bh);
83 if (!buffer_uptodate(bh)) {
84 brelse(bh);
85 return -EIO;
86 }
87 if (nilfs_btree_broken_node_block(bh)) {
88 clear_buffer_uptodate(bh);
89 brelse(bh);
90 return -EINVAL;
91 }
92 return 0;
93}
94
95static int nilfs_btree_get_new_block(const struct nilfs_bmap *btree, 69static int nilfs_btree_get_new_block(const struct nilfs_bmap *btree,
96 __u64 ptr, struct buffer_head **bhp) 70 __u64 ptr, struct buffer_head **bhp)
97{ 71{
@@ -452,6 +426,74 @@ nilfs_btree_bad_node(struct nilfs_btree_node *node, int level)
452 return 0; 426 return 0;
453} 427}
454 428
429struct nilfs_btree_readahead_info {
430 struct nilfs_btree_node *node; /* parent node */
431 int max_ra_blocks; /* max nof blocks to read ahead */
432 int index; /* current index on the parent node */
433 int ncmax; /* nof children in the parent node */
434};
435
436static int __nilfs_btree_get_block(const struct nilfs_bmap *btree, __u64 ptr,
437 struct buffer_head **bhp,
438 const struct nilfs_btree_readahead_info *ra)
439{
440 struct address_space *btnc = &NILFS_BMAP_I(btree)->i_btnode_cache;
441 struct buffer_head *bh, *ra_bh;
442 sector_t submit_ptr = 0;
443 int ret;
444
445 ret = nilfs_btnode_submit_block(btnc, ptr, 0, READ, &bh, &submit_ptr);
446 if (ret) {
447 if (ret != -EEXIST)
448 return ret;
449 goto out_check;
450 }
451
452 if (ra) {
453 int i, n;
454 __u64 ptr2;
455
456 /* read ahead sibling nodes */
457 for (n = ra->max_ra_blocks, i = ra->index + 1;
458 n > 0 && i < ra->ncmax; n--, i++) {
459 ptr2 = nilfs_btree_node_get_ptr(ra->node, i, ra->ncmax);
460
461 ret = nilfs_btnode_submit_block(btnc, ptr2, 0, READA,
462 &ra_bh, &submit_ptr);
463 if (likely(!ret || ret == -EEXIST))
464 brelse(ra_bh);
465 else if (ret != -EBUSY)
466 break;
467 if (!buffer_locked(bh))
468 goto out_no_wait;
469 }
470 }
471
472 wait_on_buffer(bh);
473
474 out_no_wait:
475 if (!buffer_uptodate(bh)) {
476 brelse(bh);
477 return -EIO;
478 }
479
480 out_check:
481 if (nilfs_btree_broken_node_block(bh)) {
482 clear_buffer_uptodate(bh);
483 brelse(bh);
484 return -EINVAL;
485 }
486
487 *bhp = bh;
488 return 0;
489}
490
491static int nilfs_btree_get_block(const struct nilfs_bmap *btree, __u64 ptr,
492 struct buffer_head **bhp)
493{
494 return __nilfs_btree_get_block(btree, ptr, bhp, NULL);
495}
496
455static int nilfs_btree_do_lookup(const struct nilfs_bmap *btree, 497static int nilfs_btree_do_lookup(const struct nilfs_bmap *btree,
456 struct nilfs_btree_path *path, 498 struct nilfs_btree_path *path,
457 __u64 key, __u64 *ptrp, int minlevel) 499 __u64 key, __u64 *ptrp, int minlevel)