From cec9074db796aa19972f33ebfb944eb9d30f811f Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Thu, 9 Apr 2009 00:27:17 +0100 Subject: [PATCH] --- yaml --- r: 142897 b: refs/heads/master c: 340cd44451fb0bfa542365e6b4b565bbd44836e2 h: refs/heads/master i: 142895: 281cb7a86137a61f620f12a89c7b1d5087363bcd v: v3 --- [refs] | 2 +- trunk/drivers/md/dm-kcopyd.c | 17 +++++++++++------ 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/[refs] b/[refs] index 36ee7a3a6b01..8c412b22fd61 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 73830857bca6f6c9dbd48e906daea50bea42d676 +refs/heads/master: 340cd44451fb0bfa542365e6b4b565bbd44836e2 diff --git a/trunk/drivers/md/dm-kcopyd.c b/trunk/drivers/md/dm-kcopyd.c index 9d379070918b..3e3fc06cb861 100644 --- a/trunk/drivers/md/dm-kcopyd.c +++ b/trunk/drivers/md/dm-kcopyd.c @@ -511,13 +511,16 @@ static void segment_complete(int read_err, unsigned long write_err, } else if (atomic_dec_and_test(&job->sub_jobs)) { /* - * To avoid a race we must keep the job around - * until after the notify function has completed. - * Otherwise the client may try and stop the job - * after we've completed. + * Queue the completion callback to the kcopyd thread. + * + * Some callers assume that all the completions are called + * from a single thread and don't race with each other. + * + * We must not call the callback directly here because this + * code may not be executing in the thread. */ - job->fn(read_err, write_err, job->context); - mempool_free(job, job->kc->job_pool); + push(&kc->complete_jobs, job); + wake(kc); } } @@ -530,6 +533,8 @@ static void split_job(struct kcopyd_job *job) { int i; + atomic_inc(&job->kc->nr_jobs); + atomic_set(&job->sub_jobs, SPLIT_COUNT); for (i = 0; i < SPLIT_COUNT; i++) segment_complete(0, 0u, job);