Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/btrfs...
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 13 Apr 2010 01:37:04 +0000 (18:37 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 13 Apr 2010 01:37:04 +0000 (18:37 -0700)
* 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/btrfs-unstable:
  Btrfs: make sure the chunk allocator doesn't create zero length chunks
  Btrfs: fix data enospc check overflow

1  2 
fs/btrfs/extent-tree.c
fs/btrfs/volumes.c

diff --combined fs/btrfs/extent-tree.c
@@@ -22,7 -22,6 +22,7 @@@
  #include <linux/sort.h>
  #include <linux/rcupdate.h>
  #include <linux/kthread.h>
 +#include <linux/slab.h>
  #include "compat.h"
  #include "hash.h"
  #include "ctree.h"
@@@ -3235,7 -3234,8 +3235,8 @@@ int btrfs_check_data_free_space(struct 
                                u64 bytes)
  {
        struct btrfs_space_info *data_sinfo;
-       int ret = 0, committed = 0;
+       u64 used;
+       int ret = 0, committed = 0, flushed = 0;
  
        /* make sure bytes are sectorsize aligned */
        bytes = (bytes + root->sectorsize - 1) & ~((u64)root->sectorsize - 1);
  again:
        /* make sure we have enough space to handle the data first */
        spin_lock(&data_sinfo->lock);
-       if (data_sinfo->total_bytes - data_sinfo->bytes_used -
-           data_sinfo->bytes_delalloc - data_sinfo->bytes_reserved -
-           data_sinfo->bytes_pinned - data_sinfo->bytes_readonly -
-           data_sinfo->bytes_may_use - data_sinfo->bytes_super < bytes) {
+       used = data_sinfo->bytes_used + data_sinfo->bytes_delalloc +
+               data_sinfo->bytes_reserved + data_sinfo->bytes_pinned +
+               data_sinfo->bytes_readonly + data_sinfo->bytes_may_use +
+               data_sinfo->bytes_super;
+       if (used + bytes > data_sinfo->total_bytes) {
                struct btrfs_trans_handle *trans;
  
+               if (!flushed) {
+                       spin_unlock(&data_sinfo->lock);
+                       flush_delalloc(root, data_sinfo);
+                       flushed = 1;
+                       goto again;
+               }
                /*
                 * if we don't have enough free bytes in this space then we need
                 * to alloc a new chunk.
diff --combined fs/btrfs/volumes.c
@@@ -17,7 -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>
@@@ -2250,6 -2249,12 +2250,12 @@@ again
        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;