Btrfs: drop WARN_ON from btrfs_add_leaf_ref
[linux-2.6-block.git] / fs / btrfs / bit-radix.c
index 783f54c2a16cf0abde87ce382cef4de994f138ce..e8bf876db393dcf984b546e9d8a858c234bf43b4 100644 (file)
@@ -1,4 +1,21 @@
-#include <linux/module.h>
+/*
+ * Copyright (C) 2007 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License v2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 021110-1307, USA.
+ */
+
 #include "bit-radix.h"
 
 #define BIT_ARRAY_BYTES 256
@@ -22,14 +39,14 @@ int set_radix_bit(struct radix_tree_root *radix, unsigned long bit)
                        return -ENOMEM;
                memset(bits + 1, 0, BIT_ARRAY_BYTES - sizeof(unsigned long));
                bits[0] = slot;
-               radix_tree_preload(GFP_NOFS);
                ret = radix_tree_insert(radix, slot, bits);
-               radix_tree_preload_end();
                if (ret)
                        return ret;
        }
-       set_bit(bit_slot, bits + 1);
-       return 0;
+       ret = test_and_set_bit(bit_slot, bits + 1);
+       if (ret < 0)
+               ret = 1;
+       return ret;
 }
 
 int test_radix_bit(struct radix_tree_root *radix, unsigned long bit)
@@ -77,7 +94,7 @@ int clear_radix_bit(struct radix_tree_root *radix, unsigned long bit)
 }
 
 int find_first_radix_bit(struct radix_tree_root *radix, unsigned long *retbits,
-                        int nr)
+                        unsigned long start, int nr)
 {
        unsigned long *bits;
        unsigned long *gang[4];
@@ -85,10 +102,13 @@ int find_first_radix_bit(struct radix_tree_root *radix, unsigned long *retbits,
        int ret;
        int i;
        int total_found = 0;
+       unsigned long slot;
 
-       ret = radix_tree_gang_lookup(radix, (void *)&gang, 0, ARRAY_SIZE(gang));
+       slot = start / BIT_RADIX_BITS_PER_ARRAY;
+       ret = radix_tree_gang_lookup(radix, (void **)gang, slot,
+                                    ARRAY_SIZE(gang));
+       found = start % BIT_RADIX_BITS_PER_ARRAY;
        for (i = 0; i < ret && nr > 0; i++) {
-               found = 0;
                bits = gang[i];
                while(nr > 0) {
                        found = find_next_bit(bits + 1,
@@ -104,6 +124,7 @@ int find_first_radix_bit(struct radix_tree_root *radix, unsigned long *retbits,
                        } else
                                break;
                }
+               found = 0;
        }
        return total_found;
 }