diff options
author | Arne Jansen <sensille@gmx.net> | 2011-09-13 05:18:10 -0400 |
---|---|---|
committer | Jan Schmidt <list.btrfs@jan-o-sch.net> | 2012-07-10 09:14:42 -0400 |
commit | 2f38b3e1900634e64a186873b3388b1bf85dabc0 (patch) | |
tree | 21017a51174be9ba31696e4e4c8daa18ce2d59f8 | |
parent | 630dc772ea51bca3ec6fac609f450cbe0cafd1d6 (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>
-rw-r--r-- | fs/btrfs/ctree.c | 72 | ||||
-rw-r--r-- | fs/btrfs/ctree.h | 3 |
2 files changed, 75 insertions, 0 deletions
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index bef68ab32204..fb21431fe4e0 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c | |||
@@ -2789,6 +2789,78 @@ done: | |||
2789 | } | 2789 | } |
2790 | 2790 | ||
2791 | /* | 2791 | /* |
2792 | * helper to use instead of search slot if no exact match is needed but | ||
2793 | * instead the next or previous item should be returned. | ||
2794 | * When find_higher is true, the next higher item is returned, the next lower | ||
2795 | * otherwise. | ||
2796 | * When return_any and find_higher are both true, and no higher item is found, | ||
2797 | * return the next lower instead. | ||
2798 | * When return_any is true and find_higher is false, and no lower item is found, | ||
2799 | * return the next higher instead. | ||
2800 | * It returns 0 if any item is found, 1 if none is found (tree empty), and | ||
2801 | * < 0 on error | ||
2802 | */ | ||
2803 | int btrfs_search_slot_for_read(struct btrfs_root *root, | ||
2804 | struct btrfs_key *key, struct btrfs_path *p, | ||
2805 | int find_higher, int return_any) | ||
2806 | { | ||
2807 | int ret; | ||
2808 | struct extent_buffer *leaf; | ||
2809 | |||
2810 | again: | ||
2811 | ret = btrfs_search_slot(NULL, root, key, p, 0, 0); | ||
2812 | if (ret <= 0) | ||
2813 | return ret; | ||
2814 | /* | ||
2815 | * a return value of 1 means the path is at the position where the | ||
2816 | * item should be inserted. Normally this is the next bigger item, | ||
2817 | * but in case the previous item is the last in a leaf, path points | ||
2818 | * to the first free slot in the previous leaf, i.e. at an invalid | ||
2819 | * item. | ||
2820 | */ | ||
2821 | leaf = p->nodes[0]; | ||
2822 | |||
2823 | if (find_higher) { | ||
2824 | if (p->slots[0] >= btrfs_header_nritems(leaf)) { | ||
2825 | ret = btrfs_next_leaf(root, p); | ||
2826 | if (ret <= 0) | ||
2827 | return ret; | ||
2828 | if (!return_any) | ||
2829 | return 1; | ||
2830 | /* | ||
2831 | * no higher item found, return the next | ||
2832 | * lower instead | ||
2833 | */ | ||
2834 | return_any = 0; | ||
2835 | find_higher = 0; | ||
2836 | btrfs_release_path(p); | ||
2837 | goto again; | ||
2838 | } | ||
2839 | } else { | ||
2840 | if (p->slots[0] >= btrfs_header_nritems(leaf)) { | ||
2841 | /* we're sitting on an invalid slot */ | ||
2842 | if (p->slots[0] == 0) { | ||
2843 | ret = btrfs_prev_leaf(root, p); | ||
2844 | if (ret <= 0) | ||
2845 | return ret; | ||
2846 | if (!return_any) | ||
2847 | return 1; | ||
2848 | /* | ||
2849 | * no lower item found, return the next | ||
2850 | * higher instead | ||
2851 | */ | ||
2852 | return_any = 0; | ||
2853 | find_higher = 1; | ||
2854 | btrfs_release_path(p); | ||
2855 | goto again; | ||
2856 | } | ||
2857 | --p->slots[0]; | ||
2858 | } | ||
2859 | } | ||
2860 | return 0; | ||
2861 | } | ||
2862 | |||
2863 | /* | ||
2792 | * adjust the pointers going up the tree, starting at level | 2864 | * adjust the pointers going up the tree, starting at level |
2793 | * making sure the right key of each node is points to 'key'. | 2865 | * making sure the right key of each node is points to 'key'. |
2794 | * This is used after shifting pointers to the left, so it stops | 2866 | * 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 33088b0dbf3f..27cf995564ed 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h | |||
@@ -2856,6 +2856,9 @@ int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root | |||
2856 | ins_len, int cow); | 2856 | ins_len, int cow); |
2857 | int btrfs_search_old_slot(struct btrfs_root *root, struct btrfs_key *key, | 2857 | int btrfs_search_old_slot(struct btrfs_root *root, struct btrfs_key *key, |
2858 | struct btrfs_path *p, u64 time_seq); | 2858 | struct btrfs_path *p, u64 time_seq); |
2859 | int btrfs_search_slot_for_read(struct btrfs_root *root, | ||
2860 | struct btrfs_key *key, struct btrfs_path *p, | ||
2861 | int find_higher, int return_any); | ||
2859 | int btrfs_realloc_node(struct btrfs_trans_handle *trans, | 2862 | int btrfs_realloc_node(struct btrfs_trans_handle *trans, |
2860 | struct btrfs_root *root, struct extent_buffer *parent, | 2863 | struct btrfs_root *root, struct extent_buffer *parent, |
2861 | int start_slot, int cache_only, u64 *last_ret, | 2864 | int start_slot, int cache_only, u64 *last_ret, |