Merge branch 'for-linus' of git://neil.brown.name/md

* 'for-linus' of git://neil.brown.name/md:
  md: Don't read past end of bitmap when reading bitmap.
This commit is contained in:
Linus Torvalds 2008-12-19 11:34:36 -08:00
commit db873cfc7c
1 changed files with 17 additions and 5 deletions

View File

@ -208,15 +208,18 @@ static void bitmap_checkfree(struct bitmap *bitmap, unsigned long page)
*/ */
/* IO operations when bitmap is stored near all superblocks */ /* IO operations when bitmap is stored near all superblocks */
static struct page *read_sb_page(mddev_t *mddev, long offset, unsigned long index) static struct page *read_sb_page(mddev_t *mddev, long offset,
struct page *page,
unsigned long index, int size)
{ {
/* choose a good rdev and read the page from there */ /* choose a good rdev and read the page from there */
mdk_rdev_t *rdev; mdk_rdev_t *rdev;
struct list_head *tmp; struct list_head *tmp;
struct page *page = alloc_page(GFP_KERNEL);
sector_t target; sector_t target;
if (!page)
page = alloc_page(GFP_KERNEL);
if (!page) if (!page)
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
@ -227,7 +230,9 @@ static struct page *read_sb_page(mddev_t *mddev, long offset, unsigned long inde
target = rdev->sb_start + offset + index * (PAGE_SIZE/512); target = rdev->sb_start + offset + index * (PAGE_SIZE/512);
if (sync_page_io(rdev->bdev, target, PAGE_SIZE, page, READ)) { if (sync_page_io(rdev->bdev, target,
roundup(size, bdev_hardsect_size(rdev->bdev)),
page, READ)) {
page->index = index; page->index = index;
attach_page_buffers(page, NULL); /* so that free_buffer will attach_page_buffers(page, NULL); /* so that free_buffer will
* quietly no-op */ * quietly no-op */
@ -544,7 +549,9 @@ static int bitmap_read_sb(struct bitmap *bitmap)
bitmap->sb_page = read_page(bitmap->file, 0, bitmap, bytes); bitmap->sb_page = read_page(bitmap->file, 0, bitmap, bytes);
} else { } else {
bitmap->sb_page = read_sb_page(bitmap->mddev, bitmap->offset, 0); bitmap->sb_page = read_sb_page(bitmap->mddev, bitmap->offset,
NULL,
0, sizeof(bitmap_super_t));
} }
if (IS_ERR(bitmap->sb_page)) { if (IS_ERR(bitmap->sb_page)) {
err = PTR_ERR(bitmap->sb_page); err = PTR_ERR(bitmap->sb_page);
@ -957,11 +964,16 @@ static int bitmap_init_from_disk(struct bitmap *bitmap, sector_t start)
*/ */
page = bitmap->sb_page; page = bitmap->sb_page;
offset = sizeof(bitmap_super_t); offset = sizeof(bitmap_super_t);
read_sb_page(bitmap->mddev, bitmap->offset,
page,
index, count);
} else if (file) { } else if (file) {
page = read_page(file, index, bitmap, count); page = read_page(file, index, bitmap, count);
offset = 0; offset = 0;
} else { } else {
page = read_sb_page(bitmap->mddev, bitmap->offset, index); page = read_sb_page(bitmap->mddev, bitmap->offset,
NULL,
index, count);
offset = 0; offset = 0;
} }
if (IS_ERR(page)) { /* read error */ if (IS_ERR(page)) { /* read error */