diff options
Diffstat (limited to 'fs/nilfs2/btree.c')
| -rw-r--r-- | fs/nilfs2/btree.c | 91 |
1 files changed, 17 insertions, 74 deletions
diff --git a/fs/nilfs2/btree.c b/fs/nilfs2/btree.c index 76c38e3e19d2..b27a342c5af6 100644 --- a/fs/nilfs2/btree.c +++ b/fs/nilfs2/btree.c | |||
| @@ -31,63 +31,16 @@ | |||
| 31 | #include "alloc.h" | 31 | #include "alloc.h" |
| 32 | #include "dat.h" | 32 | #include "dat.h" |
| 33 | 33 | ||
| 34 | /** | 34 | static struct nilfs_btree_path *nilfs_btree_alloc_path(void) |
| 35 | * struct nilfs_btree_path - A path on which B-tree operations are executed | ||
| 36 | * @bp_bh: buffer head of node block | ||
| 37 | * @bp_sib_bh: buffer head of sibling node block | ||
| 38 | * @bp_index: index of child node | ||
| 39 | * @bp_oldreq: ptr end request for old ptr | ||
| 40 | * @bp_newreq: ptr alloc request for new ptr | ||
| 41 | * @bp_op: rebalance operation | ||
| 42 | */ | ||
| 43 | struct nilfs_btree_path { | ||
| 44 | struct buffer_head *bp_bh; | ||
| 45 | struct buffer_head *bp_sib_bh; | ||
| 46 | int bp_index; | ||
| 47 | union nilfs_bmap_ptr_req bp_oldreq; | ||
| 48 | union nilfs_bmap_ptr_req bp_newreq; | ||
| 49 | struct nilfs_btnode_chkey_ctxt bp_ctxt; | ||
| 50 | void (*bp_op)(struct nilfs_btree *, struct nilfs_btree_path *, | ||
| 51 | int, __u64 *, __u64 *); | ||
| 52 | }; | ||
| 53 | |||
| 54 | /* | ||
| 55 | * B-tree path operations | ||
| 56 | */ | ||
| 57 | |||
| 58 | static struct kmem_cache *nilfs_btree_path_cache; | ||
| 59 | |||
| 60 | int __init nilfs_btree_path_cache_init(void) | ||
| 61 | { | ||
| 62 | nilfs_btree_path_cache = | ||
| 63 | kmem_cache_create("nilfs2_btree_path_cache", | ||
| 64 | sizeof(struct nilfs_btree_path) * | ||
| 65 | NILFS_BTREE_LEVEL_MAX, 0, 0, NULL); | ||
| 66 | return (nilfs_btree_path_cache != NULL) ? 0 : -ENOMEM; | ||
| 67 | } | ||
| 68 | |||
| 69 | void nilfs_btree_path_cache_destroy(void) | ||
| 70 | { | ||
| 71 | kmem_cache_destroy(nilfs_btree_path_cache); | ||
| 72 | } | ||
| 73 | |||
| 74 | static inline struct nilfs_btree_path *nilfs_btree_alloc_path(void) | ||
| 75 | { | ||
| 76 | return kmem_cache_alloc(nilfs_btree_path_cache, GFP_NOFS); | ||
| 77 | } | ||
| 78 | |||
| 79 | static inline void nilfs_btree_free_path(struct nilfs_btree_path *path) | ||
| 80 | { | 35 | { |
| 81 | kmem_cache_free(nilfs_btree_path_cache, path); | 36 | struct nilfs_btree_path *path; |
| 82 | } | 37 | int level = NILFS_BTREE_LEVEL_DATA; |
| 83 | 38 | ||
| 84 | static void nilfs_btree_init_path(struct nilfs_btree_path *path) | 39 | path = kmem_cache_alloc(nilfs_btree_path_cache, GFP_NOFS); |
| 85 | { | 40 | if (path == NULL) |
| 86 | int level; | 41 | goto out; |
| 87 | 42 | ||
| 88 | for (level = NILFS_BTREE_LEVEL_DATA; | 43 | for (; level < NILFS_BTREE_LEVEL_MAX; level++) { |
| 89 | level < NILFS_BTREE_LEVEL_MAX; | ||
| 90 | level++) { | ||
| 91 | path[level].bp_bh = NULL; | 44 | path[level].bp_bh = NULL; |
| 92 | path[level].bp_sib_bh = NULL; | 45 | path[level].bp_sib_bh = NULL; |
| 93 | path[level].bp_index = 0; | 46 | path[level].bp_index = 0; |
| @@ -95,15 +48,19 @@ static void nilfs_btree_init_path(struct nilfs_btree_path *path) | |||
| 95 | path[level].bp_newreq.bpr_ptr = NILFS_BMAP_INVALID_PTR; | 48 | path[level].bp_newreq.bpr_ptr = NILFS_BMAP_INVALID_PTR; |
| 96 | path[level].bp_op = NULL; | 49 | path[level].bp_op = NULL; |
| 97 | } | 50 | } |
| 51 | |||
| 52 | out: | ||
| 53 | return path; | ||
| 98 | } | 54 | } |
| 99 | 55 | ||
| 100 | static void nilfs_btree_release_path(struct nilfs_btree_path *path) | 56 | static void nilfs_btree_free_path(struct nilfs_btree_path *path) |
| 101 | { | 57 | { |
| 102 | int level; | 58 | int level = NILFS_BTREE_LEVEL_DATA; |
| 103 | 59 | ||
| 104 | for (level = NILFS_BTREE_LEVEL_DATA; level < NILFS_BTREE_LEVEL_MAX; | 60 | for (; level < NILFS_BTREE_LEVEL_MAX; level++) |
| 105 | level++) | ||
| 106 | brelse(path[level].bp_bh); | 61 | brelse(path[level].bp_bh); |
| 62 | |||
| 63 | kmem_cache_free(nilfs_btree_path_cache, path); | ||
| 107 | } | 64 | } |
| 108 | 65 | ||
| 109 | /* | 66 | /* |
| @@ -566,14 +523,12 @@ static int nilfs_btree_lookup(const struct nilfs_bmap *bmap, | |||
| 566 | path = nilfs_btree_alloc_path(); | 523 | path = nilfs_btree_alloc_path(); |
| 567 | if (path == NULL) | 524 | if (path == NULL) |
| 568 | return -ENOMEM; | 525 | return -ENOMEM; |
| 569 | nilfs_btree_init_path(path); | ||
| 570 | 526 | ||
| 571 | ret = nilfs_btree_do_lookup(btree, path, key, &ptr, level); | 527 | ret = nilfs_btree_do_lookup(btree, path, key, &ptr, level); |
| 572 | 528 | ||
| 573 | if (ptrp != NULL) | 529 | if (ptrp != NULL) |
| 574 | *ptrp = ptr; | 530 | *ptrp = ptr; |
| 575 | 531 | ||
| 576 | nilfs_btree_release_path(path); | ||
| 577 | nilfs_btree_free_path(path); | 532 | nilfs_btree_free_path(path); |
| 578 | 533 | ||
| 579 | return ret; | 534 | return ret; |
| @@ -594,7 +549,7 @@ static int nilfs_btree_lookup_contig(const struct nilfs_bmap *bmap, | |||
| 594 | path = nilfs_btree_alloc_path(); | 549 | path = nilfs_btree_alloc_path(); |
| 595 | if (path == NULL) | 550 | if (path == NULL) |
| 596 | return -ENOMEM; | 551 | return -ENOMEM; |
| 597 | nilfs_btree_init_path(path); | 552 | |
| 598 | ret = nilfs_btree_do_lookup(btree, path, key, &ptr, level); | 553 | ret = nilfs_btree_do_lookup(btree, path, key, &ptr, level); |
| 599 | if (ret < 0) | 554 | if (ret < 0) |
| 600 | goto out; | 555 | goto out; |
| @@ -655,7 +610,6 @@ static int nilfs_btree_lookup_contig(const struct nilfs_bmap *bmap, | |||
| 655 | *ptrp = ptr; | 610 | *ptrp = ptr; |
| 656 | ret = cnt; | 611 | ret = cnt; |
| 657 | out: | 612 | out: |
| 658 | nilfs_btree_release_path(path); | ||
| 659 | nilfs_btree_free_path(path); | 613 | nilfs_btree_free_path(path); |
| 660 | return ret; | 614 | return ret; |
| 661 | } | 615 | } |
| @@ -1123,7 +1077,6 @@ static int nilfs_btree_insert(struct nilfs_bmap *bmap, __u64 key, __u64 ptr) | |||
| 1123 | path = nilfs_btree_alloc_path(); | 1077 | path = nilfs_btree_alloc_path(); |
| 1124 | if (path == NULL) | 1078 | if (path == NULL) |
| 1125 | return -ENOMEM; | 1079 | return -ENOMEM; |
| 1126 | nilfs_btree_init_path(path); | ||
| 1127 | 1080 | ||
| 1128 | ret = nilfs_btree_do_lookup(btree, path, key, NULL, | 1081 | ret = nilfs_btree_do_lookup(btree, path, key, NULL, |
| 1129 | NILFS_BTREE_LEVEL_NODE_MIN); | 1082 | NILFS_BTREE_LEVEL_NODE_MIN); |
| @@ -1140,7 +1093,6 @@ static int nilfs_btree_insert(struct nilfs_bmap *bmap, __u64 key, __u64 ptr) | |||
| 1140 | nilfs_bmap_add_blocks(bmap, stats.bs_nblocks); | 1093 | nilfs_bmap_add_blocks(bmap, stats.bs_nblocks); |
| 1141 | 1094 | ||
| 1142 | out: | 1095 | out: |
| 1143 | nilfs_btree_release_path(path); | ||
| 1144 | nilfs_btree_free_path(path); | 1096 | nilfs_btree_free_path(path); |
| 1145 | return ret; | 1097 | return ret; |
| 1146 | } | 1098 | } |
| @@ -1456,7 +1408,7 @@ static int nilfs_btree_delete(struct nilfs_bmap *bmap, __u64 key) | |||
| 1456 | path = nilfs_btree_alloc_path(); | 1408 | path = nilfs_btree_alloc_path(); |
| 1457 | if (path == NULL) | 1409 | if (path == NULL) |
| 1458 | return -ENOMEM; | 1410 | return -ENOMEM; |
| 1459 | nilfs_btree_init_path(path); | 1411 | |
| 1460 | ret = nilfs_btree_do_lookup(btree, path, key, NULL, | 1412 | ret = nilfs_btree_do_lookup(btree, path, key, NULL, |
| 1461 | NILFS_BTREE_LEVEL_NODE_MIN); | 1413 | NILFS_BTREE_LEVEL_NODE_MIN); |
| 1462 | if (ret < 0) | 1414 | if (ret < 0) |
| @@ -1473,7 +1425,6 @@ static int nilfs_btree_delete(struct nilfs_bmap *bmap, __u64 key) | |||
| 1473 | nilfs_bmap_sub_blocks(bmap, stats.bs_nblocks); | 1425 | nilfs_bmap_sub_blocks(bmap, stats.bs_nblocks); |
| 1474 | 1426 | ||
| 1475 | out: | 1427 | out: |
| 1476 | nilfs_btree_release_path(path); | ||
| 1477 | nilfs_btree_free_path(path); | 1428 | nilfs_btree_free_path(path); |
| 1478 | return ret; | 1429 | return ret; |
| 1479 | } | 1430 | } |
| @@ -1488,11 +1439,9 @@ static int nilfs_btree_last_key(const struct nilfs_bmap *bmap, __u64 *keyp) | |||
| 1488 | path = nilfs_btree_alloc_path(); | 1439 | path = nilfs_btree_alloc_path(); |
| 1489 | if (path == NULL) | 1440 | if (path == NULL) |
| 1490 | return -ENOMEM; | 1441 | return -ENOMEM; |
| 1491 | nilfs_btree_init_path(path); | ||
| 1492 | 1442 | ||
| 1493 | ret = nilfs_btree_do_lookup_last(btree, path, keyp, NULL); | 1443 | ret = nilfs_btree_do_lookup_last(btree, path, keyp, NULL); |
| 1494 | 1444 | ||
| 1495 | nilfs_btree_release_path(path); | ||
| 1496 | nilfs_btree_free_path(path); | 1445 | nilfs_btree_free_path(path); |
| 1497 | 1446 | ||
| 1498 | return ret; | 1447 | return ret; |
| @@ -1923,7 +1872,6 @@ static int nilfs_btree_propagate(const struct nilfs_bmap *bmap, | |||
| 1923 | path = nilfs_btree_alloc_path(); | 1872 | path = nilfs_btree_alloc_path(); |
| 1924 | if (path == NULL) | 1873 | if (path == NULL) |
| 1925 | return -ENOMEM; | 1874 | return -ENOMEM; |
| 1926 | nilfs_btree_init_path(path); | ||
| 1927 | 1875 | ||
| 1928 | if (buffer_nilfs_node(bh)) { | 1876 | if (buffer_nilfs_node(bh)) { |
| 1929 | node = (struct nilfs_btree_node *)bh->b_data; | 1877 | node = (struct nilfs_btree_node *)bh->b_data; |
| @@ -1947,7 +1895,6 @@ static int nilfs_btree_propagate(const struct nilfs_bmap *bmap, | |||
| 1947 | nilfs_btree_propagate_p(btree, path, level, bh); | 1895 | nilfs_btree_propagate_p(btree, path, level, bh); |
| 1948 | 1896 | ||
| 1949 | out: | 1897 | out: |
| 1950 | nilfs_btree_release_path(path); | ||
| 1951 | nilfs_btree_free_path(path); | 1898 | nilfs_btree_free_path(path); |
| 1952 | 1899 | ||
| 1953 | return ret; | 1900 | return ret; |
| @@ -2108,7 +2055,6 @@ static int nilfs_btree_assign(struct nilfs_bmap *bmap, | |||
| 2108 | path = nilfs_btree_alloc_path(); | 2055 | path = nilfs_btree_alloc_path(); |
| 2109 | if (path == NULL) | 2056 | if (path == NULL) |
| 2110 | return -ENOMEM; | 2057 | return -ENOMEM; |
| 2111 | nilfs_btree_init_path(path); | ||
| 2112 | 2058 | ||
| 2113 | if (buffer_nilfs_node(*bh)) { | 2059 | if (buffer_nilfs_node(*bh)) { |
| 2114 | node = (struct nilfs_btree_node *)(*bh)->b_data; | 2060 | node = (struct nilfs_btree_node *)(*bh)->b_data; |
| @@ -2130,7 +2076,6 @@ static int nilfs_btree_assign(struct nilfs_bmap *bmap, | |||
| 2130 | nilfs_btree_assign_p(btree, path, level, bh, blocknr, binfo); | 2076 | nilfs_btree_assign_p(btree, path, level, bh, blocknr, binfo); |
| 2131 | 2077 | ||
| 2132 | out: | 2078 | out: |
| 2133 | nilfs_btree_release_path(path); | ||
| 2134 | nilfs_btree_free_path(path); | 2079 | nilfs_btree_free_path(path); |
| 2135 | 2080 | ||
| 2136 | return ret; | 2081 | return ret; |
| @@ -2175,7 +2120,6 @@ static int nilfs_btree_mark(struct nilfs_bmap *bmap, __u64 key, int level) | |||
| 2175 | path = nilfs_btree_alloc_path(); | 2120 | path = nilfs_btree_alloc_path(); |
| 2176 | if (path == NULL) | 2121 | if (path == NULL) |
| 2177 | return -ENOMEM; | 2122 | return -ENOMEM; |
| 2178 | nilfs_btree_init_path(path); | ||
| 2179 | 2123 | ||
| 2180 | ret = nilfs_btree_do_lookup(btree, path, key, &ptr, level + 1); | 2124 | ret = nilfs_btree_do_lookup(btree, path, key, &ptr, level + 1); |
| 2181 | if (ret < 0) { | 2125 | if (ret < 0) { |
| @@ -2195,7 +2139,6 @@ static int nilfs_btree_mark(struct nilfs_bmap *bmap, __u64 key, int level) | |||
| 2195 | nilfs_bmap_set_dirty(&btree->bt_bmap); | 2139 | nilfs_bmap_set_dirty(&btree->bt_bmap); |
| 2196 | 2140 | ||
| 2197 | out: | 2141 | out: |
| 2198 | nilfs_btree_release_path(path); | ||
| 2199 | nilfs_btree_free_path(path); | 2142 | nilfs_btree_free_path(path); |
| 2200 | return ret; | 2143 | return ret; |
| 2201 | } | 2144 | } |
