btrfs: Fix bugs in zlib workspace
authorLi Zefan <lizf@cn.fujitsu.com>
Mon, 25 Oct 2010 07:11:43 +0000 (15:11 +0800)
committerLi Zefan <lizf@cn.fujitsu.com>
Wed, 22 Dec 2010 15:15:41 +0000 (23:15 +0800)
- Fix a race that can result in alloc_workspace > cpus.
- Fix to check num_workspace after wakeup.

Signed-off-by: Li Zefan <lizf@cn.fujitsu.com>
fs/btrfs/zlib.c

index b9cd5445f71cac0c6b2d565f80d065091d65fa4b..e5b8b22e07d69f28eaef8e1ed84705b3d9666fce 100644 (file)
@@ -75,16 +75,19 @@ again:
                return workspace;
 
        }
-       spin_unlock(&workspace_lock);
        if (atomic_read(&alloc_workspace) > cpus) {
                DEFINE_WAIT(wait);
+
+               spin_unlock(&workspace_lock);
                prepare_to_wait(&workspace_wait, &wait, TASK_UNINTERRUPTIBLE);
-               if (atomic_read(&alloc_workspace) > cpus)
+               if (atomic_read(&alloc_workspace) > cpus && !num_workspace)
                        schedule();
                finish_wait(&workspace_wait, &wait);
                goto again;
        }
        atomic_inc(&alloc_workspace);
+       spin_unlock(&workspace_lock);
+
        workspace = kzalloc(sizeof(*workspace), GFP_NOFS);
        if (!workspace) {
                ret = -ENOMEM;