diff options
Diffstat (limited to 'recipes-kernel/linux/linux-ti33x-psp-3.2/3.2.10/0085-dm-io-fix-discard-support.patch')
-rw-r--r-- | recipes-kernel/linux/linux-ti33x-psp-3.2/3.2.10/0085-dm-io-fix-discard-support.patch | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/recipes-kernel/linux/linux-ti33x-psp-3.2/3.2.10/0085-dm-io-fix-discard-support.patch b/recipes-kernel/linux/linux-ti33x-psp-3.2/3.2.10/0085-dm-io-fix-discard-support.patch new file mode 100644 index 00000000..b5ff74ad --- /dev/null +++ b/recipes-kernel/linux/linux-ti33x-psp-3.2/3.2.10/0085-dm-io-fix-discard-support.patch | |||
@@ -0,0 +1,86 @@ | |||
1 | From cf6db92080c563161f5626184902162432f5fac5 Mon Sep 17 00:00:00 2001 | ||
2 | From: Milan Broz <mbroz@redhat.com> | ||
3 | Date: Wed, 7 Mar 2012 19:09:37 +0000 | ||
4 | Subject: [PATCH 85/95] dm io: fix discard support | ||
5 | |||
6 | commit 0c535e0d6f463365c29623350dbd91642363c39b upstream. | ||
7 | |||
8 | This patch fixes a crash by recognising discards in dm_io. | ||
9 | |||
10 | Currently dm_mirror can send REQ_DISCARD bios if running over a | ||
11 | discard-enabled device and without support in dm_io the system | ||
12 | crashes badly. | ||
13 | |||
14 | BUG: unable to handle kernel paging request at 00800000 | ||
15 | IP: __bio_add_page.part.17+0xf5/0x1e0 | ||
16 | ... | ||
17 | bio_add_page+0x56/0x70 | ||
18 | dispatch_io+0x1cf/0x240 [dm_mod] | ||
19 | ? km_get_page+0x50/0x50 [dm_mod] | ||
20 | ? vm_next_page+0x20/0x20 [dm_mod] | ||
21 | ? mirror_flush+0x130/0x130 [dm_mirror] | ||
22 | dm_io+0xdc/0x2b0 [dm_mod] | ||
23 | ... | ||
24 | |||
25 | Introduced in 2.6.38-rc1 by commit 5fc2ffeabb9ee0fc0e71ff16b49f34f0ed3d05b4 | ||
26 | (dm raid1: support discard). | ||
27 | |||
28 | Signed-off-by: Milan Broz <mbroz@redhat.com> | ||
29 | Acked-by: Mike Snitzer <snitzer@redhat.com> | ||
30 | Signed-off-by: Alasdair G Kergon <agk@redhat.com> | ||
31 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | ||
32 | --- | ||
33 | drivers/md/dm-io.c | 23 ++++++++++++++++------- | ||
34 | 1 file changed, 16 insertions(+), 7 deletions(-) | ||
35 | |||
36 | diff --git a/drivers/md/dm-io.c b/drivers/md/dm-io.c | ||
37 | index ad2eba4..ea5dd28 100644 | ||
38 | --- a/drivers/md/dm-io.c | ||
39 | +++ b/drivers/md/dm-io.c | ||
40 | @@ -296,6 +296,8 @@ static void do_region(int rw, unsigned region, struct dm_io_region *where, | ||
41 | unsigned offset; | ||
42 | unsigned num_bvecs; | ||
43 | sector_t remaining = where->count; | ||
44 | + struct request_queue *q = bdev_get_queue(where->bdev); | ||
45 | + sector_t discard_sectors; | ||
46 | |||
47 | /* | ||
48 | * where->count may be zero if rw holds a flush and we need to | ||
49 | @@ -305,9 +307,12 @@ static void do_region(int rw, unsigned region, struct dm_io_region *where, | ||
50 | /* | ||
51 | * Allocate a suitably sized-bio. | ||
52 | */ | ||
53 | - num_bvecs = dm_sector_div_up(remaining, | ||
54 | - (PAGE_SIZE >> SECTOR_SHIFT)); | ||
55 | - num_bvecs = min_t(int, bio_get_nr_vecs(where->bdev), num_bvecs); | ||
56 | + if (rw & REQ_DISCARD) | ||
57 | + num_bvecs = 1; | ||
58 | + else | ||
59 | + num_bvecs = min_t(int, bio_get_nr_vecs(where->bdev), | ||
60 | + dm_sector_div_up(remaining, (PAGE_SIZE >> SECTOR_SHIFT))); | ||
61 | + | ||
62 | bio = bio_alloc_bioset(GFP_NOIO, num_bvecs, io->client->bios); | ||
63 | bio->bi_sector = where->sector + (where->count - remaining); | ||
64 | bio->bi_bdev = where->bdev; | ||
65 | @@ -315,10 +320,14 @@ static void do_region(int rw, unsigned region, struct dm_io_region *where, | ||
66 | bio->bi_destructor = dm_bio_destructor; | ||
67 | store_io_and_region_in_bio(bio, io, region); | ||
68 | |||
69 | - /* | ||
70 | - * Try and add as many pages as possible. | ||
71 | - */ | ||
72 | - while (remaining) { | ||
73 | + if (rw & REQ_DISCARD) { | ||
74 | + discard_sectors = min_t(sector_t, q->limits.max_discard_sectors, remaining); | ||
75 | + bio->bi_size = discard_sectors << SECTOR_SHIFT; | ||
76 | + remaining -= discard_sectors; | ||
77 | + } else while (remaining) { | ||
78 | + /* | ||
79 | + * Try and add as many pages as possible. | ||
80 | + */ | ||
81 | dp->get_page(dp, &page, &len, &offset); | ||
82 | len = min(len, to_bytes(remaining)); | ||
83 | if (!bio_add_page(bio, page, len, offset)) | ||
84 | -- | ||
85 | 1.7.9.4 | ||
86 | |||