1/* SPDX-License-Identifier: GPL-2.0 */ 2#ifndef _RAID5_LOG_H 3#define _RAID5_LOG_H 4 5int r5l_init_log(struct r5conf *conf, struct md_rdev *rdev); 6void r5l_exit_log(struct r5conf *conf); 7int r5l_write_stripe(struct r5l_log *log, struct stripe_head *head_sh); 8void r5l_write_stripe_run(struct r5l_log *log); 9void r5l_flush_stripe_to_raid(struct r5l_log *log); 10void r5l_stripe_write_finished(struct stripe_head *sh); 11int r5l_handle_flush_request(struct r5l_log *log, struct bio *bio); 12void r5l_quiesce(struct r5l_log *log, int quiesce); 13bool r5l_log_disk_error(struct r5conf *conf); 14bool r5c_is_writeback(struct r5l_log *log); 15int r5c_try_caching_write(struct r5conf *conf, struct stripe_head *sh, 16 struct stripe_head_state *s, int disks); 17void r5c_finish_stripe_write_out(struct r5conf *conf, struct stripe_head *sh, 18 struct stripe_head_state *s); 19void r5c_release_extra_page(struct stripe_head *sh); 20void r5c_use_extra_page(struct stripe_head *sh); 21void r5l_wake_reclaim(struct r5l_log *log, sector_t space); 22void r5c_handle_cached_data_endio(struct r5conf *conf, 23 struct stripe_head *sh, int disks); 24int r5c_cache_data(struct r5l_log *log, struct stripe_head *sh); 25void r5c_make_stripe_write_out(struct stripe_head *sh); 26void r5c_flush_cache(struct r5conf *conf, int num); 27void r5c_check_stripe_cache_usage(struct r5conf *conf); 28void r5c_check_cached_full_stripe(struct r5conf *conf); 29extern struct md_sysfs_entry r5c_journal_mode; 30void r5c_update_on_rdev_error(struct mddev *mddev, struct md_rdev *rdev); 31bool r5c_big_stripe_cached(struct r5conf *conf, sector_t sect); 32int r5l_start(struct r5l_log *log); 33 34struct dma_async_tx_descriptor * 35ops_run_partial_parity(struct stripe_head *sh, struct raid5_percpu *percpu, 36 struct dma_async_tx_descriptor *tx); 37int ppl_init_log(struct r5conf *conf); 38void ppl_exit_log(struct r5conf *conf); 39int ppl_write_stripe(struct r5conf *conf, struct stripe_head *sh); 40void ppl_write_stripe_run(struct r5conf *conf); 41void ppl_stripe_write_finished(struct stripe_head *sh); 42int ppl_modify_log(struct r5conf *conf, struct md_rdev *rdev, bool add); 43void ppl_quiesce(struct r5conf *conf, int quiesce); 44int ppl_handle_flush_request(struct bio *bio); 45extern struct md_sysfs_entry ppl_write_hint; 46 47static inline bool raid5_has_log(struct r5conf *conf) 48{ 49 return test_bit(MD_HAS_JOURNAL, &conf->mddev->flags); 50} 51 52static inline bool raid5_has_ppl(struct r5conf *conf) 53{ 54 return test_bit(MD_HAS_PPL, &conf->mddev->flags); 55} 56 57static 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 78static 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 88static 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 96static 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 104static 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 116static 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 124static 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 132static 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 143static 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