]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blob - src/patches/suse-2.6.27.25/patches.suse/dm-use-md-for-free_bio_clone
Updated xen patches taken from suse.
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.25 / patches.suse / dm-use-md-for-free_bio_clone
1 From: Hannes Reinecke <hare@suse.de>
2 Subject: Kernel oops in free_bio_clone()
3 References: bnc#472360
4
5 Bug is here:
6
7 static int setup_clone(struct request *clone, struct request *rq,
8 struct dm_rq_target_io *tio)
9 {
10 int r;
11
12 blk_rq_init(NULL, clone);
13
14 r = clone_request_bios(clone, rq, tio->md);
15 if (r)
16 return r;
17
18 copy_request_info(clone, rq);
19 clone->start_time = jiffies;
20 clone->end_io = end_clone_request;
21 clone->end_io_data = tio;
22
23 return 0;
24 }
25
26 clone_request_bios() might end up calling free_bio_clone(), which references:
27
28 static void free_bio_clone(struct request *clone)
29 {
30 struct dm_rq_target_io *tio = clone->end_io_data;
31 struct mapped_device *md = tio->md;
32 ...
33
34 but end_io_data will be set only _after_ the call to clone_request_bios().
35 So we should be passing the 'md' argument directly here to avoid this
36 bug and several pointless derefencings.
37
38 Signed-off-by: Hannes Reinecke <hare@suse.de>
39
40 --- linux-2.6.27-SLE11_BRANCH/drivers/md/dm.c.orig 2009-02-04 10:33:22.656627650 +0100
41 +++ linux-2.6.27-SLE11_BRANCH/drivers/md/dm.c 2009-02-05 11:03:35.843251773 +0100
42 @@ -709,10 +709,8 @@ static void end_clone_bio(struct bio *cl
43 blk_update_request(tio->orig, 0, nr_bytes);
44 }
45
46 -static void free_bio_clone(struct request *clone)
47 +static void free_bio_clone(struct request *clone, struct mapped_device *md)
48 {
49 - struct dm_rq_target_io *tio = clone->end_io_data;
50 - struct mapped_device *md = tio->md;
51 struct bio *bio;
52
53 while ((bio = clone->bio) != NULL) {
54 @@ -743,7 +741,7 @@ static void dm_unprep_request(struct req
55 rq->special = NULL;
56 rq->cmd_flags &= ~REQ_DONTPREP;
57
58 - free_bio_clone(clone);
59 + free_bio_clone(clone, tio->md);
60 dec_rq_pending(tio);
61 free_rq_tio(tio->md, tio);
62 }
63 @@ -820,7 +818,7 @@ static void dm_end_request(struct reques
64 rq->sense_len = clone->sense_len;
65 }
66
67 - free_bio_clone(clone);
68 + free_bio_clone(clone, tio->md);
69 dec_rq_pending(tio);
70 free_rq_tio(tio->md, tio);
71
72 @@ -1406,7 +1404,7 @@ static int clone_request_bios(struct req
73 return 0;
74
75 free_and_out:
76 - free_bio_clone(clone);
77 + free_bio_clone(clone, md);
78
79 return -ENOMEM;
80 }