aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRyusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>2010-07-17 21:42:26 -0400
committerRyusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>2010-07-22 21:02:16 -0400
commit03bdb5ac58a2144dfe8cfd73347fdb9f57e2e062 (patch)
tree1ac37bb7c8020a2cf40ff5d8996d51725b190e8d
parent4e13e66bee2d792c1aae21797f16c181024834eb (diff)
nilfs2: apply read-ahead for nilfs_btree_lookup_contig
This applies read-ahead to nilfs_btree_do_lookup and nilfs_btree_lookup_contig functions and extends them to read ahead siblings of level 1 btree nodes that hold data blocks. At present, the read-ahead is not applied to most btree operations; only get_block() callback function, which is used during read of regular files or directories, receives the benefit. Signed-off-by: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
-rw-r--r--fs/nilfs2/btree.c50
1 files changed, 33 insertions, 17 deletions
diff --git a/fs/nilfs2/btree.c b/fs/nilfs2/btree.c
index d3faa0bba171..300c2bc00c3f 100644
--- a/fs/nilfs2/btree.c
+++ b/fs/nilfs2/btree.c
@@ -504,9 +504,11 @@ static int nilfs_btree_get_block(const struct nilfs_bmap *btree, __u64 ptr,
504 504
505static int nilfs_btree_do_lookup(const struct nilfs_bmap *btree, 505static int nilfs_btree_do_lookup(const struct nilfs_bmap *btree,
506 struct nilfs_btree_path *path, 506 struct nilfs_btree_path *path,
507 __u64 key, __u64 *ptrp, int minlevel) 507 __u64 key, __u64 *ptrp, int minlevel,
508 int readahead)
508{ 509{
509 struct nilfs_btree_node *node; 510 struct nilfs_btree_node *node;
511 struct nilfs_btree_readahead_info p, *ra;
510 __u64 ptr; 512 __u64 ptr;
511 int level, index, found, ncmax, ret; 513 int level, index, found, ncmax, ret;
512 514
@@ -523,10 +525,20 @@ static int nilfs_btree_do_lookup(const struct nilfs_bmap *btree,
523 525
524 ncmax = nilfs_btree_nchildren_per_block(btree); 526 ncmax = nilfs_btree_nchildren_per_block(btree);
525 527
526 for (level--; level >= minlevel; level--) { 528 while (--level >= minlevel) {
527 ret = nilfs_btree_get_block(btree, ptr, &path[level].bp_bh); 529 ra = NULL;
530 if (level == NILFS_BTREE_LEVEL_NODE_MIN && readahead) {
531 p.node = nilfs_btree_get_node(btree, path, level + 1,
532 &p.ncmax);
533 p.index = index;
534 p.max_ra_blocks = 7;
535 ra = &p;
536 }
537 ret = __nilfs_btree_get_block(btree, ptr, &path[level].bp_bh,
538 ra);
528 if (ret < 0) 539 if (ret < 0)
529 return ret; 540 return ret;
541
530 node = nilfs_btree_get_nonroot_node(path, level); 542 node = nilfs_btree_get_nonroot_node(path, level);
531 if (nilfs_btree_bad_node(node, level)) 543 if (nilfs_btree_bad_node(node, level))
532 return -EINVAL; 544 return -EINVAL;
@@ -601,7 +613,7 @@ static int nilfs_btree_lookup(const struct nilfs_bmap *btree,
601 if (path == NULL) 613 if (path == NULL)
602 return -ENOMEM; 614 return -ENOMEM;
603 615
604 ret = nilfs_btree_do_lookup(btree, path, key, ptrp, level); 616 ret = nilfs_btree_do_lookup(btree, path, key, ptrp, level, 0);
605 617
606 nilfs_btree_free_path(path); 618 nilfs_btree_free_path(path);
607 619
@@ -618,12 +630,13 @@ static int nilfs_btree_lookup_contig(const struct nilfs_bmap *btree,
618 sector_t blocknr; 630 sector_t blocknr;
619 int level = NILFS_BTREE_LEVEL_NODE_MIN; 631 int level = NILFS_BTREE_LEVEL_NODE_MIN;
620 int ret, cnt, index, maxlevel, ncmax; 632 int ret, cnt, index, maxlevel, ncmax;
633 struct nilfs_btree_readahead_info p;
621 634
622 path = nilfs_btree_alloc_path(); 635 path = nilfs_btree_alloc_path();
623 if (path == NULL) 636 if (path == NULL)
624 return -ENOMEM; 637 return -ENOMEM;
625 638
626 ret = nilfs_btree_do_lookup(btree, path, key, &ptr, level); 639 ret = nilfs_btree_do_lookup(btree, path, key, &ptr, level, 1);
627 if (ret < 0) 640 if (ret < 0)
628 goto out; 641 goto out;
629 642
@@ -662,17 +675,20 @@ static int nilfs_btree_lookup_contig(const struct nilfs_bmap *btree,
662 break; 675 break;
663 676
664 /* look-up right sibling node */ 677 /* look-up right sibling node */
665 node = nilfs_btree_get_node(btree, path, level + 1, &ncmax); 678 p.node = nilfs_btree_get_node(btree, path, level + 1, &p.ncmax);
666 index = path[level + 1].bp_index + 1; 679 p.index = path[level + 1].bp_index + 1;
667 if (index >= nilfs_btree_node_get_nchildren(node) || 680 p.max_ra_blocks = 7;
668 nilfs_btree_node_get_key(node, index) != key + cnt) 681 if (p.index >= nilfs_btree_node_get_nchildren(p.node) ||
682 nilfs_btree_node_get_key(p.node, p.index) != key + cnt)
669 break; 683 break;
670 ptr2 = nilfs_btree_node_get_ptr(node, index, ncmax); 684 ptr2 = nilfs_btree_node_get_ptr(p.node, p.index, p.ncmax);
671 path[level + 1].bp_index = index; 685 path[level + 1].bp_index = p.index;
672 686
673 brelse(path[level].bp_bh); 687 brelse(path[level].bp_bh);
674 path[level].bp_bh = NULL; 688 path[level].bp_bh = NULL;
675 ret = nilfs_btree_get_block(btree, ptr2, &path[level].bp_bh); 689
690 ret = __nilfs_btree_get_block(btree, ptr2, &path[level].bp_bh,
691 &p);
676 if (ret < 0) 692 if (ret < 0)
677 goto out; 693 goto out;
678 node = nilfs_btree_get_nonroot_node(path, level); 694 node = nilfs_btree_get_nonroot_node(path, level);
@@ -1147,7 +1163,7 @@ static int nilfs_btree_insert(struct nilfs_bmap *btree, __u64 key, __u64 ptr)
1147 return -ENOMEM; 1163 return -ENOMEM;
1148 1164
1149 ret = nilfs_btree_do_lookup(btree, path, key, NULL, 1165 ret = nilfs_btree_do_lookup(btree, path, key, NULL,
1150 NILFS_BTREE_LEVEL_NODE_MIN); 1166 NILFS_BTREE_LEVEL_NODE_MIN, 0);
1151 if (ret != -ENOENT) { 1167 if (ret != -ENOENT) {
1152 if (ret == 0) 1168 if (ret == 0)
1153 ret = -EEXIST; 1169 ret = -EEXIST;
@@ -1484,7 +1500,7 @@ static int nilfs_btree_delete(struct nilfs_bmap *btree, __u64 key)
1484 return -ENOMEM; 1500 return -ENOMEM;
1485 1501
1486 ret = nilfs_btree_do_lookup(btree, path, key, NULL, 1502 ret = nilfs_btree_do_lookup(btree, path, key, NULL,
1487 NILFS_BTREE_LEVEL_NODE_MIN); 1503 NILFS_BTREE_LEVEL_NODE_MIN, 0);
1488 if (ret < 0) 1504 if (ret < 0)
1489 goto out; 1505 goto out;
1490 1506
@@ -1955,7 +1971,7 @@ static int nilfs_btree_propagate(struct nilfs_bmap *btree,
1955 level = NILFS_BTREE_LEVEL_DATA; 1971 level = NILFS_BTREE_LEVEL_DATA;
1956 } 1972 }
1957 1973
1958 ret = nilfs_btree_do_lookup(btree, path, key, NULL, level + 1); 1974 ret = nilfs_btree_do_lookup(btree, path, key, NULL, level + 1, 0);
1959 if (ret < 0) { 1975 if (ret < 0) {
1960 if (unlikely(ret == -ENOENT)) 1976 if (unlikely(ret == -ENOENT))
1961 printk(KERN_CRIT "%s: key = %llu, level == %d\n", 1977 printk(KERN_CRIT "%s: key = %llu, level == %d\n",
@@ -2147,7 +2163,7 @@ static int nilfs_btree_assign(struct nilfs_bmap *btree,
2147 level = NILFS_BTREE_LEVEL_DATA; 2163 level = NILFS_BTREE_LEVEL_DATA;
2148 } 2164 }
2149 2165
2150 ret = nilfs_btree_do_lookup(btree, path, key, NULL, level + 1); 2166 ret = nilfs_btree_do_lookup(btree, path, key, NULL, level + 1, 0);
2151 if (ret < 0) { 2167 if (ret < 0) {
2152 WARN_ON(ret == -ENOENT); 2168 WARN_ON(ret == -ENOENT);
2153 goto out; 2169 goto out;
@@ -2201,7 +2217,7 @@ static int nilfs_btree_mark(struct nilfs_bmap *btree, __u64 key, int level)
2201 if (path == NULL) 2217 if (path == NULL)
2202 return -ENOMEM; 2218 return -ENOMEM;
2203 2219
2204 ret = nilfs_btree_do_lookup(btree, path, key, &ptr, level + 1); 2220 ret = nilfs_btree_do_lookup(btree, path, key, &ptr, level + 1, 0);
2205 if (ret < 0) { 2221 if (ret < 0) {
2206 WARN_ON(ret == -ENOENT); 2222 WARN_ON(ret == -ENOENT);
2207 goto out; 2223 goto out;