]> git.ipfire.org Git - people/teissler/ipfire-2.x.git/blame - src/patches/suse-2.6.27.31/patches.suse/md-bitmap-sub-page-chunks
Revert "Disable build of xen kernel."
[people/teissler/ipfire-2.x.git] / src / patches / suse-2.6.27.31 / patches.suse / md-bitmap-sub-page-chunks
CommitLineData
00e5a55c
BS
1From: Neil Brown <neilb@suse.de>
2Subject: md: Allow write-intent bitmaps to have chunksize < PAGE_SIZE
3Patch-mainline: no
4References: 459557
5
6md currently insists that the chunk size used for write-intent
7bitmaps (the amount of data that corresponds to one chunk)
8be at least one page.
9
10The reason for this list restriction is lost in the mists of time,
11but a review of the code (and a vague memory) suggests that the only
12problem would be related to resync. Resync tries very hard to
13work in multiples of a page, but also needs to sync with units
14of a bitmap_chunk too.
15
16This connection comes out in the bitmap_start_sync call.
17
18So change bitmap_start_sync to always work in multiples of a page.
19If the bitmap chunk size is less that one page, we flag multiple
20chunks as 'syncing' and generally make them all appear to the
21resync routines like one chunk.
22
23All other code either already works with data ranges that could
24span multiple chunks, or explicitly only cares about a single chunk.
25
26This is needed because some architectures use 64K pages in SLES11
27where they used 4K pages in SLES10. So arrays created on SLES10
28might not work with SLES11 without this change.
29
30Also, the default chunk size is 4K, and so newly create arrays
31that use the default will not work.
32
33Signed-off-by: Neil Brown <neilb@suse.de>
34
35---
36 drivers/md/bitmap.c | 41 ++++++++++++++++++++++++++++++++---------
37 1 file changed, 32 insertions(+), 9 deletions(-)
38
39--- a/drivers/md/bitmap.c
40+++ b/drivers/md/bitmap.c
41@@ -110,13 +110,12 @@ static int bitmap_checkpage(struct bitma
42 {
43 unsigned char *mappage;
44
45- if (page >= bitmap->pages) {
46- printk(KERN_ALERT
47- "%s: invalid bitmap page request: %lu (> %lu)\n",
48- bmname(bitmap), page, bitmap->pages-1);
49+ if (page >= bitmap->pages)
50+ /* This can happen if bitmap_start_sync goes beyond
51+ * End-of-device while looking for a whole page.
52+ * It is harmless.
53+ */
54 return -EINVAL;
55- }
56-
57
58 if (bitmap->bp[page].hijacked) /* it's hijacked, don't try to alloc */
59 return 0;
60@@ -571,7 +570,7 @@ static int bitmap_read_sb(struct bitmap
61 else if (le32_to_cpu(sb->version) < BITMAP_MAJOR_LO ||
62 le32_to_cpu(sb->version) > BITMAP_MAJOR_HI)
63 reason = "unrecognized superblock version";
64- else if (chunksize < PAGE_SIZE)
65+ else if (chunksize < 512)
66 reason = "bitmap chunksize too small";
67 else if ((1 << ffz(~chunksize)) != chunksize)
68 reason = "bitmap chunksize not a power of 2";
69@@ -1347,8 +1346,8 @@ void bitmap_endwrite(struct bitmap *bitm
70 }
71 }
72
73-int bitmap_start_sync(struct bitmap *bitmap, sector_t offset, int *blocks,
74- int degraded)
75+static int __bitmap_start_sync(struct bitmap *bitmap, sector_t offset, int *blocks,
76+ int degraded)
77 {
78 bitmap_counter_t *bmc;
79 int rv;
80@@ -1376,6 +1375,30 @@ int bitmap_start_sync(struct bitmap *bit
81 return rv;
82 }
83
84+int bitmap_start_sync(struct bitmap *bitmap, sector_t offset, int *blocks,
85+ int degraded)
86+{
87+ /* bitmap_start_sync must always report on multiples of whole
88+ * pages, otherwise resync (which is very PAGE_SIZE based) will
89+ * get confused.
90+ * So call __bitmap_start_sync repeatedly (if needed) until
91+ * At least PAGE_SIZE>>9 blocks are covered.
92+ * Return the 'or' of the result.
93+ */
94+ int rv = 0;
95+ int blocks1;
96+
97+ *blocks = 0;
98+ while (*blocks < (PAGE_SIZE>>9)) {
99+ rv |= __bitmap_start_sync(bitmap, offset,
100+ &blocks1, degraded);
101+ offset += blocks1;
102+ *blocks += blocks1;
103+ }
104+ return rv;
105+}
106+
107+
108 void bitmap_end_sync(struct bitmap *bitmap, sector_t offset, int *blocks, int aborted)
109 {
110 bitmap_counter_t *bmc;