|
@@ -112,7 +112,8 @@ struct iv_tcw_private {
|
|
* and encrypts / decrypts at the same time.
|
|
* and encrypts / decrypts at the same time.
|
|
*/
|
|
*/
|
|
enum flags { DM_CRYPT_SUSPENDED, DM_CRYPT_KEY_VALID,
|
|
enum flags { DM_CRYPT_SUSPENDED, DM_CRYPT_KEY_VALID,
|
|
- DM_CRYPT_SAME_CPU, DM_CRYPT_NO_OFFLOAD };
|
|
|
|
|
|
+ DM_CRYPT_SAME_CPU, DM_CRYPT_NO_OFFLOAD,
|
|
|
|
+ DM_CRYPT_EXIT_THREAD};
|
|
|
|
|
|
/*
|
|
/*
|
|
* The fields in here must be read only after initialization.
|
|
* The fields in here must be read only after initialization.
|
|
@@ -1203,20 +1204,18 @@ continue_locked:
|
|
if (!RB_EMPTY_ROOT(&cc->write_tree))
|
|
if (!RB_EMPTY_ROOT(&cc->write_tree))
|
|
goto pop_from_list;
|
|
goto pop_from_list;
|
|
|
|
|
|
|
|
+ if (unlikely(test_bit(DM_CRYPT_EXIT_THREAD, &cc->flags))) {
|
|
|
|
+ spin_unlock_irq(&cc->write_thread_wait.lock);
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+
|
|
__set_current_state(TASK_INTERRUPTIBLE);
|
|
__set_current_state(TASK_INTERRUPTIBLE);
|
|
__add_wait_queue(&cc->write_thread_wait, &wait);
|
|
__add_wait_queue(&cc->write_thread_wait, &wait);
|
|
|
|
|
|
spin_unlock_irq(&cc->write_thread_wait.lock);
|
|
spin_unlock_irq(&cc->write_thread_wait.lock);
|
|
|
|
|
|
- if (unlikely(kthread_should_stop())) {
|
|
|
|
- set_task_state(current, TASK_RUNNING);
|
|
|
|
- remove_wait_queue(&cc->write_thread_wait, &wait);
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
schedule();
|
|
schedule();
|
|
|
|
|
|
- set_task_state(current, TASK_RUNNING);
|
|
|
|
spin_lock_irq(&cc->write_thread_wait.lock);
|
|
spin_lock_irq(&cc->write_thread_wait.lock);
|
|
__remove_wait_queue(&cc->write_thread_wait, &wait);
|
|
__remove_wait_queue(&cc->write_thread_wait, &wait);
|
|
goto continue_locked;
|
|
goto continue_locked;
|
|
@@ -1531,8 +1530,13 @@ static void crypt_dtr(struct dm_target *ti)
|
|
if (!cc)
|
|
if (!cc)
|
|
return;
|
|
return;
|
|
|
|
|
|
- if (cc->write_thread)
|
|
|
|
|
|
+ if (cc->write_thread) {
|
|
|
|
+ spin_lock_irq(&cc->write_thread_wait.lock);
|
|
|
|
+ set_bit(DM_CRYPT_EXIT_THREAD, &cc->flags);
|
|
|
|
+ wake_up_locked(&cc->write_thread_wait);
|
|
|
|
+ spin_unlock_irq(&cc->write_thread_wait.lock);
|
|
kthread_stop(cc->write_thread);
|
|
kthread_stop(cc->write_thread);
|
|
|
|
+ }
|
|
|
|
|
|
if (cc->io_queue)
|
|
if (cc->io_queue)
|
|
destroy_workqueue(cc->io_queue);
|
|
destroy_workqueue(cc->io_queue);
|