aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs
diff options
context:
space:
mode:
authorArne Jansen <sensille@gmx.net>2011-09-13 05:18:10 -0400
committerAlexander Block <ablock84@googlemail.com>2012-07-25 11:33:18 -0400
commite679376911d016b670c8cfc1645c178f77e8d1d3 (patch)
tree0ecc36238400c974a6c94eee6cda7288d494f515 /fs/btrfs
parent362a20c5e27614739c46707d1c5f55c214d164ce (diff)
Btrfs: add helper for tree enumeration
Often no exact match is wanted but just the next lower or higher item. There's a lot of duplicated code throughout btrfs to deal with the corner cases. This patch adds a helper function that can facilitate searching. Signed-off-by: Arne Jansen <sensille@gmx.net>
Diffstat (limited to 'fs/btrfs')
-rw-r--r--fs/btrfs/ctree.c74
-rw-r--r--fs/btrfs/ctree.h3
2 files changed, 77 insertions, 0 deletions
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
index 8206b3900587..c82a9e4a953e 100644
--- a/fs/btrfs/ctree.c
+++ b/fs/btrfs/ctree.c
@@ -2722,6 +2722,80 @@ done:
2722} 2722}
2723 2723
2724/* 2724/*
2725 * helper to use instead of search slot if no exact match is needed but
2726 * instead the next or previous item should be returned.
2727 * When find_higher is true, the next higher item is returned, the next lower
2728 * otherwise.
2729 * When return_any and find_higher are both true, and no higher item is found,
2730 * return the next lower instead.
2731 * When return_any is true and find_higher is false, and no lower item is found,
2732 * return the next higher instead.
2733 * It returns 0 if any item is found, 1 if none is found (tree empty), and
2734 * < 0 on error
2735 */
2736int btrfs_search_slot_for_read(struct btrfs_root *root,
2737 struct btrfs_key *key, struct btrfs_path *p,
2738 int find_higher, int return_any)
2739{
2740 int ret;
2741 struct extent_buffer *leaf;
2742
2743again:
2744 ret = btrfs_search_slot(NULL, root, key, p, 0, 0);
2745 if (ret <= 0)
2746 return ret;
2747 /*
2748 * a return value of 1 means the path is at the position where the
2749 * item should be inserted. Normally this is the next bigger item,
2750 * but in case the previous item is the last in a leaf, path points
2751 * to the first free slot in the previous leaf, i.e. at an invalid
2752 * item.
2753 */
2754 leaf = p->nodes[0];
2755
2756 if (find_higher) {
2757 if (p->slots[0] >= btrfs_header_nritems(leaf)) {
2758 ret = btrfs_next_leaf(root, p);
2759 if (ret <= 0)
2760 return ret;
2761 if (!return_any)
2762 return 1;
2763 /*
2764 * no higher item found, return the next
2765 * lower instead
2766 */
2767 return_any = 0;
2768 find_higher = 0;
2769 btrfs_release_path(p);
2770 goto again;
2771 }
2772 } else {
2773 if (p->slots[0] == 0) {
2774 ret = btrfs_prev_leaf(root, p);
2775 if (ret < 0)
2776 return ret;
2777 if (!ret) {
2778 p->slots[0] = btrfs_header_nritems(leaf) - 1;
2779 return 0;
2780 }
2781 if (!return_any)
2782 return 1;
2783 /*
2784 * no lower item found, return the next
2785 * higher instead
2786 */
2787 return_any = 0;
2788 find_higher = 1;
2789 btrfs_release_path(p);
2790 goto again;
2791 } else {
2792 --p->slots[0];
2793 }
2794 }
2795 return 0;
2796}
2797
2798/*
2725 * adjust the pointers going up the tree, starting at level 2799 * adjust the pointers going up the tree, starting at level
2726 * making sure the right key of each node is points to 'key'. 2800 * making sure the right key of each node is points to 'key'.
2727 * This is used after shifting pointers to the left, so it stops 2801 * This is used after shifting pointers to the left, so it stops
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index fa5c45b39075..8cfde9326dd6 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -2711,6 +2711,9 @@ int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root
2711 ins_len, int cow); 2711 ins_len, int cow);
2712int btrfs_search_old_slot(struct btrfs_root *root, struct btrfs_key *key, 2712int btrfs_search_old_slot(struct btrfs_root *root, struct btrfs_key *key,
2713 struct btrfs_path *p, u64 time_seq); 2713 struct btrfs_path *p, u64 time_seq);
2714int btrfs_search_slot_for_read(struct btrfs_root *root,
2715 struct btrfs_key *key, struct btrfs_path *p,
2716 int find_higher, int return_any);
2714int btrfs_realloc_node(struct btrfs_trans_handle *trans, 2717int btrfs_realloc_node(struct btrfs_trans_handle *trans,
2715 struct btrfs_root *root, struct extent_buffer *parent, 2718 struct btrfs_root *root, struct extent_buffer *parent,
2716 int start_slot, int cache_only, u64 *last_ret, 2719 int start_slot, int cache_only, u64 *last_ret,