Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

md: remove 'idx' from 'struct resync_pages'

bio_add_page() won't fail for resync bio, and the page index for each
bio is same, so remove it.

More importantly the 'idx' of 'struct resync_pages' is initialized in
mempool allocator function, the current way is wrong since mempool is
only responsible for allocation, we can't use that for initialization.

Suggested-by: NeilBrown <neilb@suse.com>
Reported-by: NeilBrown <neilb@suse.com>
Reported-and-tested-by: Patrick <dto@gmx.net>
Fixes: f0250618361d(md: raid10: don't use bio's vec table to manage resync pages)
Fixes: 98d30c5812c3(md: raid1: don't use bio's vec table to manage resync pages)
Cc: stable@vger.kernel.org (4.12+)
Signed-off-by: Ming Lei <ming.lei@redhat.com>
Signed-off-by: Shaohua Li <shli@fb.com>

authored by

Ming Lei and committed by
Shaohua Li
022e510f 4ec9f7a1

+6 -7
-1
drivers/md/md.h
··· 738 738 739 739 /* for managing resync I/O pages */ 740 740 struct resync_pages { 741 - unsigned idx; /* for get/put page from the pool */ 742 741 void *raid_bio; 743 742 struct page *pages[RESYNC_PAGES]; 744 743 };
+3 -3
drivers/md/raid1.c
··· 170 170 resync_get_all_pages(rp); 171 171 } 172 172 173 - rp->idx = 0; 174 173 rp->raid_bio = r1_bio; 175 174 bio->bi_private = rp; 176 175 } ··· 2618 2619 int good_sectors = RESYNC_SECTORS; 2619 2620 int min_bad = 0; /* number of sectors that are bad in all devices */ 2620 2621 int idx = sector_to_idx(sector_nr); 2622 + int page_idx = 0; 2621 2623 2622 2624 if (!conf->r1buf_pool) 2623 2625 if (init_resync(conf)) ··· 2846 2846 bio = r1_bio->bios[i]; 2847 2847 rp = get_resync_pages(bio); 2848 2848 if (bio->bi_end_io) { 2849 - page = resync_fetch_page(rp, rp->idx++); 2849 + page = resync_fetch_page(rp, page_idx); 2850 2850 2851 2851 /* 2852 2852 * won't fail because the vec table is big ··· 2858 2858 nr_sectors += len>>9; 2859 2859 sector_nr += len>>9; 2860 2860 sync_blocks -= (len>>9); 2861 - } while (get_resync_pages(r1_bio->bios[disk]->bi_private)->idx < RESYNC_PAGES); 2861 + } while (++page_idx < RESYNC_PAGES); 2862 2862 2863 2863 r1_bio->sectors = nr_sectors; 2864 2864
+3 -3
drivers/md/raid10.c
··· 221 221 resync_get_all_pages(rp); 222 222 } 223 223 224 - rp->idx = 0; 225 224 rp->raid_bio = r10_bio; 226 225 bio->bi_private = rp; 227 226 if (rbio) { ··· 2852 2853 sector_t sectors_skipped = 0; 2853 2854 int chunks_skipped = 0; 2854 2855 sector_t chunk_mask = conf->geo.chunk_mask; 2856 + int page_idx = 0; 2855 2857 2856 2858 if (!conf->r10buf_pool) 2857 2859 if (init_resync(conf)) ··· 3355 3355 break; 3356 3356 for (bio= biolist ; bio ; bio=bio->bi_next) { 3357 3357 struct resync_pages *rp = get_resync_pages(bio); 3358 - page = resync_fetch_page(rp, rp->idx++); 3358 + page = resync_fetch_page(rp, page_idx); 3359 3359 /* 3360 3360 * won't fail because the vec table is big enough 3361 3361 * to hold all these pages ··· 3364 3364 } 3365 3365 nr_sectors += len>>9; 3366 3366 sector_nr += len>>9; 3367 - } while (get_resync_pages(biolist)->idx < RESYNC_PAGES); 3367 + } while (++page_idx < RESYNC_PAGES); 3368 3368 r10_bio->sectors = nr_sectors; 3369 3369 3370 3370 while (biolist) {