]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - fs/btrfs/volumes.c
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/btrfs...
[net-next-2.6.git] / fs / btrfs / volumes.c
index 9df8e3f1ccabea1daa2e3d4fd93fdb6424fa4555..8db7b14bbae8be31c726b8e8596d0ff0640fa35f 100644 (file)
@@ -17,6 +17,7 @@
  */
 #include <linux/sched.h>
 #include <linux/bio.h>
+#include <linux/slab.h>
 #include <linux/buffer_head.h>
 #include <linux/blkdev.h>
 #include <linux/random.h>
@@ -2198,9 +2199,9 @@ static int __btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
                min_stripes = 2;
        }
        if (type & (BTRFS_BLOCK_GROUP_RAID1)) {
-               num_stripes = min_t(u64, 2, fs_devices->rw_devices);
-               if (num_stripes < 2)
+               if (fs_devices->rw_devices < 2)
                        return -ENOSPC;
+               num_stripes = 2;
                min_stripes = 2;
        }
        if (type & (BTRFS_BLOCK_GROUP_RAID10)) {
@@ -2244,8 +2245,16 @@ again:
                do_div(calc_size, stripe_len);
                calc_size *= stripe_len;
        }
+
        /* we don't want tiny stripes */
-       calc_size = max_t(u64, min_stripe_size, calc_size);
+       if (!looped)
+               calc_size = max_t(u64, min_stripe_size, calc_size);
+
+       /*
+        * we're about to do_div by the stripe_len so lets make sure
+        * we end up with something bigger than a stripe
+        */
+       calc_size = max_t(u64, calc_size, stripe_len * 4);
 
        do_div(calc_size, stripe_len);
        calc_size *= stripe_len;
@@ -3389,6 +3398,8 @@ int btrfs_read_chunk_tree(struct btrfs_root *root)
        key.type = 0;
 again:
        ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
+       if (ret < 0)
+               goto error;
        while (1) {
                leaf = path->nodes[0];
                slot = path->slots[0];