raid1-10.c 1.8 KB

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