From: David Sterba Date: Wed, 27 Apr 2016 00:55:15 +0000 (+0200) Subject: btrfs: preallocate compression workspaces X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4f55309a0388d7f59542fabd03bd6f8c57722096;p=linux btrfs: preallocate compression workspaces 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 (cherry picked from commit f77dd0d6b2f0f2cf290cacbd48f5eee18586e52b) --- diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c index 363a9640e0c1..c134f91f69d6 100644 --- a/fs/btrfs/compression.c +++ b/fs/btrfs/compression.c @@ -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); + } } }