summaryrefslogtreecommitdiff
path: root/drivers/md/dm-vdo/completion.h
blob: 3407f34ce58c9c0116cf8b6af3d6c4711d874de8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Copyright 2023 Red Hat
 */

#ifndef VDO_COMPLETION_H
#define VDO_COMPLETION_H

#include "permassert.h"

#include "status-codes.h"
#include "types.h"

/**
 * vdo_run_completion() - Run a completion's callback or error handler on the current thread.
 *
 * Context: This function must be called from the correct callback thread.
 */
static inline void vdo_run_completion(struct vdo_completion *completion)
{
	if ((completion->result != VDO_SUCCESS) && (completion->error_handler != NULL)) {
		completion->error_handler(completion);
		return;
	}

	completion->callback(completion);
}

void vdo_set_completion_result(struct vdo_completion *completion, int result);

void vdo_initialize_completion(struct vdo_completion *completion, struct vdo *vdo,
			       enum vdo_completion_type type);

/**
 * vdo_reset_completion() - Reset a completion to a clean state, while keeping the type, vdo and
 *                          parent information.
 */
static inline void vdo_reset_completion(struct vdo_completion *completion)
{
	completion->result = VDO_SUCCESS;
	completion->complete = false;
}

void vdo_launch_completion_with_priority(struct vdo_completion *completion,
					 enum vdo_completion_priority priority);

/**
 * vdo_launch_completion() - Launch a completion with default priority.
 */
static inline void vdo_launch_completion(struct vdo_completion *completion)
{
	vdo_launch_completion_with_priority(completion, VDO_WORK_Q_DEFAULT_PRIORITY);
}

/**
 * vdo_continue_completion() - Continue processing a completion.
 * @result: The current result (will not mask older errors).
 *
 * Continue processing a completion by setting the current result and calling
 * vdo_launch_completion().
 */
static inline void vdo_continue_completion(struct vdo_completion *completion, int result)
{
	vdo_set_completion_result(completion, result);
	vdo_launch_completion(completion);
}

void vdo_finish_completion(struct vdo_completion *completion);

/**
 * vdo_fail_completion() - Set the result of a completion if it does not already have an error,
 *                         then finish it.
 */
static inline void vdo_fail_completion(struct vdo_completion *completion, int result)
{
	vdo_set_completion_result(completion, result);
	vdo_finish_completion(completion);
}

/**
 * vdo_assert_completion_type() - Assert that a completion is of the correct type.
 *
 * Return: VDO_SUCCESS or an error
 */
static inline int vdo_assert_completion_type(struct vdo_completion *completion,
					     enum vdo_completion_type expected)
{
	return VDO_ASSERT(expected == completion->type,
			  "completion type should be %u, not %u", expected,
			  completion->type);
}

static inline void vdo_set_completion_callback(struct vdo_completion *completion,
					       vdo_action_fn callback,
					       thread_id_t callback_thread_id)
{
	completion->callback = callback;
	completion->callback_thread_id = callback_thread_id;
}

/**
 * vdo_launch_completion_callback() - Set the callback for a completion and launch it immediately.
 */
static inline void vdo_launch_completion_callback(struct vdo_completion *completion,
						  vdo_action_fn callback,
						  thread_id_t callback_thread_id)
{
	vdo_set_completion_callback(completion, callback, callback_thread_id);
	vdo_launch_completion(completion);
}

/**
 * vdo_prepare_completion() - Prepare a completion for launch.
 *
 * Resets the completion, and then sets its callback, error handler, callback thread, and parent.
 */
static inline void vdo_prepare_completion(struct vdo_completion *completion,
					  vdo_action_fn callback,
					  vdo_action_fn error_handler,
					  thread_id_t callback_thread_id, void *parent)
{
	vdo_reset_completion(completion);
	vdo_set_completion_callback(completion, callback, callback_thread_id);
	completion->error_handler = error_handler;
	completion->parent = parent;
}

/**
 * vdo_prepare_completion_for_requeue() - Prepare a completion for launch ensuring that it will
 *                                        always be requeued.
 *
 * Resets the completion, and then sets its callback, error handler, callback thread, and parent.
 */
static inline void vdo_prepare_completion_for_requeue(struct vdo_completion *completion,
						      vdo_action_fn callback,
						      vdo_action_fn error_handler,
						      thread_id_t callback_thread_id,
						      void *parent)
{
	vdo_prepare_completion(completion, callback, error_handler,
			       callback_thread_id, parent);
	completion->requeue = true;
}

void vdo_enqueue_completion(struct vdo_completion *completion,
			    enum vdo_completion_priority priority);


bool vdo_requeue_completion_if_needed(struct vdo_completion *completion,
				      thread_id_t callback_thread_id);

#endif /* VDO_COMPLETION_H */