1 // SPDX-License-Identifier: GPL-2.0 2 /* Maximum size of each resync request */ 3 #define RESYNC_BLOCK_SIZE (64*1024) 4 #define RESYNC_PAGES ((RESYNC_BLOCK_SIZE + PAGE_SIZE-1) / PAGE_SIZE) 5 6 /* for managing resync I/O pages */ 7 struct resync_pages { 8 void *raid_bio; 9 struct page *pages[RESYNC_PAGES]; 10 }; 11 12 static inline int resync_alloc_pages(struct resync_pages *rp, 13 gfp_t gfp_flags) 14 { 15 int i; 16 17 for (i = 0; i < RESYNC_PAGES; i++) { 18 rp->pages[i] = alloc_page(gfp_flags); 19 if (!rp->pages[i]) 20 goto out_free; 21 } 22 23 return 0; 24 25 out_free: 26 while (--i >= 0) 27 put_page(rp->pages[i]); 28 return -ENOMEM; 29 } 30 31 static inline void resync_free_pages(struct resync_pages *rp) 32 { 33 int i; 34 35 for (i = 0; i < RESYNC_PAGES; i++) 36 put_page(rp->pages[i]); 37 } 38 39 static inline void resync_get_all_pages(struct resync_pages *rp) 40 { 41 int i; 42 43 for (i = 0; i < RESYNC_PAGES; i++) 44 get_page(rp->pages[i]); 45 } 46 47 static inline struct page *resync_fetch_page(struct resync_pages *rp, 48 unsigned idx) 49 { 50 if (WARN_ON_ONCE(idx >= RESYNC_PAGES)) 51 return NULL; 52 return rp->pages[idx]; 53 } 54 55 /* 56 * 'strct resync_pages' stores actual pages used for doing the resync 57 * IO, and it is per-bio, so make .bi_private points to it. 58 */ 59 static inline struct resync_pages *get_resync_pages(struct bio *bio) 60 { 61 return bio->bi_private; 62 } 63 64 /* generally called after bio_reset() for reseting bvec */ 65 static void md_bio_reset_resync_pages(struct bio *bio, struct resync_pages *rp, 66 int size) 67 { 68 int idx = 0; 69 70 /* initialize bvec table again */ 71 do { 72 struct page *page = resync_fetch_page(rp, idx); 73 int len = min_t(int, size, PAGE_SIZE); 74 75 /* 76 * won't fail because the vec table is big 77 * enough to hold all these pages 78 */ 79 bio_add_page(bio, page, len, 0); 80 size -= len; 81 } while (idx++ < RESYNC_PAGES && size > 0); 82 } 83