|
@@ -268,6 +268,31 @@ static int write_sb_page(struct bitmap *bitmap, struct page *page, int wait)
|
|
if (page->index == bitmap->file_pages-1)
|
|
if (page->index == bitmap->file_pages-1)
|
|
size = roundup(bitmap->last_page_size,
|
|
size = roundup(bitmap->last_page_size,
|
|
bdev_hardsect_size(rdev->bdev));
|
|
bdev_hardsect_size(rdev->bdev));
|
|
|
|
+ /* Just make sure we aren't corrupting data or
|
|
|
|
+ * metadata
|
|
|
|
+ */
|
|
|
|
+ if (bitmap->offset < 0) {
|
|
|
|
+ /* DATA BITMAP METADATA */
|
|
|
|
+ if (bitmap->offset
|
|
|
|
+ + page->index * (PAGE_SIZE/512)
|
|
|
|
+ + size/512 > 0)
|
|
|
|
+ /* bitmap runs in to metadata */
|
|
|
|
+ return -EINVAL;
|
|
|
|
+ if (rdev->data_offset + mddev->size*2
|
|
|
|
+ > rdev->sb_offset*2 + bitmap->offset)
|
|
|
|
+ /* data runs in to bitmap */
|
|
|
|
+ return -EINVAL;
|
|
|
|
+ } else if (rdev->sb_offset*2 < rdev->data_offset) {
|
|
|
|
+ /* METADATA BITMAP DATA */
|
|
|
|
+ if (rdev->sb_offset*2
|
|
|
|
+ + bitmap->offset
|
|
|
|
+ + page->index*(PAGE_SIZE/512) + size/512
|
|
|
|
+ > rdev->data_offset)
|
|
|
|
+ /* bitmap runs in to data */
|
|
|
|
+ return -EINVAL;
|
|
|
|
+ } else {
|
|
|
|
+ /* DATA METADATA BITMAP - no problems */
|
|
|
|
+ }
|
|
md_super_write(mddev, rdev,
|
|
md_super_write(mddev, rdev,
|
|
(rdev->sb_offset<<1) + bitmap->offset
|
|
(rdev->sb_offset<<1) + bitmap->offset
|
|
+ page->index * (PAGE_SIZE/512),
|
|
+ page->index * (PAGE_SIZE/512),
|
|
@@ -287,8 +312,14 @@ static int write_page(struct bitmap *bitmap, struct page *page, int wait)
|
|
{
|
|
{
|
|
struct buffer_head *bh;
|
|
struct buffer_head *bh;
|
|
|
|
|
|
- if (bitmap->file == NULL)
|
|
|
|
- return write_sb_page(bitmap, page, wait);
|
|
|
|
|
|
+ if (bitmap->file == NULL) {
|
|
|
|
+ switch (write_sb_page(bitmap, page, wait)) {
|
|
|
|
+ case -EINVAL:
|
|
|
|
+ bitmap->flags |= BITMAP_WRITE_ERROR;
|
|
|
|
+ return -EIO;
|
|
|
|
+ }
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
|
|
bh = page_buffers(page);
|
|
bh = page_buffers(page);
|
|
|
|
|