1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 /* 3 * Copyright 2023 Red Hat 4 */ 5 6 #ifndef VDO_COMPLETION_H 7 #define VDO_COMPLETION_H 8 9 #include "permassert.h" 10 11 #include "status-codes.h" 12 #include "types.h" 13 14 /** 15 * vdo_run_completion() - Run a completion's callback or error handler on the current thread. 16 * 17 * Context: This function must be called from the correct callback thread. 18 */ 19 static inline void vdo_run_completion(struct vdo_completion *completion) 20 { 21 if ((completion->result != VDO_SUCCESS) && (completion->error_handler != NULL)) { 22 completion->error_handler(completion); 23 return; 24 } 25 26 completion->callback(completion); 27 } 28 29 void vdo_set_completion_result(struct vdo_completion *completion, int result); 30 31 void vdo_initialize_completion(struct vdo_completion *completion, struct vdo *vdo, 32 enum vdo_completion_type type); 33 34 /** 35 * vdo_reset_completion() - Reset a completion to a clean state, while keeping the type, vdo and 36 * parent information. 37 */ 38 static inline void vdo_reset_completion(struct vdo_completion *completion) 39 { 40 completion->result = VDO_SUCCESS; 41 completion->complete = false; 42 } 43 44 void vdo_launch_completion_with_priority(struct vdo_completion *completion, 45 enum vdo_completion_priority priority); 46 47 /** 48 * vdo_launch_completion() - Launch a completion with default priority. 49 */ 50 static inline void vdo_launch_completion(struct vdo_completion *completion) 51 { 52 vdo_launch_completion_with_priority(completion, VDO_WORK_Q_DEFAULT_PRIORITY); 53 } 54 55 /** 56 * vdo_continue_completion() - Continue processing a completion. 57 * @result: The current result (will not mask older errors). 58 * 59 * Continue processing a completion by setting the current result and calling 60 * vdo_launch_completion(). 61 */ 62 static inline void vdo_continue_completion(struct vdo_completion *completion, int result) 63 { 64 vdo_set_completion_result(completion, result); 65 vdo_launch_completion(completion); 66 } 67 68 void vdo_finish_completion(struct vdo_completion *completion); 69 70 /** 71 * vdo_fail_completion() - Set the result of a completion if it does not already have an error, 72 * then finish it. 73 */ 74 static inline void vdo_fail_completion(struct vdo_completion *completion, int result) 75 { 76 vdo_set_completion_result(completion, result); 77 vdo_finish_completion(completion); 78 } 79 80 /** 81 * vdo_assert_completion_type() - Assert that a completion is of the correct type. 82 * 83 * Return: VDO_SUCCESS or an error 84 */ 85 static inline int vdo_assert_completion_type(struct vdo_completion *completion, 86 enum vdo_completion_type expected) 87 { 88 return VDO_ASSERT(expected == completion->type, 89 "completion type should be %u, not %u", expected, 90 completion->type); 91 } 92 93 static inline void vdo_set_completion_callback(struct vdo_completion *completion, 94 vdo_action_fn callback, 95 thread_id_t callback_thread_id) 96 { 97 completion->callback = callback; 98 completion->callback_thread_id = callback_thread_id; 99 } 100 101 /** 102 * vdo_launch_completion_callback() - Set the callback for a completion and launch it immediately. 103 */ 104 static inline void vdo_launch_completion_callback(struct vdo_completion *completion, 105 vdo_action_fn callback, 106 thread_id_t callback_thread_id) 107 { 108 vdo_set_completion_callback(completion, callback, callback_thread_id); 109 vdo_launch_completion(completion); 110 } 111 112 /** 113 * vdo_prepare_completion() - Prepare a completion for launch. 114 * 115 * Resets the completion, and then sets its callback, error handler, callback thread, and parent. 116 */ 117 static inline void vdo_prepare_completion(struct vdo_completion *completion, 118 vdo_action_fn callback, 119 vdo_action_fn error_handler, 120 thread_id_t callback_thread_id, void *parent) 121 { 122 vdo_reset_completion(completion); 123 vdo_set_completion_callback(completion, callback, callback_thread_id); 124 completion->error_handler = error_handler; 125 completion->parent = parent; 126 } 127 128 /** 129 * vdo_prepare_completion_for_requeue() - Prepare a completion for launch ensuring that it will 130 * always be requeued. 131 * 132 * Resets the completion, and then sets its callback, error handler, callback thread, and parent. 133 */ 134 static inline void vdo_prepare_completion_for_requeue(struct vdo_completion *completion, 135 vdo_action_fn callback, 136 vdo_action_fn error_handler, 137 thread_id_t callback_thread_id, 138 void *parent) 139 { 140 vdo_prepare_completion(completion, callback, error_handler, 141 callback_thread_id, parent); 142 completion->requeue = true; 143 } 144 145 void vdo_enqueue_completion(struct vdo_completion *completion, 146 enum vdo_completion_priority priority); 147 148 149 bool vdo_requeue_completion_if_needed(struct vdo_completion *completion, 150 thread_id_t callback_thread_id); 151 152 #endif /* VDO_COMPLETION_H */ 153