linux/drivers/md/raid1-10.c
<<
>>
Prefs
   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 */
   7struct resync_pages {
   8        void            *raid_bio;
   9        struct page     *pages[RESYNC_PAGES];
  10};
  11
  12static 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
  25out_free:
  26        while (--i >= 0)
  27                put_page(rp->pages[i]);
  28        return -ENOMEM;
  29}
  30
  31static 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
  39static 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
  47static 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 */
  59static 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 */
  65static 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