@@ -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;
}