aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/ioctl.c
diff options
context:
space:
mode:
authorJosef Bacik <josef@redhat.com>2011-07-15 11:16:44 -0400
committerChris Mason <chris.mason@oracle.com>2011-07-27 12:46:44 -0400
commit9e0baf60dea69f31ac3b1adeb35b03b02a53e8e1 (patch)
tree0fb899e1fa78b599d22389ca3befc8ab51ff5049 /fs/btrfs/ioctl.c
parenta5991428064e98c7367fe1c1686ea6a23fb6a4b3 (diff)
Btrfs: fix enospc problems with delalloc
So I had this brilliant idea to use atomic counters for outstanding and reserved extents, but this turned out to be a bad idea. Consider this where we have 1 outstanding extent and 1 reserved extent Reserver Releaser atomic_dec(outstanding) now 0 atomic_read(outstanding)+1 get 1 atomic_read(reserved) get 1 don't actually reserve anything because they are the same atomic_cmpxchg(reserved, 1, 0) atomic_inc(outstanding) atomic_add(0, reserved) free reserved space for 1 extent Then the reserver now has no actual space reserved for it, and when it goes to finish the ordered IO it won't have enough space to do it's allocation and you get those lovely warnings. Signed-off-by: Josef Bacik <josef@redhat.com> Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/ioctl.c')
-rw-r--r--fs/btrfs/ioctl.c4
1 files changed, 3 insertions, 1 deletions
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index 09c9a8d26ee9..fd252fff4c66 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -938,7 +938,9 @@ again:
938 GFP_NOFS); 938 GFP_NOFS);
939 939
940 if (i_done != num_pages) { 940 if (i_done != num_pages) {
941 atomic_inc(&BTRFS_I(inode)->outstanding_extents); 941 spin_lock(&BTRFS_I(inode)->lock);
942 BTRFS_I(inode)->outstanding_extents++;
943 spin_unlock(&BTRFS_I(inode)->lock);
942 btrfs_delalloc_release_space(inode, 944 btrfs_delalloc_release_space(inode,
943 (num_pages - i_done) << PAGE_CACHE_SHIFT); 945 (num_pages - i_done) << PAGE_CACHE_SHIFT);
944 } 946 }