}
 
 /*
- * this finds an available workspace or allocates a new one
- * ERR_PTR is returned if things go bad.
+ * This finds an available workspace or allocates a new one.
+ * If it's not possible to allocate a new one, waits until there's one.
+ * Preallocation makes a forward progress guarantees and we do not return
+ * errors.
  */
 static struct list_head *find_workspace(int type)
 {
        if (IS_ERR(workspace)) {
                atomic_dec(total_ws);
                wake_up(ws_wait);
+
+               /*
+                * Do not return the error but go back to waiting. There's a
+                * workspace preallocated for each type and the compression
+                * time is bounded so we get to a workspace eventually. This
+                * makes our caller's life easier.
+                */
+               goto again;
        }
        return workspace;
 }
        int ret;
 
        workspace = find_workspace(type);
-       if (IS_ERR(workspace))
-               return PTR_ERR(workspace);
 
        ret = btrfs_compress_op[type-1]->compress_pages(workspace, mapping,
                                                      start, len, pages,
        int ret;
 
        workspace = find_workspace(type);
-       if (IS_ERR(workspace))
-               return PTR_ERR(workspace);
 
        ret = btrfs_compress_op[type-1]->decompress_biovec(workspace, pages_in,
                                                         disk_start,
        int ret;
 
        workspace = find_workspace(type);
-       if (IS_ERR(workspace))
-               return PTR_ERR(workspace);
 
        ret = btrfs_compress_op[type-1]->decompress(workspace, data_in,
                                                  dest_page, start_byte,