Skip to content

Commit 3b501d1

Browse files
committed
btrfs: make find_workspace always succeed
With just one preallocated workspace we can guarantee forward progress even if there's no memory available for new workspaces. The cost is more waiting but we also get rid of several error paths. On average, there will be several idle workspaces, so the waiting penalty won't be so bad. In the worst case, all cpus will compete for one workspace until there's some memory. Attempts to allocate a new one are done each time the waiters are woken up. Signed-off-by: David Sterba <[email protected]>
1 parent 3853368 commit 3b501d1

File tree

1 file changed

+12
-8
lines changed

1 file changed

+12
-8
lines changed

fs/btrfs/compression.c

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -785,8 +785,10 @@ void __init btrfs_init_compress(void)
785785
}
786786

787787
/*
788-
* this finds an available workspace or allocates a new one
789-
* ERR_PTR is returned if things go bad.
788+
* This finds an available workspace or allocates a new one.
789+
* If it's not possible to allocate a new one, waits until there's one.
790+
* Preallocation makes a forward progress guarantees and we do not return
791+
* errors.
790792
*/
791793
static struct list_head *find_workspace(int type)
792794
{
@@ -826,6 +828,14 @@ static struct list_head *find_workspace(int type)
826828
if (IS_ERR(workspace)) {
827829
atomic_dec(total_ws);
828830
wake_up(ws_wait);
831+
832+
/*
833+
* Do not return the error but go back to waiting. There's a
834+
* workspace preallocated for each type and the compression
835+
* time is bounded so we get to a workspace eventually. This
836+
* makes our caller's life easier.
837+
*/
838+
goto again;
829839
}
830840
return workspace;
831841
}
@@ -913,8 +923,6 @@ int btrfs_compress_pages(int type, struct address_space *mapping,
913923
int ret;
914924

915925
workspace = find_workspace(type);
916-
if (IS_ERR(workspace))
917-
return PTR_ERR(workspace);
918926

919927
ret = btrfs_compress_op[type-1]->compress_pages(workspace, mapping,
920928
start, len, pages,
@@ -949,8 +957,6 @@ static int btrfs_decompress_biovec(int type, struct page **pages_in,
949957
int ret;
950958

951959
workspace = find_workspace(type);
952-
if (IS_ERR(workspace))
953-
return PTR_ERR(workspace);
954960

955961
ret = btrfs_compress_op[type-1]->decompress_biovec(workspace, pages_in,
956962
disk_start,
@@ -971,8 +977,6 @@ int btrfs_decompress(int type, unsigned char *data_in, struct page *dest_page,
971977
int ret;
972978

973979
workspace = find_workspace(type);
974-
if (IS_ERR(workspace))
975-
return PTR_ERR(workspace);
976980

977981
ret = btrfs_compress_op[type-1]->decompress(workspace, data_in,
978982
dest_page, start_byte,

0 commit comments

Comments
 (0)