0001
0002
0003 #define RESYNC_BLOCK_SIZE (64*1024)
0004 #define RESYNC_PAGES ((RESYNC_BLOCK_SIZE + PAGE_SIZE-1) / PAGE_SIZE)
0005
0006
0007
0008
0009 #define NR_RAID_BIOS 256
0010
0011
0012
0013
0014
0015
0016 #define IO_BLOCKED ((struct bio *)1)
0017
0018
0019
0020
0021 #define IO_MADE_GOOD ((struct bio *)2)
0022
0023 #define BIO_SPECIAL(bio) ((unsigned long)bio <= 2)
0024
0025
0026 struct resync_pages {
0027 void *raid_bio;
0028 struct page *pages[RESYNC_PAGES];
0029 };
0030
0031 struct raid1_plug_cb {
0032 struct blk_plug_cb cb;
0033 struct bio_list pending;
0034 };
0035
0036 static void rbio_pool_free(void *rbio, void *data)
0037 {
0038 kfree(rbio);
0039 }
0040
0041 static inline int resync_alloc_pages(struct resync_pages *rp,
0042 gfp_t gfp_flags)
0043 {
0044 int i;
0045
0046 for (i = 0; i < RESYNC_PAGES; i++) {
0047 rp->pages[i] = alloc_page(gfp_flags);
0048 if (!rp->pages[i])
0049 goto out_free;
0050 }
0051
0052 return 0;
0053
0054 out_free:
0055 while (--i >= 0)
0056 put_page(rp->pages[i]);
0057 return -ENOMEM;
0058 }
0059
0060 static inline void resync_free_pages(struct resync_pages *rp)
0061 {
0062 int i;
0063
0064 for (i = 0; i < RESYNC_PAGES; i++)
0065 put_page(rp->pages[i]);
0066 }
0067
0068 static inline void resync_get_all_pages(struct resync_pages *rp)
0069 {
0070 int i;
0071
0072 for (i = 0; i < RESYNC_PAGES; i++)
0073 get_page(rp->pages[i]);
0074 }
0075
0076 static inline struct page *resync_fetch_page(struct resync_pages *rp,
0077 unsigned idx)
0078 {
0079 if (WARN_ON_ONCE(idx >= RESYNC_PAGES))
0080 return NULL;
0081 return rp->pages[idx];
0082 }
0083
0084
0085
0086
0087
0088 static inline struct resync_pages *get_resync_pages(struct bio *bio)
0089 {
0090 return bio->bi_private;
0091 }
0092
0093
0094 static void md_bio_reset_resync_pages(struct bio *bio, struct resync_pages *rp,
0095 int size)
0096 {
0097 int idx = 0;
0098
0099
0100 do {
0101 struct page *page = resync_fetch_page(rp, idx);
0102 int len = min_t(int, size, PAGE_SIZE);
0103
0104
0105
0106
0107
0108 bio_add_page(bio, page, len, 0);
0109 size -= len;
0110 } while (idx++ < RESYNC_PAGES && size > 0);
0111 }