diff options
Diffstat (limited to 'drivers/md/bitmap.c')
-rw-r--r-- | drivers/md/bitmap.c | 35 |
1 files changed, 33 insertions, 2 deletions
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c index 9620d452d030..ae94f3beb5fc 100644 --- a/drivers/md/bitmap.c +++ b/drivers/md/bitmap.c | |||
@@ -268,6 +268,31 @@ static int write_sb_page(struct bitmap *bitmap, struct page *page, int wait) | |||
268 | if (page->index == bitmap->file_pages-1) | 268 | if (page->index == bitmap->file_pages-1) |
269 | size = roundup(bitmap->last_page_size, | 269 | size = roundup(bitmap->last_page_size, |
270 | bdev_hardsect_size(rdev->bdev)); | 270 | bdev_hardsect_size(rdev->bdev)); |
271 | /* Just make sure we aren't corrupting data or | ||
272 | * metadata | ||
273 | */ | ||
274 | if (bitmap->offset < 0) { | ||
275 | /* DATA BITMAP METADATA */ | ||
276 | if (bitmap->offset | ||
277 | + page->index * (PAGE_SIZE/512) | ||
278 | + size/512 > 0) | ||
279 | /* bitmap runs in to metadata */ | ||
280 | return -EINVAL; | ||
281 | if (rdev->data_offset + mddev->size*2 | ||
282 | > rdev->sb_offset*2 + bitmap->offset) | ||
283 | /* data runs in to bitmap */ | ||
284 | return -EINVAL; | ||
285 | } else if (rdev->sb_offset*2 < rdev->data_offset) { | ||
286 | /* METADATA BITMAP DATA */ | ||
287 | if (rdev->sb_offset*2 | ||
288 | + bitmap->offset | ||
289 | + page->index*(PAGE_SIZE/512) + size/512 | ||
290 | > rdev->data_offset) | ||
291 | /* bitmap runs in to data */ | ||
292 | return -EINVAL; | ||
293 | } else { | ||
294 | /* DATA METADATA BITMAP - no problems */ | ||
295 | } | ||
271 | md_super_write(mddev, rdev, | 296 | md_super_write(mddev, rdev, |
272 | (rdev->sb_offset<<1) + bitmap->offset | 297 | (rdev->sb_offset<<1) + bitmap->offset |
273 | + page->index * (PAGE_SIZE/512), | 298 | + page->index * (PAGE_SIZE/512), |
@@ -287,8 +312,14 @@ static int write_page(struct bitmap *bitmap, struct page *page, int wait) | |||
287 | { | 312 | { |
288 | struct buffer_head *bh; | 313 | struct buffer_head *bh; |
289 | 314 | ||
290 | if (bitmap->file == NULL) | 315 | if (bitmap->file == NULL) { |
291 | return write_sb_page(bitmap, page, wait); | 316 | switch (write_sb_page(bitmap, page, wait)) { |
317 | case -EINVAL: | ||
318 | bitmap->flags |= BITMAP_WRITE_ERROR; | ||
319 | return -EIO; | ||
320 | } | ||
321 | return 0; | ||
322 | } | ||
292 | 323 | ||
293 | bh = page_buffers(page); | 324 | bh = page_buffers(page); |
294 | 325 | ||