|
@@ -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 */
|