Magellan Linux

Contents of /trunk/kernel26-magellan/patches-2.6.16-r12/0112-2.6.16.12-fix-kcopyd-destructor.patch

Parent Directory Parent Directory | Revision Log Revision Log


Revision 72 - (show annotations) (download)
Mon Jun 5 09:25:38 2006 UTC (17 years, 10 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);