diff options
Diffstat (limited to 'drivers/md/bitmap.c')
| -rw-r--r-- | drivers/md/bitmap.c | 22 | 
1 files changed, 17 insertions, 5 deletions
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c index ac89a5deaca..ab7c8e4a61f 100644 --- a/drivers/md/bitmap.c +++ b/drivers/md/bitmap.c  | |||
| @@ -208,16 +208,19 @@ static void bitmap_checkfree(struct bitmap *bitmap, unsigned long page) | |||
| 208 | */ | 208 | */ | 
| 209 | 209 | ||
| 210 | /* IO operations when bitmap is stored near all superblocks */ | 210 | /* IO operations when bitmap is stored near all superblocks */ | 
| 211 | static struct page *read_sb_page(mddev_t *mddev, long offset, unsigned long index) | 211 | static struct page *read_sb_page(mddev_t *mddev, long offset, | 
| 212 | struct page *page, | ||
| 213 | unsigned long index, int size) | ||
| 212 | { | 214 | { | 
| 213 | /* choose a good rdev and read the page from there */ | 215 | /* choose a good rdev and read the page from there */ | 
| 214 | 216 | ||
| 215 | mdk_rdev_t *rdev; | 217 | mdk_rdev_t *rdev; | 
| 216 | struct list_head *tmp; | 218 | struct list_head *tmp; | 
| 217 | struct page *page = alloc_page(GFP_KERNEL); | ||
| 218 | sector_t target; | 219 | sector_t target; | 
| 219 | 220 | ||
| 220 | if (!page) | 221 | if (!page) | 
| 222 | page = alloc_page(GFP_KERNEL); | ||
| 223 | if (!page) | ||
| 221 | return ERR_PTR(-ENOMEM); | 224 | return ERR_PTR(-ENOMEM); | 
| 222 | 225 | ||
| 223 | rdev_for_each(rdev, tmp, mddev) { | 226 | rdev_for_each(rdev, tmp, mddev) { | 
| @@ -227,7 +230,9 @@ static struct page *read_sb_page(mddev_t *mddev, long offset, unsigned long inde | |||
| 227 | 230 | ||
| 228 | target = rdev->sb_start + offset + index * (PAGE_SIZE/512); | 231 | target = rdev->sb_start + offset + index * (PAGE_SIZE/512); | 
| 229 | 232 | ||
| 230 | if (sync_page_io(rdev->bdev, target, PAGE_SIZE, page, READ)) { | 233 | if (sync_page_io(rdev->bdev, target, | 
| 234 | roundup(size, bdev_hardsect_size(rdev->bdev)), | ||
| 235 | page, READ)) { | ||
| 231 | page->index = index; | 236 | page->index = index; | 
| 232 | attach_page_buffers(page, NULL); /* so that free_buffer will | 237 | attach_page_buffers(page, NULL); /* so that free_buffer will | 
| 233 | * quietly no-op */ | 238 | * quietly no-op */ | 
| @@ -544,7 +549,9 @@ static int bitmap_read_sb(struct bitmap *bitmap) | |||
| 544 | 549 | ||
| 545 | bitmap->sb_page = read_page(bitmap->file, 0, bitmap, bytes); | 550 | bitmap->sb_page = read_page(bitmap->file, 0, bitmap, bytes); | 
| 546 | } else { | 551 | } else { | 
| 547 | bitmap->sb_page = read_sb_page(bitmap->mddev, bitmap->offset, 0); | 552 | bitmap->sb_page = read_sb_page(bitmap->mddev, bitmap->offset, | 
| 553 | NULL, | ||
| 554 | 0, sizeof(bitmap_super_t)); | ||
| 548 | } | 555 | } | 
| 549 | if (IS_ERR(bitmap->sb_page)) { | 556 | if (IS_ERR(bitmap->sb_page)) { | 
| 550 | err = PTR_ERR(bitmap->sb_page); | 557 | err = PTR_ERR(bitmap->sb_page); | 
| @@ -957,11 +964,16 @@ static int bitmap_init_from_disk(struct bitmap *bitmap, sector_t start) | |||
| 957 | */ | 964 | */ | 
| 958 | page = bitmap->sb_page; | 965 | page = bitmap->sb_page; | 
| 959 | offset = sizeof(bitmap_super_t); | 966 | offset = sizeof(bitmap_super_t); | 
| 967 | read_sb_page(bitmap->mddev, bitmap->offset, | ||
| 968 | page, | ||
| 969 | index, count); | ||
| 960 | } else if (file) { | 970 | } else if (file) { | 
| 961 | page = read_page(file, index, bitmap, count); | 971 | page = read_page(file, index, bitmap, count); | 
| 962 | offset = 0; | 972 | offset = 0; | 
| 963 | } else { | 973 | } else { | 
| 964 | page = read_sb_page(bitmap->mddev, bitmap->offset, index); | 974 | page = read_sb_page(bitmap->mddev, bitmap->offset, | 
| 975 | NULL, | ||
| 976 | index, count); | ||
| 965 | offset = 0; | 977 | offset = 0; | 
| 966 | } | 978 | } | 
| 967 | if (IS_ERR(page)) { /* read error */ | 979 | if (IS_ERR(page)) { /* read error */ | 
