diff options
author | Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp> | 2010-07-17 21:42:26 -0400 |
---|---|---|
committer | Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp> | 2010-07-22 21:02:16 -0400 |
commit | 03bdb5ac58a2144dfe8cfd73347fdb9f57e2e062 (patch) | |
tree | 1ac37bb7c8020a2cf40ff5d8996d51725b190e8d /fs | |
parent | 4e13e66bee2d792c1aae21797f16c181024834eb (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>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/nilfs2/btree.c | 50 |
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 | ||
505 | static int nilfs_btree_do_lookup(const struct nilfs_bmap *btree, | 505 | static 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; |