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 */ 19static 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 29void vdo_set_completion_result(struct vdo_completion *completion, int result); 30 31void 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 */ 38static inline void vdo_reset_completion(struct vdo_completion *completion) 39{ 40 completion->result = VDO_SUCCESS; 41 completion->complete = false; 42} 43 44void 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 */ 50static 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 */ 62static 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 68void 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 */ 74static 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 */ 85static 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 93static 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 */ 104static 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 */ 117static 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 */ 134static 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 145void vdo_enqueue_completion(struct vdo_completion *completion, 146 enum vdo_completion_priority priority); 147 148 149bool vdo_requeue_completion_if_needed(struct vdo_completion *completion, 150 thread_id_t callback_thread_id); 151 152#endif /* VDO_COMPLETION_H */ 153