diff options
| -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; |
