Commit db873cfc7c0a6f34ab0f1c811fc245273adf35af
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.
Showing 1 changed file Side-by-side Diff
drivers/md/bitmap.c
... | ... | @@ -208,16 +208,19 @@ |
208 | 208 | */ |
209 | 209 | |
210 | 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 | 215 | /* choose a good rdev and read the page from there */ |
214 | 216 | |
215 | 217 | mdk_rdev_t *rdev; |
216 | 218 | struct list_head *tmp; |
217 | - struct page *page = alloc_page(GFP_KERNEL); | |
218 | 219 | sector_t target; |
219 | 220 | |
220 | 221 | if (!page) |
222 | + page = alloc_page(GFP_KERNEL); | |
223 | + if (!page) | |
221 | 224 | return ERR_PTR(-ENOMEM); |
222 | 225 | |
223 | 226 | rdev_for_each(rdev, tmp, mddev) { |
... | ... | @@ -227,7 +230,9 @@ |
227 | 230 | |
228 | 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 | 236 | page->index = index; |
232 | 237 | attach_page_buffers(page, NULL); /* so that free_buffer will |
233 | 238 | * quietly no-op */ |
... | ... | @@ -544,7 +549,9 @@ |
544 | 549 | |
545 | 550 | bitmap->sb_page = read_page(bitmap->file, 0, bitmap, bytes); |
546 | 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 | 556 | if (IS_ERR(bitmap->sb_page)) { |
550 | 557 | err = PTR_ERR(bitmap->sb_page); |
551 | 558 | |
... | ... | @@ -957,11 +964,16 @@ |
957 | 964 | */ |
958 | 965 | page = bitmap->sb_page; |
959 | 966 | offset = sizeof(bitmap_super_t); |
967 | + read_sb_page(bitmap->mddev, bitmap->offset, | |
968 | + page, | |
969 | + index, count); | |
960 | 970 | } else if (file) { |
961 | 971 | page = read_page(file, index, bitmap, count); |
962 | 972 | offset = 0; |
963 | 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 | 977 | offset = 0; |
966 | 978 | } |
967 | 979 | if (IS_ERR(page)) { /* read error */ |