Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /* Maximum size of each resync request */
0003 #define RESYNC_BLOCK_SIZE (64*1024)
0004 #define RESYNC_PAGES ((RESYNC_BLOCK_SIZE + PAGE_SIZE-1) / PAGE_SIZE)
0005 
0006 /*
0007  * Number of guaranteed raid bios in case of extreme VM load:
0008  */
0009 #define NR_RAID_BIOS 256
0010 
0011 /* when we get a read error on a read-only array, we redirect to another
0012  * device without failing the first device, or trying to over-write to
0013  * correct the read error.  To keep track of bad blocks on a per-bio
0014  * level, we store IO_BLOCKED in the appropriate 'bios' pointer
0015  */
0016 #define IO_BLOCKED ((struct bio *)1)
0017 /* When we successfully write to a known bad-block, we need to remove the
0018  * bad-block marking which must be done from process context.  So we record
0019  * the success by setting devs[n].bio to IO_MADE_GOOD
0020  */
0021 #define IO_MADE_GOOD ((struct bio *)2)
0022 
0023 #define BIO_SPECIAL(bio) ((unsigned long)bio <= 2)
0024 
0025 /* for managing resync I/O pages */
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  * 'strct resync_pages' stores actual pages used for doing the resync
0086  *  IO, and it is per-bio, so make .bi_private points to it.
0087  */
0088 static inline struct resync_pages *get_resync_pages(struct bio *bio)
0089 {
0090     return bio->bi_private;
0091 }
0092 
0093 /* generally called after bio_reset() for reseting bvec */
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     /* initialize bvec table again */
0100     do {
0101         struct page *page = resync_fetch_page(rp, idx);
0102         int len = min_t(int, size, PAGE_SIZE);
0103 
0104         /*
0105          * won't fail because the vec table is big
0106          * enough to hold all these pages
0107          */
0108         bio_add_page(bio, page, len, 0);
0109         size -= len;
0110     } while (idx++ < RESYNC_PAGES && size > 0);
0111 }