Merge branch 'i2c-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jdelvar...
[pandora-kernel.git] / fs / nilfs2 / btree.c
index 76c38e3..b27a342 100644 (file)
 #include "alloc.h"
 #include "dat.h"
 
-/**
- * struct nilfs_btree_path - A path on which B-tree operations are executed
- * @bp_bh: buffer head of node block
- * @bp_sib_bh: buffer head of sibling node block
- * @bp_index: index of child node
- * @bp_oldreq: ptr end request for old ptr
- * @bp_newreq: ptr alloc request for new ptr
- * @bp_op: rebalance operation
- */
-struct nilfs_btree_path {
-       struct buffer_head *bp_bh;
-       struct buffer_head *bp_sib_bh;
-       int bp_index;
-       union nilfs_bmap_ptr_req bp_oldreq;
-       union nilfs_bmap_ptr_req bp_newreq;
-       struct nilfs_btnode_chkey_ctxt bp_ctxt;
-       void (*bp_op)(struct nilfs_btree *, struct nilfs_btree_path *,
-                     int, __u64 *, __u64 *);
-};
-
-/*
- * B-tree path operations
- */
-
-static struct kmem_cache *nilfs_btree_path_cache;
-
-int __init nilfs_btree_path_cache_init(void)
-{
-       nilfs_btree_path_cache =
-               kmem_cache_create("nilfs2_btree_path_cache",
-                                 sizeof(struct nilfs_btree_path) *
-                                 NILFS_BTREE_LEVEL_MAX, 0, 0, NULL);
-       return (nilfs_btree_path_cache != NULL) ? 0 : -ENOMEM;
-}
-
-void nilfs_btree_path_cache_destroy(void)
-{
-       kmem_cache_destroy(nilfs_btree_path_cache);
-}
-
-static inline struct nilfs_btree_path *nilfs_btree_alloc_path(void)
-{
-       return kmem_cache_alloc(nilfs_btree_path_cache, GFP_NOFS);
-}
-
-static inline void nilfs_btree_free_path(struct nilfs_btree_path *path)
+static struct nilfs_btree_path *nilfs_btree_alloc_path(void)
 {
-       kmem_cache_free(nilfs_btree_path_cache, path);
-}
+       struct nilfs_btree_path *path;
+       int level = NILFS_BTREE_LEVEL_DATA;
 
-static void nilfs_btree_init_path(struct nilfs_btree_path *path)
-{
-       int level;
+       path = kmem_cache_alloc(nilfs_btree_path_cache, GFP_NOFS);
+       if (path == NULL)
+               goto out;
 
-       for (level = NILFS_BTREE_LEVEL_DATA;
-            level < NILFS_BTREE_LEVEL_MAX;
-            level++) {
+       for (; level < NILFS_BTREE_LEVEL_MAX; level++) {
                path[level].bp_bh = NULL;
                path[level].bp_sib_bh = NULL;
                path[level].bp_index = 0;
@@ -95,15 +48,19 @@ static void nilfs_btree_init_path(struct nilfs_btree_path *path)
                path[level].bp_newreq.bpr_ptr = NILFS_BMAP_INVALID_PTR;
                path[level].bp_op = NULL;
        }
+
+out:
+       return path;
 }
 
-static void nilfs_btree_release_path(struct nilfs_btree_path *path)
+static void nilfs_btree_free_path(struct nilfs_btree_path *path)
 {
-       int level;
+       int level = NILFS_BTREE_LEVEL_DATA;
 
-       for (level = NILFS_BTREE_LEVEL_DATA; level < NILFS_BTREE_LEVEL_MAX;
-            level++)
+       for (; level < NILFS_BTREE_LEVEL_MAX; level++)
                brelse(path[level].bp_bh);
+
+       kmem_cache_free(nilfs_btree_path_cache, path);
 }
 
 /*
@@ -566,14 +523,12 @@ static int nilfs_btree_lookup(const struct nilfs_bmap *bmap,
        path = nilfs_btree_alloc_path();
        if (path == NULL)
                return -ENOMEM;
-       nilfs_btree_init_path(path);
 
        ret = nilfs_btree_do_lookup(btree, path, key, &ptr, level);
 
        if (ptrp != NULL)
                *ptrp = ptr;
 
-       nilfs_btree_release_path(path);
        nilfs_btree_free_path(path);
 
        return ret;
@@ -594,7 +549,7 @@ static int nilfs_btree_lookup_contig(const struct nilfs_bmap *bmap,
        path = nilfs_btree_alloc_path();
        if (path == NULL)
                return -ENOMEM;
-       nilfs_btree_init_path(path);
+
        ret = nilfs_btree_do_lookup(btree, path, key, &ptr, level);
        if (ret < 0)
                goto out;
@@ -655,7 +610,6 @@ static int nilfs_btree_lookup_contig(const struct nilfs_bmap *bmap,
        *ptrp = ptr;
        ret = cnt;
  out:
-       nilfs_btree_release_path(path);
        nilfs_btree_free_path(path);
        return ret;
 }
@@ -1123,7 +1077,6 @@ static int nilfs_btree_insert(struct nilfs_bmap *bmap, __u64 key, __u64 ptr)
        path = nilfs_btree_alloc_path();
        if (path == NULL)
                return -ENOMEM;
-       nilfs_btree_init_path(path);
 
        ret = nilfs_btree_do_lookup(btree, path, key, NULL,
                                    NILFS_BTREE_LEVEL_NODE_MIN);
@@ -1140,7 +1093,6 @@ static int nilfs_btree_insert(struct nilfs_bmap *bmap, __u64 key, __u64 ptr)
        nilfs_bmap_add_blocks(bmap, stats.bs_nblocks);
 
  out:
-       nilfs_btree_release_path(path);
        nilfs_btree_free_path(path);
        return ret;
 }
@@ -1456,7 +1408,7 @@ static int nilfs_btree_delete(struct nilfs_bmap *bmap, __u64 key)
        path = nilfs_btree_alloc_path();
        if (path == NULL)
                return -ENOMEM;
-       nilfs_btree_init_path(path);
+
        ret = nilfs_btree_do_lookup(btree, path, key, NULL,
                                    NILFS_BTREE_LEVEL_NODE_MIN);
        if (ret < 0)
@@ -1473,7 +1425,6 @@ static int nilfs_btree_delete(struct nilfs_bmap *bmap, __u64 key)
        nilfs_bmap_sub_blocks(bmap, stats.bs_nblocks);
 
 out:
-       nilfs_btree_release_path(path);
        nilfs_btree_free_path(path);
        return ret;
 }
@@ -1488,11 +1439,9 @@ static int nilfs_btree_last_key(const struct nilfs_bmap *bmap, __u64 *keyp)
        path = nilfs_btree_alloc_path();
        if (path == NULL)
                return -ENOMEM;
-       nilfs_btree_init_path(path);
 
        ret = nilfs_btree_do_lookup_last(btree, path, keyp, NULL);
 
-       nilfs_btree_release_path(path);
        nilfs_btree_free_path(path);
 
        return ret;
@@ -1923,7 +1872,6 @@ static int nilfs_btree_propagate(const struct nilfs_bmap *bmap,
        path = nilfs_btree_alloc_path();
        if (path == NULL)
                return -ENOMEM;
-       nilfs_btree_init_path(path);
 
        if (buffer_nilfs_node(bh)) {
                node = (struct nilfs_btree_node *)bh->b_data;
@@ -1947,7 +1895,6 @@ static int nilfs_btree_propagate(const struct nilfs_bmap *bmap,
                nilfs_btree_propagate_p(btree, path, level, bh);
 
  out:
-       nilfs_btree_release_path(path);
        nilfs_btree_free_path(path);
 
        return ret;
@@ -2108,7 +2055,6 @@ static int nilfs_btree_assign(struct nilfs_bmap *bmap,
        path = nilfs_btree_alloc_path();
        if (path == NULL)
                return -ENOMEM;
-       nilfs_btree_init_path(path);
 
        if (buffer_nilfs_node(*bh)) {
                node = (struct nilfs_btree_node *)(*bh)->b_data;
@@ -2130,7 +2076,6 @@ static int nilfs_btree_assign(struct nilfs_bmap *bmap,
                nilfs_btree_assign_p(btree, path, level, bh, blocknr, binfo);
 
  out:
-       nilfs_btree_release_path(path);
        nilfs_btree_free_path(path);
 
        return ret;
@@ -2175,7 +2120,6 @@ static int nilfs_btree_mark(struct nilfs_bmap *bmap, __u64 key, int level)
        path = nilfs_btree_alloc_path();
        if (path == NULL)
                return -ENOMEM;
-       nilfs_btree_init_path(path);
 
        ret = nilfs_btree_do_lookup(btree, path, key, &ptr, level + 1);
        if (ret < 0) {
@@ -2195,7 +2139,6 @@ static int nilfs_btree_mark(struct nilfs_bmap *bmap, __u64 key, int level)
                nilfs_bmap_set_dirty(&btree->bt_bmap);
 
  out:
-       nilfs_btree_release_path(path);
        nilfs_btree_free_path(path);
        return ret;
 }