76
{
77
bool fixed_iothread = export->has_fixed_iothread && export->fixed_iothread;
78
bool allow_inactive = export->has_allow_inactive && export->allow_inactive;
79
+ bool multithread = export->iothread &&
80
+ export->iothread->type == QTYPE_QLIST;
81
const BlockExportDriver *drv;
82
BlockExport *exp = NULL;
83
BlockDriverState *bs;
84
BlockBackend *blk = NULL;
85
AioContext *ctx;
86
+ AioContext **multithread_ctxs = NULL;
87
+ size_t multithread_count = 0;
88
uint64_t perm;
89
int ret;
90
91
GLOBAL_STATE_CODE();
92
93
+ if (fixed_iothread && multithread) {
94
+ error_setg(errp,
95
+ "Cannot use fixed-iothread for a multi-threaded export");
96
+ return NULL;
97
+ }
98
+
99
if (!id_wellformed(export->id)) {
100
error_setg(errp, "Invalid block export id");
101
return NULL;
126
127
ctx = bdrv_get_aio_context(bs);
128
119
- if (export->iothread) {
129
+ /* Move the BDS to the target I/O thread, if it is a single one */
130
+ if (export->iothread && !multithread) {
131
+ const char *iothread_id = export->iothread->u.single;
132
IOThread *iothread;
133
AioContext *new_ctx;
134
Error **set_context_errp;
135
124
- iothread = iothread_by_id(export->iothread);
136
+ iothread = iothread_by_id(iothread_id);
137
if (!iothread) {
126
- error_setg(errp, "iothread \"%s\" not found", export->iothread);
138
+ error_setg(errp, "iothread \"%s\" not found", iothread_id);
139
goto fail;
140
}
141
149
} else if (fixed_iothread) {
150
goto fail;
151
}
152
+ } else if (multithread) {
153
+ strList *iothread_list = export->iothread->u.multi;
154
+ size_t i;
155
+
156
+ multithread_count = 0;
157
+ for (strList *e = iothread_list; e; e = e->next) {
158
+ multithread_count++;
159
+ }
160
+
161
+ if (multithread_count == 0) {
162
+ error_setg(errp, "The set of I/O threads must not be empty");
163
+ return NULL;
164
+ }
165
+
166
+ multithread_ctxs = g_new(AioContext *, multithread_count);
167
+ i = 0;
168
+ for (strList *e = iothread_list; e; e = e->next) {
169
+ IOThread *iothread = iothread_by_id(e->value);
170
+
171
+ if (!iothread) {
172
+ error_setg(errp, "iothread \"%s\" not found", e->value);
173
+ goto fail;
174
+ }
175
+ multithread_ctxs[i++] = iothread_get_aio_context(iothread);
176
+ }
177
+ assert(i == multithread_count);
178
}
179
180
bdrv_graph_rdlock_main_loop();
233
.blk = blk,
234
};
235
198
- ret = drv->create(exp, export, errp);
236
+ ret = drv->create(exp, export, multithread_ctxs, multithread_count, errp);
237
if (ret < 0) {
238
goto fail;
239
}
241
assert(exp->blk != NULL);
242
243
QLIST_INSERT_HEAD(&block_exports, exp, next);
244
+ g_free(multithread_ctxs);
245
return exp;
246
247
fail:
253
g_free(exp->id);
254
g_free(exp);
255
}
256
+ g_free(multithread_ctxs);
257
return NULL;
258
}
259