]> git.hungrycats.org Git - linux/commitdiff
btrfs: preallocate compression workspaces
authorDavid Sterba <dsterba@suse.com>
Wed, 27 Apr 2016 00:55:15 +0000 (02:55 +0200)
committerZygo Blaxell <zblaxell@waya.furryterror.org>
Wed, 17 Aug 2016 02:42:11 +0000 (22:42 -0400)
Preallocate one workspace for each compression type so we can guarantee
forward progress in the worst case. A failure cannot be a hard error as
we might not use compression at all on the filesystem. If we can't
allocate the workspaces later when need them, it might actually
deadlock, but in such situation the system has effectively not enough
memory to operate properly.

Signed-off-by: David Sterba <dsterba@suse.com>
(cherry picked from commit f77dd0d6b2f0f2cf290cacbd48f5eee18586e52b)

fs/btrfs/compression.c

index 363a9640e0c1ff7ce5f9e5694446f8b3031fbae5..c134f91f69d6605419c04ad4237700e13d1beb34 100644 (file)
@@ -764,10 +764,26 @@ void __init btrfs_init_compress(void)
        int i;
 
        for (i = 0; i < BTRFS_COMPRESS_TYPES; i++) {
+               struct list_head *workspace;
+
                INIT_LIST_HEAD(&btrfs_comp_ws[i].idle_ws);
                spin_lock_init(&btrfs_comp_ws[i].ws_lock);
                atomic_set(&btrfs_comp_ws[i].alloc_ws, 0);
                init_waitqueue_head(&btrfs_comp_ws[i].ws_wait);
+
+               /*
+                * Preallocate one workspace for each compression type so
+                * we can guarantee forward progress in the worst case
+                */
+               workspace = btrfs_compress_op[i]->alloc_workspace();
+               if (IS_ERR(workspace)) {
+                       printk(KERN_WARNING
+       "BTRFS: cannot preallocate compression workspace, will try later");
+               } else {
+                       atomic_set(&btrfs_comp_ws[i].total_ws, 1);
+                       btrfs_comp_ws[i].free_ws = 1;
+                       list_add(workspace, &btrfs_comp_ws[i].idle_ws);
+               }
        }
 }