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 | } |