1 /* SPDX-License-Identifier: GPL-2.0 */ 2 #ifndef _RAID5_LOG_H 3 #define _RAID5_LOG_H 4 5 int r5l_init_log(struct r5conf *conf, struct md_rdev *rdev); 6 void r5l_exit_log(struct r5conf *conf); 7 int r5l_write_stripe(struct r5l_log *log, struct stripe_head *head_sh); 8 void r5l_write_stripe_run(struct r5l_log *log); 9 void r5l_flush_stripe_to_raid(struct r5l_log *log); 10 void r5l_stripe_write_finished(struct stripe_head *sh); 11 int r5l_handle_flush_request(struct r5l_log *log, struct bio *bio); 12 void r5l_quiesce(struct r5l_log *log, int quiesce); 13 bool r5l_log_disk_error(struct r5conf *conf); 14 bool r5c_is_writeback(struct r5l_log *log); 15 int r5c_try_caching_write(struct r5conf *conf, struct stripe_head *sh, 16 struct stripe_head_state *s, int disks); 17 void r5c_finish_stripe_write_out(struct r5conf *conf, struct stripe_head *sh, 18 struct stripe_head_state *s); 19 void r5c_release_extra_page(struct stripe_head *sh); 20 void r5c_use_extra_page(struct stripe_head *sh); 21 void r5l_wake_reclaim(struct r5l_log *log, sector_t space); 22 void r5c_handle_cached_data_endio(struct r5conf *conf, 23 struct stripe_head *sh, int disks); 24 int r5c_cache_data(struct r5l_log *log, struct stripe_head *sh); 25 void r5c_make_stripe_write_out(struct stripe_head *sh); 26 void r5c_flush_cache(struct r5conf *conf, int num); 27 void r5c_check_stripe_cache_usage(struct r5conf *conf); 28 void r5c_check_cached_full_stripe(struct r5conf *conf); 29 extern struct md_sysfs_entry r5c_journal_mode; 30 void r5c_update_on_rdev_error(struct mddev *mddev, struct md_rdev *rdev); 31 bool r5c_big_stripe_cached(struct r5conf *conf, sector_t sect); 32 int r5l_start(struct r5l_log *log); 33 34 struct dma_async_tx_descriptor * 35 ops_run_partial_parity(struct stripe_head *sh, struct raid5_percpu *percpu, 36 struct dma_async_tx_descriptor *tx); 37 int ppl_init_log(struct r5conf *conf); 38 void ppl_exit_log(struct r5conf *conf); 39 int ppl_write_stripe(struct r5conf *conf, struct stripe_head *sh); 40 void ppl_write_stripe_run(struct r5conf *conf); 41 void ppl_stripe_write_finished(struct stripe_head *sh); 42 int ppl_modify_log(struct r5conf *conf, struct md_rdev *rdev, bool add); 43 void ppl_quiesce(struct r5conf *conf, int quiesce); 44 int ppl_handle_flush_request(struct bio *bio); 45 extern struct md_sysfs_entry ppl_write_hint; 46 47 static inline bool raid5_has_log(struct r5conf *conf) 48 { 49 return test_bit(MD_HAS_JOURNAL, &conf->mddev->flags); 50 } 51 52 static inline bool raid5_has_ppl(struct r5conf *conf) 53 { 54 return test_bit(MD_HAS_PPL, &conf->mddev->flags); 55 } 56 57 static inline int log_stripe(struct stripe_head *sh, struct stripe_head_state *s) 58 { 59 struct r5conf *conf = sh->raid_conf; 60 61 if (conf->log) { 62 if (!test_bit(STRIPE_R5C_CACHING, &sh->state)) { 63 /* writing out phase */ 64 if (s->waiting_extra_page) 65 return 0; 66 return r5l_write_stripe(conf->log, sh); 67 } else if (test_bit(STRIPE_LOG_TRAPPED, &sh->state)) { 68 /* caching phase */ 69 return r5c_cache_data(conf->log, sh); 70 } 71 } else if (raid5_has_ppl(conf)) { 72 return ppl_write_stripe(conf, sh); 73 } 74 75 return -EAGAIN; 76 } 77 78 static inline void log_stripe_write_finished(struct stripe_head *sh) 79 { 80 struct r5conf *conf = sh->raid_conf; 81 82 if (conf->log) 83 r5l_stripe_write_finished(sh); 84 else if (raid5_has_ppl(conf)) 85 ppl_stripe_write_finished(sh); 86 } 87 88 static inline void log_write_stripe_run(struct r5conf *conf) 89 { 90 if (conf->log) 91 r5l_write_stripe_run(conf->log); 92 else if (raid5_has_ppl(conf)) 93 ppl_write_stripe_run(conf); 94 } 95 96 static inline void log_flush_stripe_to_raid(struct r5conf *conf) 97 { 98 if (conf->log) 99 r5l_flush_stripe_to_raid(conf->log); 100 else if (raid5_has_ppl(conf)) 101 ppl_write_stripe_run(conf); 102 } 103 104 static inline int log_handle_flush_request(struct r5conf *conf, struct bio *bio) 105 { 106 int ret = -ENODEV; 107 108 if (conf->log) 109 ret = r5l_handle_flush_request(conf->log, bio); 110 else if (raid5_has_ppl(conf)) 111 ret = ppl_handle_flush_request(bio); 112 113 return ret; 114 } 115 116 static inline void log_quiesce(struct r5conf *conf, int quiesce) 117 { 118 if (conf->log) 119 r5l_quiesce(conf->log, quiesce); 120 else if (raid5_has_ppl(conf)) 121 ppl_quiesce(conf, quiesce); 122 } 123 124 static inline void log_exit(struct r5conf *conf) 125 { 126 if (conf->log) 127 r5l_exit_log(conf); 128 else if (raid5_has_ppl(conf)) 129 ppl_exit_log(conf); 130 } 131 132 static inline int log_init(struct r5conf *conf, struct md_rdev *journal_dev, 133 bool ppl) 134 { 135 if (journal_dev) 136 return r5l_init_log(conf, journal_dev); 137 else if (ppl) 138 return ppl_init_log(conf); 139 140 return 0; 141 } 142 143 static inline int log_modify(struct r5conf *conf, struct md_rdev *rdev, bool add) 144 { 145 if (raid5_has_ppl(conf)) 146 return ppl_modify_log(conf, rdev, add); 147 148 return 0; 149 } 150 151 #endif 152