diff mbox

Btrfs: force delalloc flushing when things get desperate

Message ID 20100312212309.GC2332@localhost.localdomain (mailing list archive)
State New, archived
Headers show

Commit Message

Josef Bacik March 12, 2010, 9:23 p.m. UTC
None
diff mbox

Patch

diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 0085dcb..aeef481 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -2873,7 +2873,7 @@  static noinline void flush_delalloc_async(struct btrfs_work *work)
 	kfree(async);
 }
 
-static void wait_on_flush(struct btrfs_root *root, struct btrfs_space_info *info)
+static void wait_on_flush(struct btrfs_root *root, struct btrfs_space_info *info, int soft)
 {
 	DEFINE_WAIT(wait);
 	u64 num_bytes;
@@ -2895,6 +2895,12 @@  static void wait_on_flush(struct btrfs_root *root, struct btrfs_space_info *info
 			break;
 		}
 
+		if (!soft) {
+			spin_unlock(&info->lock);
+			schedule();
+			continue;
+		}
+
 		free = 0;
 		for_each_possible_cpu(i) {
 			struct btrfs_reserved_space_pool *pool;
@@ -2924,7 +2930,7 @@  static void wait_on_flush(struct btrfs_root *root, struct btrfs_space_info *info
 }
 
 static void flush_delalloc(struct btrfs_root *root,
-				 struct btrfs_space_info *info)
+			   struct btrfs_space_info *info, int soft)
 {
 	struct async_flush *async;
 	bool wait = false;
@@ -2939,7 +2945,7 @@  static void flush_delalloc(struct btrfs_root *root,
 	spin_unlock(&info->lock);
 
 	if (wait) {
-		wait_on_flush(root, info);
+		wait_on_flush(root, info, soft);
 		return;
 	}
 
@@ -2953,7 +2959,7 @@  static void flush_delalloc(struct btrfs_root *root,
 
 	btrfs_queue_worker(&root->fs_info->enospc_workers,
 			   &async->work);
-	wait_on_flush(root, info);
+	wait_on_flush(root, info, soft);
 	return;
 
 flush:
@@ -3146,14 +3152,17 @@  again:
 
 	if (!delalloc_flushed) {
 		delalloc_flushed = true;
-		flush_delalloc(root, meta_sinfo);
+		flush_delalloc(root, meta_sinfo, 1);
 		goto again;
 	}
 
 	if (!chunk_allocated) {
+		int ret;
+
 		chunk_allocated = true;
-		btrfs_wait_ordered_extents(root, 0, 0);
-		maybe_allocate_chunk(root, meta_sinfo);
+		ret = maybe_allocate_chunk(root, meta_sinfo);
+		if (!ret)
+			flush_delalloc(root, meta_sinfo, 0);
 		goto again;
 	}
 
@@ -3338,7 +3347,7 @@  again:
 
 	if (!delalloc_flushed) {
 		delalloc_flushed = true;
-		flush_delalloc(root, meta_sinfo);
+		flush_delalloc(root, meta_sinfo, 0);
 		goto again;
 	}