Contents of /trunk/kernel26-magellan/patches-2.6.16-r12/0112-2.6.16.12-fix-kcopyd-destructor.patch
Parent Directory | Revision Log
Revision 72 -
(show annotations)
(download)
Mon Jun 5 09:25:38 2006 UTC (18 years, 3 months ago) by niro
File size: 3122 byte(s)
Mon Jun 5 09:25:38 2006 UTC (18 years, 3 months ago) by niro
File size: 3122 byte(s)
ver bump to 2.6.16-r12: - updated to linux-2.6.16.19 - updated to ck11
1 | From: Alasdair G Kergon <agk@redhat.com> |
2 | Date: Mon, 24 Apr 2006 20:36:06 +0000 (-0700) |
3 | Subject: [PATCH] dm snapshot: fix kcopyd destructor |
4 | X-Git-Url: http://www.kernel.org/git/?p=linux/kernel/git/stable/linux-2.6.16.y.git;a=commitdiff;h=f6a731290ca18b31fd447989319eb913d9c308d8 |
5 | |
6 | [PATCH] dm snapshot: fix kcopyd destructor |
7 | |
8 | Before removing a snapshot, wait for the completion of any kcopyd jobs using |
9 | it. |
10 | |
11 | Do this by maintaining a count (nr_jobs) of how many outstanding jobs each |
12 | kcopyd_client has. |
13 | |
14 | The snapshot destructor first unregisters the snapshot so that no new kcopyd |
15 | jobs (created by writes to the origin) will reference that particular |
16 | snapshot. kcopyd_client_destroy() is now run next to wait for the completion |
17 | of any outstanding jobs before the snapshot exception structures (that those |
18 | jobs reference) are freed. |
19 | |
20 | Signed-off-by: Alasdair G Kergon <agk@redhat.com> |
21 | Signed-off-by: Andrew Morton <akpm@osdl.org> |
22 | Signed-off-by: Linus Torvalds <torvalds@osdl.org> |
23 | Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> |
24 | --- |
25 | |
26 | --- a/drivers/md/dm-snap.c |
27 | +++ b/drivers/md/dm-snap.c |
28 | @@ -542,8 +542,12 @@ static void snapshot_dtr(struct dm_targe |
29 | { |
30 | struct dm_snapshot *s = (struct dm_snapshot *) ti->private; |
31 | |
32 | + /* Prevent further origin writes from using this snapshot. */ |
33 | + /* After this returns there can be no new kcopyd jobs. */ |
34 | unregister_snapshot(s); |
35 | |
36 | + kcopyd_client_destroy(s->kcopyd_client); |
37 | + |
38 | exit_exception_table(&s->pending, pending_cache); |
39 | exit_exception_table(&s->complete, exception_cache); |
40 | |
41 | @@ -552,7 +556,7 @@ static void snapshot_dtr(struct dm_targe |
42 | |
43 | dm_put_device(ti, s->origin); |
44 | dm_put_device(ti, s->cow); |
45 | - kcopyd_client_destroy(s->kcopyd_client); |
46 | + |
47 | kfree(s); |
48 | } |
49 | |
50 | --- a/drivers/md/kcopyd.c |
51 | +++ b/drivers/md/kcopyd.c |
52 | @@ -44,6 +44,9 @@ struct kcopyd_client { |
53 | struct page_list *pages; |
54 | unsigned int nr_pages; |
55 | unsigned int nr_free_pages; |
56 | + |
57 | + wait_queue_head_t destroyq; |
58 | + atomic_t nr_jobs; |
59 | }; |
60 | |
61 | static struct page_list *alloc_pl(void) |
62 | @@ -293,10 +296,15 @@ static int run_complete_job(struct kcopy |
63 | int read_err = job->read_err; |
64 | unsigned int write_err = job->write_err; |
65 | kcopyd_notify_fn fn = job->fn; |
66 | + struct kcopyd_client *kc = job->kc; |
67 | |
68 | - kcopyd_put_pages(job->kc, job->pages); |
69 | + kcopyd_put_pages(kc, job->pages); |
70 | mempool_free(job, _job_pool); |
71 | fn(read_err, write_err, context); |
72 | + |
73 | + if (atomic_dec_and_test(&kc->nr_jobs)) |
74 | + wake_up(&kc->destroyq); |
75 | + |
76 | return 0; |
77 | } |
78 | |
79 | @@ -431,6 +439,7 @@ static void do_work(void *ignored) |
80 | */ |
81 | static void dispatch_job(struct kcopyd_job *job) |
82 | { |
83 | + atomic_inc(&job->kc->nr_jobs); |
84 | push(&_pages_jobs, job); |
85 | wake(); |
86 | } |
87 | @@ -670,6 +679,9 @@ int kcopyd_client_create(unsigned int nr |
88 | return r; |
89 | } |
90 | |
91 | + init_waitqueue_head(&kc->destroyq); |
92 | + atomic_set(&kc->nr_jobs, 0); |
93 | + |
94 | client_add(kc); |
95 | *result = kc; |
96 | return 0; |
97 | @@ -677,6 +689,9 @@ int kcopyd_client_create(unsigned int nr |
98 | |
99 | void kcopyd_client_destroy(struct kcopyd_client *kc) |
100 | { |
101 | + /* Wait for completion of all jobs submitted by this client. */ |
102 | + wait_event(kc->destroyq, !atomic_read(&kc->nr_jobs)); |
103 | + |
104 | dm_io_put(kc->nr_pages); |
105 | client_free_pages(kc); |
106 | client_del(kc); |