Line data Source code
1 : /* SPDX-License-Identifier: BSD-3-Clause
2 : * Copyright (C) 2017 Intel Corporation.
3 : * All rights reserved.
4 : * Copyright (c) 2022-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
5 : */
6 :
7 : #include "spdk/rpc.h"
8 : #include "spdk/bdev_module.h"
9 : #include "spdk/log.h"
10 : #include "spdk/string.h"
11 : #include "spdk/uuid.h"
12 : #include "spdk/blob.h"
13 :
14 : #include "vbdev_lvol.h"
15 :
16 : struct vbdev_lvol_io {
17 : struct spdk_blob_ext_io_opts ext_io_opts;
18 : };
19 :
20 : static TAILQ_HEAD(, lvol_store_bdev) g_spdk_lvol_pairs = TAILQ_HEAD_INITIALIZER(
21 : g_spdk_lvol_pairs);
22 :
23 : static int vbdev_lvs_init(void);
24 : static void vbdev_lvs_fini_start(void);
25 : static int vbdev_lvs_get_ctx_size(void);
26 : static void vbdev_lvs_examine_config(struct spdk_bdev *bdev);
27 : static void vbdev_lvs_examine_disk(struct spdk_bdev *bdev);
28 : static bool g_shutdown_started = false;
29 :
30 : static struct spdk_bdev_module g_lvol_if = {
31 : .name = "lvol",
32 : .module_init = vbdev_lvs_init,
33 : .fini_start = vbdev_lvs_fini_start,
34 : .async_fini_start = true,
35 : .examine_config = vbdev_lvs_examine_config,
36 : .examine_disk = vbdev_lvs_examine_disk,
37 : .get_ctx_size = vbdev_lvs_get_ctx_size,
38 :
39 : };
40 :
41 1 : SPDK_BDEV_MODULE_REGISTER(lvol, &g_lvol_if)
42 :
43 : static void _vbdev_lvol_destroy(struct spdk_lvol *lvol, spdk_lvol_op_complete cb_fn, void *cb_arg);
44 :
45 : struct lvol_store_bdev *
46 70 : vbdev_get_lvs_bdev_by_lvs(struct spdk_lvol_store *lvs_orig)
47 : {
48 70 : struct spdk_lvol_store *lvs = NULL;
49 70 : struct lvol_store_bdev *lvs_bdev = vbdev_lvol_store_first();
50 :
51 70 : while (lvs_bdev != NULL) {
52 70 : lvs = lvs_bdev->lvs;
53 70 : if (lvs == lvs_orig) {
54 70 : if (lvs_bdev->removal_in_progress) {
55 : /* We do not allow access to lvs that are being unloaded or
56 : * destroyed */
57 0 : SPDK_DEBUGLOG(vbdev_lvol, "lvs %s: removal in progress\n",
58 : lvs_orig->name);
59 0 : return NULL;
60 : } else {
61 70 : return lvs_bdev;
62 : }
63 : }
64 0 : lvs_bdev = vbdev_lvol_store_next(lvs_bdev);
65 : }
66 :
67 0 : return NULL;
68 : }
69 :
70 : static int
71 4 : _vbdev_lvol_change_bdev_alias(struct spdk_lvol *lvol, const char *new_lvol_name)
72 : {
73 : struct spdk_bdev_alias *tmp;
74 : char *old_alias;
75 : char *alias;
76 : int rc;
77 4 : int alias_number = 0;
78 :
79 : /* bdev representing lvols have only one alias,
80 : * while we changed lvs name earlier, we have to iterate alias list to get one,
81 : * and check if there is only one alias */
82 :
83 8 : TAILQ_FOREACH(tmp, spdk_bdev_get_aliases(lvol->bdev), tailq) {
84 4 : if (++alias_number > 1) {
85 0 : SPDK_ERRLOG("There is more than 1 alias in bdev %s\n", lvol->bdev->name);
86 0 : return -EINVAL;
87 : }
88 :
89 4 : old_alias = tmp->alias.name;
90 : }
91 :
92 4 : if (alias_number == 0) {
93 0 : SPDK_ERRLOG("There are no aliases in bdev %s\n", lvol->bdev->name);
94 0 : return -EINVAL;
95 : }
96 :
97 4 : alias = spdk_sprintf_alloc("%s/%s", lvol->lvol_store->name, new_lvol_name);
98 4 : if (alias == NULL) {
99 0 : SPDK_ERRLOG("Cannot alloc memory for alias\n");
100 0 : return -ENOMEM;
101 : }
102 :
103 4 : rc = spdk_bdev_alias_add(lvol->bdev, alias);
104 4 : if (rc != 0) {
105 1 : SPDK_ERRLOG("cannot add alias '%s'\n", alias);
106 1 : free(alias);
107 1 : return rc;
108 : }
109 3 : free(alias);
110 :
111 3 : rc = spdk_bdev_alias_del(lvol->bdev, old_alias);
112 3 : if (rc != 0) {
113 0 : SPDK_ERRLOG("cannot remove alias '%s'\n", old_alias);
114 0 : return rc;
115 : }
116 :
117 3 : return 0;
118 : }
119 :
120 : static struct lvol_store_bdev *
121 2 : vbdev_get_lvs_bdev_by_bdev(struct spdk_bdev *bdev_orig)
122 : {
123 2 : struct lvol_store_bdev *lvs_bdev = vbdev_lvol_store_first();
124 :
125 3 : while (lvs_bdev != NULL) {
126 2 : if (lvs_bdev->bdev == bdev_orig) {
127 1 : if (lvs_bdev->removal_in_progress) {
128 : /* We do not allow access to lvs that are being unloaded or
129 : * destroyed */
130 0 : SPDK_DEBUGLOG(vbdev_lvol, "lvs %s: removal in progress\n",
131 : lvs_bdev->lvs->name);
132 0 : return NULL;
133 : } else {
134 1 : return lvs_bdev;
135 : }
136 : }
137 1 : lvs_bdev = vbdev_lvol_store_next(lvs_bdev);
138 : }
139 :
140 1 : return NULL;
141 : }
142 :
143 : static void
144 2 : vbdev_lvs_hotremove_cb(struct spdk_bdev *bdev)
145 : {
146 : struct lvol_store_bdev *lvs_bdev;
147 :
148 2 : lvs_bdev = vbdev_get_lvs_bdev_by_bdev(bdev);
149 2 : if (lvs_bdev != NULL) {
150 1 : SPDK_NOTICELOG("bdev %s being removed: closing lvstore %s\n",
151 : spdk_bdev_get_name(bdev), lvs_bdev->lvs->name);
152 1 : vbdev_lvs_unload(lvs_bdev->lvs, NULL, NULL);
153 : }
154 2 : }
155 :
156 : static void
157 0 : vbdev_lvs_base_bdev_event_cb(enum spdk_bdev_event_type type, struct spdk_bdev *bdev,
158 : void *event_ctx)
159 : {
160 0 : switch (type) {
161 0 : case SPDK_BDEV_EVENT_REMOVE:
162 0 : vbdev_lvs_hotremove_cb(bdev);
163 0 : break;
164 0 : default:
165 0 : SPDK_NOTICELOG("Unsupported bdev event: type %d\n", type);
166 0 : break;
167 : }
168 0 : }
169 :
170 : static void
171 16 : _vbdev_lvs_create_cb(void *cb_arg, struct spdk_lvol_store *lvs, int lvserrno)
172 : {
173 16 : struct spdk_lvs_with_handle_req *req = cb_arg;
174 : struct lvol_store_bdev *lvs_bdev;
175 16 : struct spdk_bdev *bdev = req->base_bdev;
176 16 : struct spdk_bs_dev *bs_dev = req->bs_dev;
177 :
178 16 : if (lvserrno != 0) {
179 1 : assert(lvs == NULL);
180 1 : SPDK_ERRLOG("Cannot create lvol store bdev\n");
181 1 : goto end;
182 : }
183 :
184 15 : lvserrno = spdk_bs_bdev_claim(bs_dev, &g_lvol_if);
185 15 : if (lvserrno != 0) {
186 0 : SPDK_INFOLOG(vbdev_lvol, "Lvol store base bdev already claimed by another bdev\n");
187 0 : req->bs_dev->destroy(req->bs_dev);
188 0 : goto end;
189 : }
190 :
191 15 : assert(lvs != NULL);
192 :
193 15 : lvs_bdev = calloc(1, sizeof(*lvs_bdev));
194 15 : if (!lvs_bdev) {
195 0 : lvserrno = -ENOMEM;
196 0 : goto end;
197 : }
198 15 : lvs_bdev->lvs = lvs;
199 15 : lvs_bdev->bdev = bdev;
200 15 : lvs_bdev->req = NULL;
201 :
202 15 : TAILQ_INSERT_TAIL(&g_spdk_lvol_pairs, lvs_bdev, lvol_stores);
203 15 : SPDK_INFOLOG(vbdev_lvol, "Lvol store bdev inserted\n");
204 :
205 15 : end:
206 16 : req->cb_fn(req->cb_arg, lvs, lvserrno);
207 16 : free(req);
208 :
209 16 : return;
210 : }
211 :
212 : int
213 18 : vbdev_lvs_create(const char *base_bdev_name, const char *name, uint32_t cluster_sz,
214 : enum lvs_clear_method clear_method, uint32_t num_md_pages_per_cluster_ratio,
215 : spdk_lvs_op_with_handle_complete cb_fn, void *cb_arg)
216 : {
217 18 : struct spdk_bs_dev *bs_dev;
218 : struct spdk_lvs_with_handle_req *lvs_req;
219 18 : struct spdk_lvs_opts opts;
220 : int rc;
221 : int len;
222 :
223 18 : if (base_bdev_name == NULL) {
224 0 : SPDK_ERRLOG("missing base_bdev_name param\n");
225 0 : return -EINVAL;
226 : }
227 :
228 18 : spdk_lvs_opts_init(&opts);
229 18 : if (cluster_sz != 0) {
230 0 : opts.cluster_sz = cluster_sz;
231 : }
232 :
233 18 : if (clear_method != 0) {
234 0 : opts.clear_method = clear_method;
235 : }
236 :
237 18 : if (num_md_pages_per_cluster_ratio != 0) {
238 0 : opts.num_md_pages_per_cluster_ratio = num_md_pages_per_cluster_ratio;
239 : }
240 :
241 18 : if (name == NULL) {
242 0 : SPDK_ERRLOG("missing name param\n");
243 0 : return -EINVAL;
244 : }
245 :
246 18 : len = strnlen(name, SPDK_LVS_NAME_MAX);
247 :
248 18 : if (len == 0 || len == SPDK_LVS_NAME_MAX) {
249 0 : SPDK_ERRLOG("name must be between 1 and %d characters\n", SPDK_LVS_NAME_MAX - 1);
250 0 : return -EINVAL;
251 : }
252 18 : snprintf(opts.name, sizeof(opts.name), "%s", name);
253 18 : opts.esnap_bs_dev_create = vbdev_lvol_esnap_dev_create;
254 :
255 18 : lvs_req = calloc(1, sizeof(*lvs_req));
256 18 : if (!lvs_req) {
257 0 : SPDK_ERRLOG("Cannot alloc memory for vbdev lvol store request pointer\n");
258 0 : return -ENOMEM;
259 : }
260 :
261 18 : rc = spdk_bdev_create_bs_dev_ext(base_bdev_name, vbdev_lvs_base_bdev_event_cb,
262 : NULL, &bs_dev);
263 18 : if (rc < 0) {
264 1 : SPDK_ERRLOG("Cannot create blobstore device\n");
265 1 : free(lvs_req);
266 1 : return rc;
267 : }
268 :
269 17 : lvs_req->bs_dev = bs_dev;
270 17 : lvs_req->base_bdev = bs_dev->get_base_bdev(bs_dev);
271 17 : lvs_req->cb_fn = cb_fn;
272 17 : lvs_req->cb_arg = cb_arg;
273 :
274 17 : rc = spdk_lvs_init(bs_dev, &opts, _vbdev_lvs_create_cb, lvs_req);
275 17 : if (rc < 0) {
276 1 : free(lvs_req);
277 1 : bs_dev->destroy(bs_dev);
278 1 : return rc;
279 : }
280 :
281 16 : return 0;
282 : }
283 :
284 : static void
285 2 : _vbdev_lvs_rename_cb(void *cb_arg, int lvserrno)
286 : {
287 2 : struct spdk_lvs_req *req = cb_arg;
288 : struct spdk_lvol *tmp;
289 :
290 2 : if (lvserrno != 0) {
291 1 : SPDK_INFOLOG(vbdev_lvol, "Lvol store rename failed\n");
292 : } else {
293 2 : TAILQ_FOREACH(tmp, &req->lvol_store->lvols, link) {
294 : /* We have to pass current lvol name, since only lvs name changed */
295 1 : _vbdev_lvol_change_bdev_alias(tmp, tmp->name);
296 : }
297 : }
298 :
299 2 : req->cb_fn(req->cb_arg, lvserrno);
300 2 : free(req);
301 2 : }
302 :
303 : void
304 2 : vbdev_lvs_rename(struct spdk_lvol_store *lvs, const char *new_lvs_name,
305 : spdk_lvs_op_complete cb_fn, void *cb_arg)
306 : {
307 : struct lvol_store_bdev *lvs_bdev;
308 :
309 : struct spdk_lvs_req *req;
310 :
311 2 : lvs_bdev = vbdev_get_lvs_bdev_by_lvs(lvs);
312 2 : if (!lvs_bdev) {
313 0 : SPDK_ERRLOG("No such lvol store found\n");
314 0 : cb_fn(cb_arg, -ENODEV);
315 0 : return;
316 : }
317 :
318 2 : req = calloc(1, sizeof(*req));
319 2 : if (!req) {
320 0 : SPDK_ERRLOG("Cannot alloc memory for vbdev lvol store request pointer\n");
321 0 : cb_fn(cb_arg, -ENOMEM);
322 0 : return;
323 : }
324 2 : req->cb_fn = cb_fn;
325 2 : req->cb_arg = cb_arg;
326 2 : req->lvol_store = lvs;
327 :
328 2 : spdk_lvs_rename(lvs, new_lvs_name, _vbdev_lvs_rename_cb, req);
329 : }
330 :
331 : static void
332 17 : _vbdev_lvs_remove_cb(void *cb_arg, int lvserrno)
333 : {
334 17 : struct lvol_store_bdev *lvs_bdev = cb_arg;
335 17 : struct spdk_lvs_req *req = lvs_bdev->req;
336 :
337 17 : if (lvserrno != 0) {
338 0 : SPDK_INFOLOG(vbdev_lvol, "Lvol store removed with error: %d.\n", lvserrno);
339 : }
340 :
341 17 : TAILQ_REMOVE(&g_spdk_lvol_pairs, lvs_bdev, lvol_stores);
342 17 : free(lvs_bdev);
343 :
344 17 : if (req->cb_fn != NULL) {
345 16 : req->cb_fn(req->cb_arg, lvserrno);
346 : }
347 17 : free(req);
348 17 : }
349 :
350 : static void
351 19 : _vbdev_lvs_remove_lvol_cb(void *cb_arg, int lvolerrno)
352 : {
353 19 : struct lvol_store_bdev *lvs_bdev = cb_arg;
354 19 : struct spdk_lvol_store *lvs = lvs_bdev->lvs;
355 : struct spdk_lvol *lvol;
356 :
357 19 : if (lvolerrno != 0) {
358 0 : SPDK_DEBUGLOG(vbdev_lvol, "Lvol removed with errno %d\n", lvolerrno);
359 : }
360 :
361 19 : if (TAILQ_EMPTY(&lvs->lvols)) {
362 6 : spdk_lvs_destroy(lvs, _vbdev_lvs_remove_cb, lvs_bdev);
363 6 : return;
364 : }
365 :
366 13 : lvol = TAILQ_FIRST(&lvs->lvols);
367 13 : while (lvol != NULL) {
368 13 : if (spdk_lvol_deletable(lvol)) {
369 13 : _vbdev_lvol_destroy(lvol, _vbdev_lvs_remove_lvol_cb, lvs_bdev);
370 13 : return;
371 : }
372 0 : lvol = TAILQ_NEXT(lvol, link);
373 : }
374 :
375 : /* If no lvol is deletable, that means there is circular dependency. */
376 0 : SPDK_ERRLOG("Lvols left in lvs, but unable to delete.\n");
377 0 : assert(false);
378 : }
379 :
380 : static bool
381 21 : _vbdev_lvs_are_lvols_closed(struct spdk_lvol_store *lvs)
382 : {
383 : struct spdk_lvol *lvol;
384 :
385 23 : TAILQ_FOREACH(lvol, &lvs->lvols, link) {
386 10 : if (lvol->ref_count != 0) {
387 8 : return false;
388 : }
389 : }
390 13 : return true;
391 : }
392 :
393 : static void
394 1 : _vbdev_lvs_remove_bdev_unregistered_cb(void *cb_arg, int bdeverrno)
395 : {
396 1 : struct lvol_store_bdev *lvs_bdev = cb_arg;
397 1 : struct spdk_lvol_store *lvs = lvs_bdev->lvs;
398 :
399 1 : if (bdeverrno != 0) {
400 0 : SPDK_DEBUGLOG(vbdev_lvol, "Lvol unregistered with errno %d\n", bdeverrno);
401 : }
402 :
403 : /* Lvol store can be unloaded once all lvols are closed. */
404 1 : if (_vbdev_lvs_are_lvols_closed(lvs)) {
405 1 : spdk_lvs_unload(lvs, _vbdev_lvs_remove_cb, lvs_bdev);
406 : }
407 1 : }
408 :
409 : static void
410 17 : _vbdev_lvs_remove(struct spdk_lvol_store *lvs, spdk_lvs_op_complete cb_fn, void *cb_arg,
411 : bool destroy)
412 : {
413 : struct spdk_lvs_req *req;
414 : struct lvol_store_bdev *lvs_bdev;
415 : struct spdk_lvol *lvol, *tmp;
416 :
417 17 : lvs_bdev = vbdev_get_lvs_bdev_by_lvs(lvs);
418 17 : if (!lvs_bdev) {
419 0 : SPDK_ERRLOG("No such lvol store found\n");
420 0 : if (cb_fn != NULL) {
421 0 : cb_fn(cb_arg, -ENODEV);
422 : }
423 0 : return;
424 : }
425 :
426 17 : req = calloc(1, sizeof(*req));
427 17 : if (!req) {
428 0 : SPDK_ERRLOG("Cannot alloc memory for vbdev lvol store request pointer\n");
429 0 : if (cb_fn != NULL) {
430 0 : cb_fn(cb_arg, -ENOMEM);
431 : }
432 0 : return;
433 : }
434 :
435 17 : lvs_bdev->removal_in_progress = true;
436 :
437 17 : req->cb_fn = cb_fn;
438 17 : req->cb_arg = cb_arg;
439 17 : lvs_bdev->req = req;
440 :
441 17 : if (_vbdev_lvs_are_lvols_closed(lvs)) {
442 10 : if (destroy) {
443 9 : spdk_lvs_destroy(lvs, _vbdev_lvs_remove_cb, lvs_bdev);
444 9 : return;
445 : }
446 1 : spdk_lvs_unload(lvs, _vbdev_lvs_remove_cb, lvs_bdev);
447 1 : return;
448 : }
449 7 : if (destroy) {
450 6 : _vbdev_lvs_remove_lvol_cb(lvs_bdev, 0);
451 6 : return;
452 : }
453 2 : TAILQ_FOREACH_SAFE(lvol, &lvs->lvols, link, tmp) {
454 1 : if (lvol->bdev == NULL) {
455 0 : spdk_lvol_close(lvol, _vbdev_lvs_remove_bdev_unregistered_cb, lvs_bdev);
456 0 : continue;
457 : }
458 1 : spdk_bdev_unregister(lvol->bdev, _vbdev_lvs_remove_bdev_unregistered_cb, lvs_bdev);
459 : }
460 : }
461 :
462 : void
463 2 : vbdev_lvs_unload(struct spdk_lvol_store *lvs, spdk_lvs_op_complete cb_fn, void *cb_arg)
464 : {
465 2 : _vbdev_lvs_remove(lvs, cb_fn, cb_arg, false);
466 2 : }
467 :
468 : void
469 15 : vbdev_lvs_destruct(struct spdk_lvol_store *lvs, spdk_lvs_op_complete cb_fn, void *cb_arg)
470 : {
471 15 : _vbdev_lvs_remove(lvs, cb_fn, cb_arg, true);
472 15 : }
473 :
474 : struct lvol_store_bdev *
475 74 : vbdev_lvol_store_first(void)
476 : {
477 : struct lvol_store_bdev *lvs_bdev;
478 :
479 74 : lvs_bdev = TAILQ_FIRST(&g_spdk_lvol_pairs);
480 74 : if (lvs_bdev) {
481 74 : SPDK_INFOLOG(vbdev_lvol, "Starting lvolstore iteration at %p\n", lvs_bdev->lvs);
482 : }
483 :
484 74 : return lvs_bdev;
485 : }
486 :
487 : struct lvol_store_bdev *
488 3 : vbdev_lvol_store_next(struct lvol_store_bdev *prev)
489 : {
490 : struct lvol_store_bdev *lvs_bdev;
491 :
492 3 : if (prev == NULL) {
493 0 : SPDK_ERRLOG("prev argument cannot be NULL\n");
494 0 : return NULL;
495 : }
496 :
497 3 : lvs_bdev = TAILQ_NEXT(prev, lvol_stores);
498 3 : if (lvs_bdev) {
499 0 : SPDK_INFOLOG(vbdev_lvol, "Continuing lvolstore iteration at %p\n", lvs_bdev->lvs);
500 : }
501 :
502 3 : return lvs_bdev;
503 : }
504 :
505 : static struct spdk_lvol_store *
506 0 : _vbdev_get_lvol_store_by_uuid(const struct spdk_uuid *uuid)
507 : {
508 0 : struct spdk_lvol_store *lvs = NULL;
509 0 : struct lvol_store_bdev *lvs_bdev = vbdev_lvol_store_first();
510 :
511 0 : while (lvs_bdev != NULL) {
512 0 : lvs = lvs_bdev->lvs;
513 0 : if (spdk_uuid_compare(&lvs->uuid, uuid) == 0) {
514 0 : return lvs;
515 : }
516 0 : lvs_bdev = vbdev_lvol_store_next(lvs_bdev);
517 : }
518 0 : return NULL;
519 : }
520 :
521 : struct spdk_lvol_store *
522 0 : vbdev_get_lvol_store_by_uuid(const char *uuid_str)
523 : {
524 0 : struct spdk_uuid uuid;
525 :
526 0 : if (spdk_uuid_parse(&uuid, uuid_str)) {
527 0 : return NULL;
528 : }
529 :
530 0 : return _vbdev_get_lvol_store_by_uuid(&uuid);
531 : }
532 :
533 : struct spdk_lvol_store *
534 0 : vbdev_get_lvol_store_by_name(const char *name)
535 : {
536 0 : struct spdk_lvol_store *lvs = NULL;
537 0 : struct lvol_store_bdev *lvs_bdev = vbdev_lvol_store_first();
538 :
539 0 : while (lvs_bdev != NULL) {
540 0 : lvs = lvs_bdev->lvs;
541 0 : if (strncmp(lvs->name, name, sizeof(lvs->name)) == 0) {
542 0 : return lvs;
543 : }
544 0 : lvs_bdev = vbdev_lvol_store_next(lvs_bdev);
545 : }
546 0 : return NULL;
547 : }
548 :
549 : struct vbdev_lvol_destroy_ctx {
550 : struct spdk_lvol *lvol;
551 : spdk_lvol_op_complete cb_fn;
552 : void *cb_arg;
553 : };
554 :
555 : static void
556 1 : _vbdev_lvol_unregister_unload_lvs(void *cb_arg, int lvserrno)
557 : {
558 1 : struct lvol_bdev *lvol_bdev = cb_arg;
559 1 : struct lvol_store_bdev *lvs_bdev = lvol_bdev->lvs_bdev;
560 :
561 1 : if (lvserrno != 0) {
562 0 : SPDK_INFOLOG(vbdev_lvol, "Lvol store removed with error: %d.\n", lvserrno);
563 : }
564 :
565 1 : TAILQ_REMOVE(&g_spdk_lvol_pairs, lvs_bdev, lvol_stores);
566 1 : free(lvs_bdev);
567 :
568 1 : spdk_bdev_destruct_done(&lvol_bdev->bdev, lvserrno);
569 1 : free(lvol_bdev);
570 1 : }
571 :
572 : static void
573 27 : _vbdev_lvol_unregister_cb(void *ctx, int lvolerrno)
574 : {
575 27 : struct lvol_bdev *lvol_bdev = ctx;
576 27 : struct lvol_store_bdev *lvs_bdev = lvol_bdev->lvs_bdev;
577 :
578 27 : if (g_shutdown_started && _vbdev_lvs_are_lvols_closed(lvs_bdev->lvs)) {
579 1 : spdk_lvs_unload(lvs_bdev->lvs, _vbdev_lvol_unregister_unload_lvs, lvol_bdev);
580 1 : return;
581 : }
582 :
583 26 : spdk_bdev_destruct_done(&lvol_bdev->bdev, lvolerrno);
584 26 : free(lvol_bdev);
585 : }
586 :
587 : static int
588 27 : vbdev_lvol_unregister(void *ctx)
589 : {
590 27 : struct spdk_lvol *lvol = ctx;
591 : struct lvol_bdev *lvol_bdev;
592 :
593 27 : assert(lvol != NULL);
594 27 : lvol_bdev = SPDK_CONTAINEROF(lvol->bdev, struct lvol_bdev, bdev);
595 :
596 27 : spdk_bdev_alias_del_all(lvol->bdev);
597 27 : spdk_lvol_close(lvol, _vbdev_lvol_unregister_cb, lvol_bdev);
598 :
599 : /* return 1 to indicate we have an operation that must finish asynchronously before the
600 : * lvol is closed
601 : */
602 27 : return 1;
603 : }
604 :
605 : static void
606 25 : _vbdev_lvol_destroy_cb(void *cb_arg, int bdeverrno)
607 : {
608 25 : struct vbdev_lvol_destroy_ctx *ctx = cb_arg;
609 25 : struct spdk_lvol *lvol = ctx->lvol;
610 :
611 25 : if (bdeverrno < 0) {
612 0 : SPDK_INFOLOG(vbdev_lvol, "Could not unregister bdev during lvol (%s) destroy\n",
613 : lvol->unique_id);
614 0 : ctx->cb_fn(ctx->cb_arg, bdeverrno);
615 0 : free(ctx);
616 0 : return;
617 : }
618 :
619 25 : spdk_lvol_destroy(lvol, ctx->cb_fn, ctx->cb_arg);
620 25 : free(ctx);
621 : }
622 :
623 : static void
624 25 : _vbdev_lvol_destroy(struct spdk_lvol *lvol, spdk_lvol_op_complete cb_fn, void *cb_arg)
625 : {
626 : struct vbdev_lvol_destroy_ctx *ctx;
627 25 : size_t count;
628 :
629 25 : assert(lvol != NULL);
630 25 : assert(cb_fn != NULL);
631 :
632 : /* Callers other than _vbdev_lvs_remove() must ensure the lvstore is not being removed. */
633 25 : assert(cb_fn == _vbdev_lvs_remove_lvol_cb ||
634 : vbdev_get_lvs_bdev_by_lvs(lvol->lvol_store) != NULL);
635 :
636 : /* Check if it is possible to delete lvol */
637 25 : spdk_blob_get_clones(lvol->lvol_store->blobstore, lvol->blob_id, NULL, &count);
638 25 : if (count > 1) {
639 : /* throw an error */
640 0 : SPDK_ERRLOG("Cannot delete lvol\n");
641 0 : cb_fn(cb_arg, -EPERM);
642 0 : return;
643 : }
644 :
645 25 : ctx = calloc(1, sizeof(*ctx));
646 25 : if (!ctx) {
647 0 : cb_fn(cb_arg, -ENOMEM);
648 0 : return;
649 : }
650 :
651 25 : ctx->lvol = lvol;
652 25 : ctx->cb_fn = cb_fn;
653 25 : ctx->cb_arg = cb_arg;
654 :
655 25 : if (spdk_lvol_is_degraded(lvol)) {
656 0 : spdk_lvol_close(lvol, _vbdev_lvol_destroy_cb, ctx);
657 0 : return;
658 : }
659 :
660 25 : spdk_bdev_unregister(lvol->bdev, _vbdev_lvol_destroy_cb, ctx);
661 : }
662 :
663 : void
664 12 : vbdev_lvol_destroy(struct spdk_lvol *lvol, spdk_lvol_op_complete cb_fn, void *cb_arg)
665 : {
666 : struct lvol_store_bdev *lvs_bdev;
667 :
668 : /*
669 : * During destruction of an lvolstore, _vbdev_lvs_unload() iterates through lvols until they
670 : * are all deleted. There may be some IO required
671 : */
672 12 : lvs_bdev = vbdev_get_lvs_bdev_by_lvs(lvol->lvol_store);
673 12 : if (lvs_bdev == NULL) {
674 0 : SPDK_DEBUGLOG(vbdev_lvol, "lvol %s: lvolstore is being removed\n",
675 : lvol->unique_id);
676 0 : cb_fn(cb_arg, -ENODEV);
677 0 : return;
678 : }
679 :
680 12 : _vbdev_lvol_destroy(lvol, cb_fn, cb_arg);
681 : }
682 :
683 : static char *
684 0 : vbdev_lvol_find_name(struct spdk_lvol *lvol, spdk_blob_id blob_id)
685 : {
686 : struct spdk_lvol_store *lvs;
687 : struct spdk_lvol *_lvol;
688 :
689 0 : assert(lvol != NULL);
690 :
691 0 : lvs = lvol->lvol_store;
692 :
693 0 : assert(lvs);
694 :
695 0 : TAILQ_FOREACH(_lvol, &lvs->lvols, link) {
696 0 : if (_lvol->blob_id == blob_id) {
697 0 : return _lvol->name;
698 : }
699 : }
700 :
701 0 : return NULL;
702 : }
703 :
704 : static int
705 0 : vbdev_lvol_dump_info_json(void *ctx, struct spdk_json_write_ctx *w)
706 : {
707 0 : struct spdk_lvol *lvol = ctx;
708 : struct lvol_store_bdev *lvs_bdev;
709 : struct spdk_bdev *bdev;
710 : struct spdk_blob *blob;
711 0 : spdk_blob_id *ids = NULL;
712 0 : size_t count, i;
713 : char *name;
714 0 : int rc = 0;
715 :
716 0 : spdk_json_write_named_object_begin(w, "lvol");
717 :
718 0 : lvs_bdev = vbdev_get_lvs_bdev_by_lvs(lvol->lvol_store);
719 0 : if (!lvs_bdev) {
720 0 : SPDK_ERRLOG("No such lvol store found\n");
721 0 : rc = -ENODEV;
722 0 : goto end;
723 : }
724 :
725 0 : bdev = lvs_bdev->bdev;
726 :
727 0 : spdk_json_write_named_uuid(w, "lvol_store_uuid", &lvol->lvol_store->uuid);
728 :
729 0 : spdk_json_write_named_string(w, "base_bdev", spdk_bdev_get_name(bdev));
730 :
731 0 : blob = lvol->blob;
732 :
733 0 : spdk_json_write_named_bool(w, "thin_provision", spdk_blob_is_thin_provisioned(blob));
734 :
735 0 : spdk_json_write_named_uint64(w, "num_allocated_clusters",
736 : spdk_blob_get_num_allocated_clusters(blob));
737 :
738 0 : spdk_json_write_named_bool(w, "snapshot", spdk_blob_is_snapshot(blob));
739 :
740 0 : spdk_json_write_named_bool(w, "clone", spdk_blob_is_clone(blob));
741 :
742 0 : if (spdk_blob_is_clone(blob)) {
743 0 : spdk_blob_id snapshotid = spdk_blob_get_parent_snapshot(lvol->lvol_store->blobstore, lvol->blob_id);
744 0 : if (snapshotid != SPDK_BLOBID_INVALID) {
745 0 : name = vbdev_lvol_find_name(lvol, snapshotid);
746 0 : if (name != NULL) {
747 0 : spdk_json_write_named_string(w, "base_snapshot", name);
748 : } else {
749 0 : SPDK_ERRLOG("Cannot obtain snapshots name\n");
750 : }
751 : }
752 : }
753 :
754 0 : if (spdk_blob_is_snapshot(blob)) {
755 : /* Take a number of clones */
756 0 : rc = spdk_blob_get_clones(lvol->lvol_store->blobstore, lvol->blob_id, NULL, &count);
757 0 : if (rc == -ENOMEM && count > 0) {
758 0 : ids = malloc(sizeof(spdk_blob_id) * count);
759 0 : if (ids == NULL) {
760 0 : SPDK_ERRLOG("Cannot allocate memory\n");
761 0 : rc = -ENOMEM;
762 0 : goto end;
763 : }
764 :
765 0 : rc = spdk_blob_get_clones(lvol->lvol_store->blobstore, lvol->blob_id, ids, &count);
766 0 : if (rc == 0) {
767 0 : spdk_json_write_named_array_begin(w, "clones");
768 0 : for (i = 0; i < count; i++) {
769 0 : name = vbdev_lvol_find_name(lvol, ids[i]);
770 0 : if (name != NULL) {
771 0 : spdk_json_write_string(w, name);
772 : } else {
773 0 : SPDK_ERRLOG("Cannot obtain clone name\n");
774 : }
775 :
776 : }
777 0 : spdk_json_write_array_end(w);
778 : }
779 0 : free(ids);
780 : }
781 :
782 : }
783 :
784 0 : spdk_json_write_named_bool(w, "esnap_clone", spdk_blob_is_esnap_clone(blob));
785 :
786 0 : if (spdk_blob_is_esnap_clone(blob)) {
787 0 : const char *name;
788 0 : size_t name_len;
789 :
790 0 : rc = spdk_blob_get_esnap_id(blob, (const void **)&name, &name_len);
791 0 : if (rc == 0 && name != NULL && strnlen(name, name_len) + 1 == name_len) {
792 0 : spdk_json_write_named_string(w, "external_snapshot_name", name);
793 : }
794 : }
795 :
796 0 : end:
797 0 : spdk_json_write_object_end(w);
798 :
799 0 : return rc;
800 : }
801 :
802 : static void
803 0 : vbdev_lvol_write_config_json(struct spdk_bdev *bdev, struct spdk_json_write_ctx *w)
804 : {
805 : /* Nothing to dump as lvol configuration is saved on physical device. */
806 0 : }
807 :
808 : static struct spdk_io_channel *
809 1 : vbdev_lvol_get_io_channel(void *ctx)
810 : {
811 1 : struct spdk_lvol *lvol = ctx;
812 :
813 1 : return spdk_lvol_get_io_channel(lvol);
814 : }
815 :
816 : static bool
817 20 : vbdev_lvol_io_type_supported(void *ctx, enum spdk_bdev_io_type io_type)
818 : {
819 20 : struct spdk_lvol *lvol = ctx;
820 :
821 20 : switch (io_type) {
822 6 : case SPDK_BDEV_IO_TYPE_WRITE:
823 : case SPDK_BDEV_IO_TYPE_UNMAP:
824 : case SPDK_BDEV_IO_TYPE_WRITE_ZEROES:
825 6 : return !spdk_blob_is_read_only(lvol->blob);
826 8 : case SPDK_BDEV_IO_TYPE_RESET:
827 : case SPDK_BDEV_IO_TYPE_READ:
828 : case SPDK_BDEV_IO_TYPE_SEEK_DATA:
829 : case SPDK_BDEV_IO_TYPE_SEEK_HOLE:
830 8 : return true;
831 6 : default:
832 6 : return false;
833 : }
834 : }
835 :
836 : static void
837 4 : lvol_op_comp(void *cb_arg, int bserrno)
838 : {
839 4 : struct spdk_bdev_io *bdev_io = cb_arg;
840 4 : enum spdk_bdev_io_status status = SPDK_BDEV_IO_STATUS_SUCCESS;
841 :
842 4 : if (bserrno != 0) {
843 0 : if (bserrno == -ENOMEM) {
844 0 : status = SPDK_BDEV_IO_STATUS_NOMEM;
845 : } else {
846 0 : status = SPDK_BDEV_IO_STATUS_FAILED;
847 : }
848 : }
849 :
850 4 : spdk_bdev_io_complete(bdev_io, status);
851 4 : }
852 :
853 : static void
854 0 : lvol_unmap(struct spdk_lvol *lvol, struct spdk_io_channel *ch, struct spdk_bdev_io *bdev_io)
855 : {
856 : uint64_t start_page, num_pages;
857 0 : struct spdk_blob *blob = lvol->blob;
858 :
859 0 : start_page = bdev_io->u.bdev.offset_blocks;
860 0 : num_pages = bdev_io->u.bdev.num_blocks;
861 :
862 0 : spdk_blob_io_unmap(blob, ch, start_page, num_pages, lvol_op_comp, bdev_io);
863 0 : }
864 :
865 : static void
866 2 : lvol_seek_data(struct spdk_lvol *lvol, struct spdk_bdev_io *bdev_io)
867 : {
868 2 : bdev_io->u.bdev.seek.offset = spdk_blob_get_next_allocated_io_unit(lvol->blob,
869 : bdev_io->u.bdev.offset_blocks);
870 :
871 2 : spdk_bdev_io_complete(bdev_io, SPDK_BDEV_IO_STATUS_SUCCESS);
872 2 : }
873 :
874 : static void
875 2 : lvol_seek_hole(struct spdk_lvol *lvol, struct spdk_bdev_io *bdev_io)
876 : {
877 2 : bdev_io->u.bdev.seek.offset = spdk_blob_get_next_unallocated_io_unit(lvol->blob,
878 : bdev_io->u.bdev.offset_blocks);
879 :
880 2 : spdk_bdev_io_complete(bdev_io, SPDK_BDEV_IO_STATUS_SUCCESS);
881 2 : }
882 :
883 : static void
884 0 : lvol_write_zeroes(struct spdk_lvol *lvol, struct spdk_io_channel *ch, struct spdk_bdev_io *bdev_io)
885 : {
886 : uint64_t start_page, num_pages;
887 0 : struct spdk_blob *blob = lvol->blob;
888 :
889 0 : start_page = bdev_io->u.bdev.offset_blocks;
890 0 : num_pages = bdev_io->u.bdev.num_blocks;
891 :
892 0 : spdk_blob_io_write_zeroes(blob, ch, start_page, num_pages, lvol_op_comp, bdev_io);
893 0 : }
894 :
895 : static void
896 2 : lvol_read(struct spdk_io_channel *ch, struct spdk_bdev_io *bdev_io)
897 : {
898 : uint64_t start_page, num_pages;
899 2 : struct spdk_lvol *lvol = bdev_io->bdev->ctxt;
900 2 : struct spdk_blob *blob = lvol->blob;
901 2 : struct vbdev_lvol_io *lvol_io = (struct vbdev_lvol_io *)bdev_io->driver_ctx;
902 :
903 2 : start_page = bdev_io->u.bdev.offset_blocks;
904 2 : num_pages = bdev_io->u.bdev.num_blocks;
905 :
906 2 : lvol_io->ext_io_opts.size = sizeof(lvol_io->ext_io_opts);
907 2 : lvol_io->ext_io_opts.memory_domain = bdev_io->u.bdev.memory_domain;
908 2 : lvol_io->ext_io_opts.memory_domain_ctx = bdev_io->u.bdev.memory_domain_ctx;
909 :
910 2 : spdk_blob_io_readv_ext(blob, ch, bdev_io->u.bdev.iovs, bdev_io->u.bdev.iovcnt, start_page,
911 : num_pages, lvol_op_comp, bdev_io, &lvol_io->ext_io_opts);
912 2 : }
913 :
914 : static void
915 2 : lvol_write(struct spdk_lvol *lvol, struct spdk_io_channel *ch, struct spdk_bdev_io *bdev_io)
916 : {
917 : uint64_t start_page, num_pages;
918 2 : struct spdk_blob *blob = lvol->blob;
919 2 : struct vbdev_lvol_io *lvol_io = (struct vbdev_lvol_io *)bdev_io->driver_ctx;
920 :
921 2 : start_page = bdev_io->u.bdev.offset_blocks;
922 2 : num_pages = bdev_io->u.bdev.num_blocks;
923 :
924 2 : lvol_io->ext_io_opts.size = sizeof(lvol_io->ext_io_opts);
925 2 : lvol_io->ext_io_opts.memory_domain = bdev_io->u.bdev.memory_domain;
926 2 : lvol_io->ext_io_opts.memory_domain_ctx = bdev_io->u.bdev.memory_domain_ctx;
927 :
928 2 : spdk_blob_io_writev_ext(blob, ch, bdev_io->u.bdev.iovs, bdev_io->u.bdev.iovcnt, start_page,
929 : num_pages, lvol_op_comp, bdev_io, &lvol_io->ext_io_opts);
930 2 : }
931 :
932 : static int
933 0 : lvol_reset(struct spdk_bdev_io *bdev_io)
934 : {
935 0 : spdk_bdev_io_complete(bdev_io, SPDK_BDEV_IO_STATUS_FAILED);
936 :
937 0 : return 0;
938 : }
939 :
940 : static void
941 0 : lvol_get_buf_cb(struct spdk_io_channel *ch, struct spdk_bdev_io *bdev_io, bool success)
942 : {
943 0 : if (!success) {
944 0 : spdk_bdev_io_complete(bdev_io, SPDK_BDEV_IO_STATUS_FAILED);
945 0 : return;
946 : }
947 :
948 0 : lvol_read(ch, bdev_io);
949 : }
950 :
951 : static void
952 1 : vbdev_lvol_submit_request(struct spdk_io_channel *ch, struct spdk_bdev_io *bdev_io)
953 : {
954 1 : struct spdk_lvol *lvol = bdev_io->bdev->ctxt;
955 :
956 1 : switch (bdev_io->type) {
957 1 : case SPDK_BDEV_IO_TYPE_READ:
958 1 : spdk_bdev_io_get_buf(bdev_io, lvol_get_buf_cb,
959 1 : bdev_io->u.bdev.num_blocks * bdev_io->bdev->blocklen);
960 1 : break;
961 0 : case SPDK_BDEV_IO_TYPE_WRITE:
962 0 : lvol_write(lvol, ch, bdev_io);
963 0 : break;
964 0 : case SPDK_BDEV_IO_TYPE_RESET:
965 0 : lvol_reset(bdev_io);
966 0 : break;
967 0 : case SPDK_BDEV_IO_TYPE_UNMAP:
968 0 : lvol_unmap(lvol, ch, bdev_io);
969 0 : break;
970 0 : case SPDK_BDEV_IO_TYPE_WRITE_ZEROES:
971 0 : lvol_write_zeroes(lvol, ch, bdev_io);
972 0 : break;
973 0 : case SPDK_BDEV_IO_TYPE_SEEK_DATA:
974 0 : lvol_seek_data(lvol, bdev_io);
975 0 : break;
976 0 : case SPDK_BDEV_IO_TYPE_SEEK_HOLE:
977 0 : lvol_seek_hole(lvol, bdev_io);
978 0 : break;
979 0 : default:
980 0 : SPDK_INFOLOG(vbdev_lvol, "lvol: unsupported I/O type %d\n", bdev_io->type);
981 0 : spdk_bdev_io_complete(bdev_io, SPDK_BDEV_IO_STATUS_FAILED);
982 0 : return;
983 : }
984 1 : return;
985 : }
986 :
987 : static int
988 0 : vbdev_lvol_get_memory_domains(void *ctx, struct spdk_memory_domain **domains, int array_size)
989 : {
990 0 : struct spdk_lvol *lvol = ctx;
991 : struct spdk_bdev *base_bdev, *esnap_bdev;
992 : struct spdk_bs_dev *bs_dev;
993 : struct spdk_lvol_store *lvs;
994 : int base_cnt, esnap_cnt;
995 :
996 0 : lvs = lvol->lvol_store;
997 0 : base_bdev = lvs->bs_dev->get_base_bdev(lvol->lvol_store->bs_dev);
998 :
999 0 : base_cnt = spdk_bdev_get_memory_domains(base_bdev, domains, array_size);
1000 0 : if (base_cnt < 0) {
1001 0 : return base_cnt;
1002 : }
1003 :
1004 0 : if (lvol->blob == NULL) {
1005 : /*
1006 : * This is probably called due to an open happening during blobstore load. Another
1007 : * open will follow shortly that has lvol->blob set.
1008 : */
1009 0 : return -EAGAIN;
1010 : }
1011 :
1012 0 : if (!spdk_blob_is_esnap_clone(lvol->blob)) {
1013 0 : return base_cnt;
1014 : }
1015 :
1016 0 : bs_dev = spdk_blob_get_esnap_bs_dev(lvol->blob);
1017 0 : if (bs_dev == NULL) {
1018 0 : assert(false);
1019 : SPDK_ERRLOG("lvol %s is an esnap clone but has no esnap device\n", lvol->unique_id);
1020 : return base_cnt;
1021 : }
1022 :
1023 0 : if (bs_dev->get_base_bdev == NULL) {
1024 : /*
1025 : * If this were a blob_bdev, we wouldn't be here. We are probably here because an
1026 : * lvol bdev is being registered with spdk_bdev_register() before the external
1027 : * snapshot bdev is loaded. Ideally, the load of a missing esnap would trigger an
1028 : * event that causes the lvol bdev's memory domain information to be updated.
1029 : */
1030 0 : return base_cnt;
1031 : }
1032 :
1033 0 : esnap_bdev = bs_dev->get_base_bdev(bs_dev);
1034 0 : if (esnap_bdev == NULL) {
1035 : /*
1036 : * The esnap bdev has not yet been loaded. Anyone that has opened at this point may
1037 : * miss out on using memory domains if base_cnt is zero.
1038 : */
1039 0 : SPDK_NOTICELOG("lvol %s reporting %d memory domains, not including missing esnap\n",
1040 : lvol->unique_id, base_cnt);
1041 0 : return base_cnt;
1042 : }
1043 :
1044 0 : if (base_cnt < array_size) {
1045 0 : array_size -= base_cnt;
1046 0 : domains += base_cnt;
1047 : } else {
1048 0 : array_size = 0;
1049 0 : domains = NULL;
1050 : }
1051 :
1052 0 : esnap_cnt = spdk_bdev_get_memory_domains(esnap_bdev, domains, array_size);
1053 0 : if (esnap_cnt <= 0) {
1054 0 : return base_cnt;
1055 : }
1056 :
1057 0 : return base_cnt + esnap_cnt;
1058 : }
1059 :
1060 : static struct spdk_bdev_fn_table vbdev_lvol_fn_table = {
1061 : .destruct = vbdev_lvol_unregister,
1062 : .io_type_supported = vbdev_lvol_io_type_supported,
1063 : .submit_request = vbdev_lvol_submit_request,
1064 : .get_io_channel = vbdev_lvol_get_io_channel,
1065 : .dump_info_json = vbdev_lvol_dump_info_json,
1066 : .write_config_json = vbdev_lvol_write_config_json,
1067 : .get_memory_domains = vbdev_lvol_get_memory_domains,
1068 : };
1069 :
1070 : static void
1071 0 : lvol_destroy_cb(void *cb_arg, int bdeverrno)
1072 : {
1073 0 : }
1074 :
1075 : static void
1076 0 : _create_lvol_disk_destroy_cb(void *cb_arg, int bdeverrno)
1077 : {
1078 0 : struct spdk_lvol *lvol = cb_arg;
1079 :
1080 0 : if (bdeverrno < 0) {
1081 0 : SPDK_ERRLOG("Could not unregister bdev for lvol %s\n",
1082 : lvol->unique_id);
1083 0 : return;
1084 : }
1085 :
1086 0 : spdk_lvol_destroy(lvol, lvol_destroy_cb, NULL);
1087 : }
1088 :
1089 : static void
1090 0 : _create_lvol_disk_unload_cb(void *cb_arg, int bdeverrno)
1091 : {
1092 0 : struct spdk_lvol *lvol = cb_arg;
1093 :
1094 0 : if (bdeverrno < 0) {
1095 0 : SPDK_ERRLOG("Could not unregister bdev for lvol %s\n",
1096 : lvol->unique_id);
1097 0 : return;
1098 : }
1099 :
1100 0 : TAILQ_REMOVE(&lvol->lvol_store->lvols, lvol, link);
1101 0 : free(lvol);
1102 : }
1103 :
1104 : static int
1105 27 : _create_lvol_disk(struct spdk_lvol *lvol, bool destroy)
1106 : {
1107 : struct spdk_bdev *bdev;
1108 : struct lvol_bdev *lvol_bdev;
1109 : struct lvol_store_bdev *lvs_bdev;
1110 : uint64_t total_size;
1111 : unsigned char *alias;
1112 : int rc;
1113 :
1114 27 : if (spdk_lvol_is_degraded(lvol)) {
1115 0 : SPDK_NOTICELOG("lvol %s: blob is degraded: deferring bdev creation\n",
1116 : lvol->unique_id);
1117 0 : return 0;
1118 : }
1119 :
1120 27 : lvs_bdev = vbdev_get_lvs_bdev_by_lvs(lvol->lvol_store);
1121 27 : if (lvs_bdev == NULL) {
1122 0 : SPDK_ERRLOG("No spdk lvs-bdev pair found for lvol %s\n", lvol->unique_id);
1123 0 : assert(false);
1124 : return -ENODEV;
1125 : }
1126 :
1127 27 : lvol_bdev = calloc(1, sizeof(struct lvol_bdev));
1128 27 : if (!lvol_bdev) {
1129 0 : SPDK_ERRLOG("Cannot alloc memory for lvol bdev\n");
1130 0 : return -ENOMEM;
1131 : }
1132 :
1133 27 : lvol_bdev->lvol = lvol;
1134 27 : lvol_bdev->lvs_bdev = lvs_bdev;
1135 :
1136 27 : bdev = &lvol_bdev->bdev;
1137 27 : bdev->name = lvol->unique_id;
1138 27 : bdev->product_name = "Logical Volume";
1139 27 : bdev->blocklen = spdk_bs_get_io_unit_size(lvol->lvol_store->blobstore);
1140 27 : total_size = spdk_blob_get_num_clusters(lvol->blob) *
1141 27 : spdk_bs_get_cluster_size(lvol->lvol_store->blobstore);
1142 27 : assert((total_size % bdev->blocklen) == 0);
1143 27 : bdev->blockcnt = total_size / bdev->blocklen;
1144 27 : bdev->uuid = lvol->uuid;
1145 27 : bdev->required_alignment = lvs_bdev->bdev->required_alignment;
1146 27 : bdev->split_on_optimal_io_boundary = true;
1147 27 : bdev->optimal_io_boundary = spdk_bs_get_cluster_size(lvol->lvol_store->blobstore) / bdev->blocklen;
1148 :
1149 27 : bdev->ctxt = lvol;
1150 27 : bdev->fn_table = &vbdev_lvol_fn_table;
1151 27 : bdev->module = &g_lvol_if;
1152 :
1153 : /* Set default bdev reset waiting time. This value indicates how much
1154 : * time a reset should wait before forcing a reset down to the underlying
1155 : * bdev module.
1156 : * Setting this parameter is mainly to avoid "empty" resets to a shared
1157 : * bdev that may be used by multiple lvols. */
1158 27 : bdev->reset_io_drain_timeout = SPDK_BDEV_RESET_IO_DRAIN_RECOMMENDED_VALUE;
1159 :
1160 27 : rc = spdk_bdev_register(bdev);
1161 27 : if (rc) {
1162 0 : free(lvol_bdev);
1163 0 : return rc;
1164 : }
1165 27 : lvol->bdev = bdev;
1166 :
1167 27 : alias = spdk_sprintf_alloc("%s/%s", lvs_bdev->lvs->name, lvol->name);
1168 27 : if (alias == NULL) {
1169 0 : SPDK_ERRLOG("Cannot alloc memory for alias\n");
1170 0 : spdk_bdev_unregister(lvol->bdev, (destroy ? _create_lvol_disk_destroy_cb :
1171 : _create_lvol_disk_unload_cb), lvol);
1172 0 : return -ENOMEM;
1173 : }
1174 :
1175 27 : rc = spdk_bdev_alias_add(bdev, alias);
1176 27 : if (rc != 0) {
1177 0 : SPDK_ERRLOG("Cannot add alias to lvol bdev\n");
1178 0 : spdk_bdev_unregister(lvol->bdev, (destroy ? _create_lvol_disk_destroy_cb :
1179 : _create_lvol_disk_unload_cb), lvol);
1180 : }
1181 27 : free(alias);
1182 :
1183 27 : return rc;
1184 : }
1185 :
1186 : static void
1187 18 : _vbdev_lvol_create_cb(void *cb_arg, struct spdk_lvol *lvol, int lvolerrno)
1188 : {
1189 18 : struct spdk_lvol_with_handle_req *req = cb_arg;
1190 :
1191 18 : if (lvolerrno < 0) {
1192 0 : goto end;
1193 : }
1194 :
1195 18 : lvolerrno = _create_lvol_disk(lvol, true);
1196 :
1197 18 : end:
1198 18 : req->cb_fn(req->cb_arg, lvol, lvolerrno);
1199 18 : free(req);
1200 18 : }
1201 :
1202 : int
1203 13 : vbdev_lvol_create(struct spdk_lvol_store *lvs, const char *name, uint64_t sz,
1204 : bool thin_provision, enum lvol_clear_method clear_method, spdk_lvol_op_with_handle_complete cb_fn,
1205 : void *cb_arg)
1206 : {
1207 : struct spdk_lvol_with_handle_req *req;
1208 : int rc;
1209 :
1210 13 : req = calloc(1, sizeof(*req));
1211 13 : if (req == NULL) {
1212 0 : return -ENOMEM;
1213 : }
1214 13 : req->cb_fn = cb_fn;
1215 13 : req->cb_arg = cb_arg;
1216 :
1217 13 : rc = spdk_lvol_create(lvs, name, sz, thin_provision, clear_method,
1218 : _vbdev_lvol_create_cb, req);
1219 13 : if (rc != 0) {
1220 0 : free(req);
1221 : }
1222 :
1223 13 : return rc;
1224 : }
1225 :
1226 : void
1227 2 : vbdev_lvol_create_snapshot(struct spdk_lvol *lvol, const char *snapshot_name,
1228 : spdk_lvol_op_with_handle_complete cb_fn, void *cb_arg)
1229 : {
1230 : struct spdk_lvol_with_handle_req *req;
1231 :
1232 2 : req = calloc(1, sizeof(*req));
1233 2 : if (req == NULL) {
1234 0 : cb_fn(cb_arg, NULL, -ENOMEM);
1235 0 : return;
1236 : }
1237 :
1238 2 : req->cb_fn = cb_fn;
1239 2 : req->cb_arg = cb_arg;
1240 :
1241 2 : spdk_lvol_create_snapshot(lvol, snapshot_name, _vbdev_lvol_create_cb, req);
1242 : }
1243 :
1244 : void
1245 1 : vbdev_lvol_create_clone(struct spdk_lvol *lvol, const char *clone_name,
1246 : spdk_lvol_op_with_handle_complete cb_fn, void *cb_arg)
1247 : {
1248 : struct spdk_lvol_with_handle_req *req;
1249 :
1250 1 : req = calloc(1, sizeof(*req));
1251 1 : if (req == NULL) {
1252 0 : cb_fn(cb_arg, NULL, -ENOMEM);
1253 0 : return;
1254 : }
1255 :
1256 1 : req->cb_fn = cb_fn;
1257 1 : req->cb_arg = cb_arg;
1258 :
1259 1 : spdk_lvol_create_clone(lvol, clone_name, _vbdev_lvol_create_cb, req);
1260 : }
1261 :
1262 : static void
1263 0 : ignore_bdev_event_cb(enum spdk_bdev_event_type type, struct spdk_bdev *bdev, void *ctx)
1264 : {
1265 0 : }
1266 :
1267 : void
1268 4 : vbdev_lvol_create_bdev_clone(const char *esnap_name,
1269 : struct spdk_lvol_store *lvs, const char *clone_name,
1270 : spdk_lvol_op_with_handle_complete cb_fn, void *cb_arg)
1271 : {
1272 : struct spdk_lvol_with_handle_req *req;
1273 4 : struct spdk_bdev_desc *desc;
1274 : struct spdk_bdev *bdev;
1275 4 : char bdev_uuid[SPDK_UUID_STRING_LEN];
1276 : uint64_t sz;
1277 : int rc;
1278 :
1279 4 : if (lvs == NULL) {
1280 1 : SPDK_ERRLOG("lvol store not specified\n");
1281 1 : cb_fn(cb_arg, NULL, -EINVAL);
1282 1 : return;
1283 : }
1284 :
1285 3 : rc = spdk_bdev_open_ext(esnap_name, false, ignore_bdev_event_cb, NULL, &desc);
1286 3 : if (rc != 0) {
1287 1 : SPDK_ERRLOG("bdev '%s' could not be opened: error %d\n", esnap_name, rc);
1288 1 : cb_fn(cb_arg, NULL, rc);
1289 1 : return;
1290 : }
1291 2 : bdev = spdk_bdev_desc_get_bdev(desc);
1292 :
1293 2 : rc = spdk_uuid_fmt_lower(bdev_uuid, sizeof(bdev_uuid), spdk_bdev_get_uuid(bdev));
1294 2 : if (rc != 0) {
1295 0 : spdk_bdev_close(desc);
1296 0 : SPDK_ERRLOG("bdev %s: unable to parse UUID\n", esnap_name);
1297 0 : assert(false);
1298 : cb_fn(cb_arg, NULL, -ENODEV);
1299 : return;
1300 : }
1301 :
1302 2 : req = calloc(1, sizeof(*req));
1303 2 : if (req == NULL) {
1304 0 : spdk_bdev_close(desc);
1305 0 : cb_fn(cb_arg, NULL, -ENOMEM);
1306 0 : return;
1307 : }
1308 :
1309 2 : req->cb_fn = cb_fn;
1310 2 : req->cb_arg = cb_arg;
1311 :
1312 2 : sz = spdk_bdev_get_num_blocks(bdev) * spdk_bdev_get_block_size(bdev);
1313 2 : rc = spdk_lvol_create_esnap_clone(bdev_uuid, sizeof(bdev_uuid), sz, lvs, clone_name,
1314 : _vbdev_lvol_create_cb, req);
1315 2 : spdk_bdev_close(desc);
1316 2 : if (rc != 0) {
1317 0 : cb_fn(cb_arg, NULL, rc);
1318 0 : free(req);
1319 : }
1320 : }
1321 :
1322 : static void
1323 2 : _vbdev_lvol_rename_cb(void *cb_arg, int lvolerrno)
1324 : {
1325 2 : struct spdk_lvol_req *req = cb_arg;
1326 :
1327 2 : if (lvolerrno != 0) {
1328 0 : SPDK_ERRLOG("Renaming lvol failed\n");
1329 : }
1330 :
1331 2 : req->cb_fn(req->cb_arg, lvolerrno);
1332 2 : free(req);
1333 2 : }
1334 :
1335 : void
1336 3 : vbdev_lvol_rename(struct spdk_lvol *lvol, const char *new_lvol_name,
1337 : spdk_lvol_op_complete cb_fn, void *cb_arg)
1338 : {
1339 : struct spdk_lvol_req *req;
1340 : int rc;
1341 :
1342 3 : rc = _vbdev_lvol_change_bdev_alias(lvol, new_lvol_name);
1343 3 : if (rc != 0) {
1344 1 : SPDK_ERRLOG("renaming lvol to '%s' does not succeed\n", new_lvol_name);
1345 1 : cb_fn(cb_arg, rc);
1346 1 : return;
1347 : }
1348 :
1349 2 : req = calloc(1, sizeof(*req));
1350 2 : if (req == NULL) {
1351 0 : cb_fn(cb_arg, -ENOMEM);
1352 0 : return;
1353 : }
1354 2 : req->cb_fn = cb_fn;
1355 2 : req->cb_arg = cb_arg;
1356 :
1357 2 : spdk_lvol_rename(lvol, new_lvol_name, _vbdev_lvol_rename_cb, req);
1358 : }
1359 :
1360 : static void
1361 1 : _vbdev_lvol_resize_cb(void *cb_arg, int lvolerrno)
1362 : {
1363 1 : struct spdk_lvol_req *req = cb_arg;
1364 1 : struct spdk_lvol *lvol = req->lvol;
1365 : uint64_t total_size;
1366 :
1367 : /* change bdev size */
1368 1 : if (lvolerrno != 0) {
1369 0 : SPDK_ERRLOG("CB function for bdev lvol %s receive error no: %d.\n", lvol->name, lvolerrno);
1370 0 : goto finish;
1371 : }
1372 :
1373 1 : total_size = spdk_blob_get_num_clusters(lvol->blob) *
1374 1 : spdk_bs_get_cluster_size(lvol->lvol_store->blobstore);
1375 1 : assert((total_size % lvol->bdev->blocklen) == 0);
1376 :
1377 1 : lvolerrno = spdk_bdev_notify_blockcnt_change(lvol->bdev, total_size / lvol->bdev->blocklen);
1378 1 : if (lvolerrno != 0) {
1379 0 : SPDK_ERRLOG("Could not change num blocks for bdev lvol %s with error no: %d.\n",
1380 : lvol->name, lvolerrno);
1381 : }
1382 :
1383 1 : finish:
1384 1 : req->cb_fn(req->cb_arg, lvolerrno);
1385 1 : free(req);
1386 1 : }
1387 :
1388 : void
1389 2 : vbdev_lvol_resize(struct spdk_lvol *lvol, uint64_t sz, spdk_lvol_op_complete cb_fn, void *cb_arg)
1390 : {
1391 : struct spdk_lvol_req *req;
1392 :
1393 2 : if (lvol == NULL) {
1394 1 : SPDK_ERRLOG("lvol does not exist\n");
1395 1 : cb_fn(cb_arg, -EINVAL);
1396 1 : return;
1397 : }
1398 :
1399 1 : assert(lvol->bdev != NULL);
1400 :
1401 1 : req = calloc(1, sizeof(*req));
1402 1 : if (req == NULL) {
1403 0 : cb_fn(cb_arg, -ENOMEM);
1404 0 : return;
1405 : }
1406 :
1407 1 : req->cb_fn = cb_fn;
1408 1 : req->cb_arg = cb_arg;
1409 1 : req->sz = sz;
1410 1 : req->lvol = lvol;
1411 :
1412 1 : spdk_lvol_resize(req->lvol, req->sz, _vbdev_lvol_resize_cb, req);
1413 : }
1414 :
1415 : static void
1416 1 : _vbdev_lvol_set_read_only_cb(void *cb_arg, int lvolerrno)
1417 : {
1418 1 : struct spdk_lvol_req *req = cb_arg;
1419 1 : struct spdk_lvol *lvol = req->lvol;
1420 :
1421 1 : if (lvolerrno != 0) {
1422 0 : SPDK_ERRLOG("Could not set bdev lvol %s as read only due to error: %d.\n", lvol->name, lvolerrno);
1423 : }
1424 :
1425 1 : req->cb_fn(req->cb_arg, lvolerrno);
1426 1 : free(req);
1427 1 : }
1428 :
1429 : void
1430 1 : vbdev_lvol_set_read_only(struct spdk_lvol *lvol, spdk_lvol_op_complete cb_fn, void *cb_arg)
1431 : {
1432 : struct spdk_lvol_req *req;
1433 :
1434 1 : if (lvol == NULL) {
1435 0 : SPDK_ERRLOG("lvol does not exist\n");
1436 0 : cb_fn(cb_arg, -EINVAL);
1437 0 : return;
1438 : }
1439 :
1440 1 : assert(lvol->bdev != NULL);
1441 :
1442 1 : req = calloc(1, sizeof(*req));
1443 1 : if (req == NULL) {
1444 0 : cb_fn(cb_arg, -ENOMEM);
1445 0 : return;
1446 : }
1447 :
1448 1 : req->cb_fn = cb_fn;
1449 1 : req->cb_arg = cb_arg;
1450 1 : req->lvol = lvol;
1451 :
1452 1 : spdk_lvol_set_read_only(lvol, _vbdev_lvol_set_read_only_cb, req);
1453 : }
1454 :
1455 : static int
1456 0 : vbdev_lvs_init(void)
1457 : {
1458 0 : return 0;
1459 : }
1460 :
1461 : static void vbdev_lvs_fini_start_iter(struct lvol_store_bdev *lvs_bdev);
1462 :
1463 : static void
1464 1 : vbdev_lvs_fini_start_unload_cb(void *cb_arg, int lvserrno)
1465 : {
1466 1 : struct lvol_store_bdev *lvs_bdev = cb_arg;
1467 1 : struct lvol_store_bdev *next_lvs_bdev = vbdev_lvol_store_next(lvs_bdev);
1468 :
1469 1 : if (lvserrno != 0) {
1470 0 : SPDK_INFOLOG(vbdev_lvol, "Lvol store removed with error: %d.\n", lvserrno);
1471 : }
1472 :
1473 1 : TAILQ_REMOVE(&g_spdk_lvol_pairs, lvs_bdev, lvol_stores);
1474 1 : free(lvs_bdev);
1475 :
1476 1 : vbdev_lvs_fini_start_iter(next_lvs_bdev);
1477 1 : }
1478 :
1479 : static void
1480 3 : vbdev_lvs_fini_start_iter(struct lvol_store_bdev *lvs_bdev)
1481 : {
1482 : struct spdk_lvol_store *lvs;
1483 :
1484 4 : while (lvs_bdev != NULL) {
1485 2 : lvs = lvs_bdev->lvs;
1486 :
1487 2 : if (_vbdev_lvs_are_lvols_closed(lvs)) {
1488 1 : spdk_lvs_unload(lvs, vbdev_lvs_fini_start_unload_cb, lvs_bdev);
1489 1 : return;
1490 : }
1491 1 : lvs_bdev = vbdev_lvol_store_next(lvs_bdev);
1492 : }
1493 :
1494 2 : spdk_bdev_module_fini_start_done();
1495 : }
1496 :
1497 : static void
1498 2 : vbdev_lvs_fini_start(void)
1499 : {
1500 2 : g_shutdown_started = true;
1501 2 : vbdev_lvs_fini_start_iter(vbdev_lvol_store_first());
1502 2 : }
1503 :
1504 : static int
1505 2 : vbdev_lvs_get_ctx_size(void)
1506 : {
1507 2 : return sizeof(struct vbdev_lvol_io);
1508 : }
1509 :
1510 : static void
1511 6 : _vbdev_lvs_examine_done(struct spdk_lvs_req *req, int lvserrno)
1512 : {
1513 6 : req->cb_fn(req->cb_arg, lvserrno);
1514 6 : }
1515 :
1516 : static void
1517 0 : _vbdev_lvs_examine_failed(void *cb_arg, int lvserrno)
1518 : {
1519 0 : struct spdk_lvs_req *req = cb_arg;
1520 :
1521 0 : _vbdev_lvs_examine_done(req, req->lvserrno);
1522 0 : }
1523 :
1524 : static void
1525 11 : _vbdev_lvs_examine_finish(void *cb_arg, struct spdk_lvol *lvol, int lvolerrno)
1526 : {
1527 11 : struct spdk_lvs_req *req = cb_arg;
1528 11 : struct spdk_lvol_store *lvs = req->lvol_store;
1529 :
1530 11 : if (lvolerrno != 0) {
1531 2 : TAILQ_REMOVE(&lvs->lvols, lvol, link);
1532 2 : if (lvolerrno == -ENOMEM) {
1533 1 : TAILQ_INSERT_TAIL(&lvs->retry_open_lvols, lvol, link);
1534 1 : return;
1535 : }
1536 1 : SPDK_ERRLOG("Error opening lvol %s\n", lvol->unique_id);
1537 1 : lvs->lvol_count--;
1538 1 : free(lvol);
1539 1 : goto end;
1540 : }
1541 :
1542 9 : if (_create_lvol_disk(lvol, false)) {
1543 0 : SPDK_ERRLOG("Cannot create bdev for lvol %s\n", lvol->unique_id);
1544 0 : lvs->lvol_count--;
1545 0 : goto end;
1546 : }
1547 :
1548 9 : lvs->lvols_opened++;
1549 9 : SPDK_INFOLOG(vbdev_lvol, "Opening lvol %s succeeded\n", lvol->unique_id);
1550 :
1551 9 : end:
1552 10 : if (!TAILQ_EMPTY(&lvs->retry_open_lvols)) {
1553 1 : lvol = TAILQ_FIRST(&lvs->retry_open_lvols);
1554 1 : TAILQ_REMOVE(&lvs->retry_open_lvols, lvol, link);
1555 1 : TAILQ_INSERT_HEAD(&lvs->lvols, lvol, link);
1556 1 : spdk_lvol_open(lvol, _vbdev_lvs_examine_finish, req);
1557 1 : return;
1558 : }
1559 9 : if (lvs->lvols_opened >= lvs->lvol_count) {
1560 4 : SPDK_INFOLOG(vbdev_lvol, "Opening lvols finished\n");
1561 4 : _vbdev_lvs_examine_done(req, 0);
1562 : }
1563 : }
1564 :
1565 : /* Walks a tree of clones that are no longer degraded to create bdevs. */
1566 : static int
1567 0 : create_esnap_clone_lvol_disks(void *ctx, struct spdk_lvol *lvol)
1568 : {
1569 0 : struct spdk_bdev *bdev = ctx;
1570 : int rc;
1571 :
1572 0 : rc = _create_lvol_disk(lvol, false);
1573 0 : if (rc != 0) {
1574 0 : SPDK_ERRLOG("lvol %s: failed to create bdev after esnap hotplug of %s: %d\n",
1575 : lvol->unique_id, spdk_bdev_get_name(bdev), rc);
1576 : /* Do not prevent creation of other clones in case of one failure. */
1577 0 : return 0;
1578 : }
1579 :
1580 0 : return spdk_lvol_iter_immediate_clones(lvol, create_esnap_clone_lvol_disks, ctx);
1581 : }
1582 :
1583 : static void
1584 0 : vbdev_lvs_hotplug(void *ctx, struct spdk_lvol *lvol, int lvolerrno)
1585 : {
1586 0 : struct spdk_bdev *esnap_clone_bdev = ctx;
1587 :
1588 0 : if (lvolerrno != 0) {
1589 0 : SPDK_ERRLOG("lvol %s: during examine of bdev %s: not creating clone bdev due to "
1590 : "error %d\n", lvol->unique_id, spdk_bdev_get_name(esnap_clone_bdev),
1591 : lvolerrno);
1592 0 : return;
1593 : }
1594 0 : create_esnap_clone_lvol_disks(esnap_clone_bdev, lvol);
1595 : }
1596 :
1597 : static void
1598 2 : vbdev_lvs_examine_config(struct spdk_bdev *bdev)
1599 : {
1600 2 : char uuid_str[SPDK_UUID_STRING_LEN];
1601 :
1602 2 : spdk_uuid_fmt_lower(uuid_str, sizeof(uuid_str), &bdev->uuid);
1603 :
1604 2 : if (spdk_lvs_notify_hotplug(uuid_str, sizeof(uuid_str), vbdev_lvs_hotplug, bdev)) {
1605 1 : SPDK_INFOLOG(vbdev_lvol, "bdev %s: claimed by one or more esnap clones\n",
1606 : uuid_str);
1607 : }
1608 2 : spdk_bdev_module_examine_done(&g_lvol_if);
1609 2 : }
1610 :
1611 : static void
1612 5 : _vbdev_lvs_examine_cb(void *arg, struct spdk_lvol_store *lvol_store, int lvserrno)
1613 : {
1614 : struct lvol_store_bdev *lvs_bdev;
1615 5 : struct spdk_lvs_with_handle_req *req = (struct spdk_lvs_with_handle_req *)arg;
1616 : struct spdk_lvol *lvol, *tmp;
1617 5 : struct spdk_lvs_req *ori_req = req->cb_arg;
1618 :
1619 5 : if (lvserrno == -EEXIST) {
1620 0 : SPDK_INFOLOG(vbdev_lvol,
1621 : "Name for lvolstore on device %s conflicts with name for already loaded lvs\n",
1622 : req->base_bdev->name);
1623 : /* On error blobstore destroys bs_dev itself */
1624 0 : _vbdev_lvs_examine_done(ori_req, lvserrno);
1625 0 : goto end;
1626 5 : } else if (lvserrno != 0) {
1627 1 : SPDK_INFOLOG(vbdev_lvol, "Lvol store not found on %s\n", req->base_bdev->name);
1628 : /* On error blobstore destroys bs_dev itself */
1629 1 : _vbdev_lvs_examine_done(ori_req, lvserrno);
1630 1 : goto end;
1631 : }
1632 :
1633 4 : lvserrno = spdk_bs_bdev_claim(lvol_store->bs_dev, &g_lvol_if);
1634 4 : if (lvserrno != 0) {
1635 0 : SPDK_INFOLOG(vbdev_lvol, "Lvol store base bdev already claimed by another bdev\n");
1636 0 : ori_req->lvserrno = lvserrno;
1637 0 : spdk_lvs_unload(lvol_store, _vbdev_lvs_examine_failed, ori_req);
1638 0 : goto end;
1639 : }
1640 :
1641 4 : lvs_bdev = calloc(1, sizeof(*lvs_bdev));
1642 4 : if (!lvs_bdev) {
1643 0 : SPDK_ERRLOG("Cannot alloc memory for lvs_bdev\n");
1644 0 : ori_req->lvserrno = lvserrno;
1645 0 : spdk_lvs_unload(lvol_store, _vbdev_lvs_examine_failed, ori_req);
1646 0 : goto end;
1647 : }
1648 :
1649 4 : lvs_bdev->lvs = lvol_store;
1650 4 : lvs_bdev->bdev = req->base_bdev;
1651 :
1652 4 : TAILQ_INSERT_TAIL(&g_spdk_lvol_pairs, lvs_bdev, lvol_stores);
1653 :
1654 4 : SPDK_INFOLOG(vbdev_lvol, "Lvol store found on %s - begin parsing\n",
1655 : req->base_bdev->name);
1656 :
1657 4 : lvol_store->lvols_opened = 0;
1658 :
1659 4 : ori_req->lvol_store = lvol_store;
1660 :
1661 4 : if (TAILQ_EMPTY(&lvol_store->lvols)) {
1662 0 : SPDK_INFOLOG(vbdev_lvol, "Lvol store examination done\n");
1663 0 : _vbdev_lvs_examine_done(ori_req, 0);
1664 : } else {
1665 : /* Open all lvols */
1666 14 : TAILQ_FOREACH_SAFE(lvol, &lvol_store->lvols, link, tmp) {
1667 10 : spdk_lvol_open(lvol, _vbdev_lvs_examine_finish, ori_req);
1668 : }
1669 : }
1670 :
1671 4 : end:
1672 5 : free(req);
1673 5 : }
1674 :
1675 : static void
1676 6 : _vbdev_lvs_examine(struct spdk_bdev *bdev, struct spdk_lvs_req *ori_req,
1677 : void (*action)(struct spdk_bs_dev *bs_dev, spdk_lvs_op_with_handle_complete cb_fn, void *cb_arg))
1678 : {
1679 6 : struct spdk_bs_dev *bs_dev;
1680 : struct spdk_lvs_with_handle_req *req;
1681 : int rc;
1682 :
1683 6 : req = calloc(1, sizeof(*req));
1684 6 : if (req == NULL) {
1685 0 : SPDK_ERRLOG("Cannot alloc memory for vbdev lvol store request pointer\n");
1686 0 : _vbdev_lvs_examine_done(ori_req, -ENOMEM);
1687 0 : return;
1688 : }
1689 :
1690 6 : rc = spdk_bdev_create_bs_dev_ext(bdev->name, vbdev_lvs_base_bdev_event_cb,
1691 : NULL, &bs_dev);
1692 6 : if (rc < 0) {
1693 1 : SPDK_INFOLOG(vbdev_lvol, "Cannot create bs dev on %s\n", bdev->name);
1694 1 : _vbdev_lvs_examine_done(ori_req, rc);
1695 1 : free(req);
1696 1 : return;
1697 : }
1698 :
1699 5 : req->base_bdev = bdev;
1700 5 : req->cb_arg = ori_req;
1701 :
1702 5 : action(bs_dev, _vbdev_lvs_examine_cb, req);
1703 : }
1704 :
1705 : static void
1706 6 : vbdev_lvs_examine_done(void *arg, int lvserrno)
1707 : {
1708 6 : struct spdk_lvs_req *req = arg;
1709 :
1710 6 : spdk_bdev_module_examine_done(&g_lvol_if);
1711 6 : free(req);
1712 6 : }
1713 :
1714 : static void
1715 5 : vbdev_lvs_load(struct spdk_bs_dev *bs_dev, spdk_lvs_op_with_handle_complete cb_fn, void *cb_arg)
1716 : {
1717 5 : struct spdk_lvs_opts lvs_opts;
1718 :
1719 5 : spdk_lvs_opts_init(&lvs_opts);
1720 5 : lvs_opts.esnap_bs_dev_create = vbdev_lvol_esnap_dev_create;
1721 5 : spdk_lvs_load_ext(bs_dev, &lvs_opts, cb_fn, cb_arg);
1722 5 : }
1723 :
1724 : static void
1725 6 : vbdev_lvs_examine_disk(struct spdk_bdev *bdev)
1726 : {
1727 : struct spdk_lvs_req *req;
1728 :
1729 6 : if (spdk_bdev_get_md_size(bdev) != 0) {
1730 0 : SPDK_INFOLOG(vbdev_lvol, "Cannot create bs dev on %s\n which is formatted with metadata",
1731 : bdev->name);
1732 0 : spdk_bdev_module_examine_done(&g_lvol_if);
1733 0 : return;
1734 : }
1735 :
1736 6 : req = calloc(1, sizeof(*req));
1737 6 : if (req == NULL) {
1738 0 : SPDK_ERRLOG("Cannot alloc memory for vbdev lvol store request pointer\n");
1739 0 : spdk_bdev_module_examine_done(&g_lvol_if);
1740 0 : return;
1741 : }
1742 :
1743 6 : req->cb_fn = vbdev_lvs_examine_done;
1744 6 : req->cb_arg = req;
1745 :
1746 6 : _vbdev_lvs_examine(bdev, req, vbdev_lvs_load);
1747 : }
1748 :
1749 : struct spdk_lvol *
1750 0 : vbdev_lvol_get_from_bdev(struct spdk_bdev *bdev)
1751 : {
1752 0 : if (!bdev || bdev->module != &g_lvol_if) {
1753 0 : return NULL;
1754 : }
1755 :
1756 0 : if (bdev->ctxt == NULL) {
1757 0 : SPDK_ERRLOG("No lvol ctx assigned to bdev %s\n", bdev->name);
1758 0 : return NULL;
1759 : }
1760 :
1761 0 : return (struct spdk_lvol *)bdev->ctxt;
1762 : }
1763 :
1764 : /* Begin degraded blobstore device */
1765 :
1766 : /*
1767 : * When an external snapshot is missing, an instance of bs_dev_degraded is used as the blob's
1768 : * back_bs_dev. No bdev is registered, so there should be no IO nor requests for channels. The main
1769 : * purposes of this device are to prevent blobstore from hitting fatal runtime errors and to
1770 : * indicate that the blob is degraded via the is_degraded() callback.
1771 : */
1772 :
1773 : static void
1774 0 : bs_dev_degraded_read(struct spdk_bs_dev *dev, struct spdk_io_channel *channel, void *payload,
1775 : uint64_t lba, uint32_t lba_count, struct spdk_bs_dev_cb_args *cb_args)
1776 : {
1777 0 : assert(false);
1778 : cb_args->cb_fn(cb_args->channel, cb_args->cb_arg, -EIO);
1779 : }
1780 :
1781 : static void
1782 0 : bs_dev_degraded_readv(struct spdk_bs_dev *dev, struct spdk_io_channel *channel,
1783 : struct iovec *iov, int iovcnt, uint64_t lba, uint32_t lba_count,
1784 : struct spdk_bs_dev_cb_args *cb_args)
1785 : {
1786 0 : assert(false);
1787 : cb_args->cb_fn(cb_args->channel, cb_args->cb_arg, -EIO);
1788 : }
1789 :
1790 : static void
1791 0 : bs_dev_degraded_readv_ext(struct spdk_bs_dev *dev, struct spdk_io_channel *channel,
1792 : struct iovec *iov, int iovcnt, uint64_t lba, uint32_t lba_count,
1793 : struct spdk_bs_dev_cb_args *cb_args,
1794 : struct spdk_blob_ext_io_opts *io_opts)
1795 : {
1796 0 : assert(false);
1797 : cb_args->cb_fn(cb_args->channel, cb_args->cb_arg, -EIO);
1798 : }
1799 :
1800 : static bool
1801 0 : bs_dev_degraded_is_zeroes(struct spdk_bs_dev *dev, uint64_t lba, uint64_t lba_count)
1802 : {
1803 0 : assert(false);
1804 : return false;
1805 : }
1806 :
1807 : static bool
1808 0 : bs_dev_degraded_is_range_valid(struct spdk_bs_dev *dev, uint64_t lba, uint64_t lba_count)
1809 : {
1810 0 : assert(false);
1811 : return false;
1812 : }
1813 :
1814 : static struct spdk_io_channel *
1815 0 : bs_dev_degraded_create_channel(struct spdk_bs_dev *bs_dev)
1816 : {
1817 0 : assert(false);
1818 : return NULL;
1819 : }
1820 :
1821 : static void
1822 0 : bs_dev_degraded_destroy_channel(struct spdk_bs_dev *bs_dev, struct spdk_io_channel *channel)
1823 : {
1824 0 : assert(false);
1825 : }
1826 :
1827 : static void
1828 2 : bs_dev_degraded_destroy(struct spdk_bs_dev *bs_dev)
1829 : {
1830 2 : }
1831 :
1832 : static bool
1833 0 : bs_dev_degraded_is_degraded(struct spdk_bs_dev *bs_dev)
1834 : {
1835 0 : return true;
1836 : }
1837 :
1838 : static struct spdk_bs_dev bs_dev_degraded = {
1839 : .create_channel = bs_dev_degraded_create_channel,
1840 : .destroy_channel = bs_dev_degraded_destroy_channel,
1841 : .destroy = bs_dev_degraded_destroy,
1842 : .read = bs_dev_degraded_read,
1843 : .readv = bs_dev_degraded_readv,
1844 : .readv_ext = bs_dev_degraded_readv_ext,
1845 : .is_zeroes = bs_dev_degraded_is_zeroes,
1846 : .is_range_valid = bs_dev_degraded_is_range_valid,
1847 : .is_degraded = bs_dev_degraded_is_degraded,
1848 : /* Make the device as large as possible without risk of uint64 overflow. */
1849 : .blockcnt = UINT64_MAX / 512,
1850 : /* Prevent divide by zero errors calculating LBAs that will never be read. */
1851 : .blocklen = 512,
1852 : };
1853 :
1854 : /* End degraded blobstore device */
1855 :
1856 : /* Begin external snapshot support */
1857 :
1858 : static void
1859 0 : vbdev_lvol_esnap_bdev_event_cb(enum spdk_bdev_event_type type, struct spdk_bdev *bdev,
1860 : void *event_ctx)
1861 : {
1862 0 : SPDK_NOTICELOG("bdev name (%s) received unsupported event type %d\n",
1863 : spdk_bdev_get_name(bdev), type);
1864 0 : }
1865 :
1866 : int
1867 6 : vbdev_lvol_esnap_dev_create(void *bs_ctx, void *blob_ctx, struct spdk_blob *blob,
1868 : const void *esnap_id, uint32_t id_len,
1869 : struct spdk_bs_dev **_bs_dev)
1870 : {
1871 6 : struct spdk_lvol_store *lvs = bs_ctx;
1872 6 : struct spdk_lvol *lvol = blob_ctx;
1873 6 : struct spdk_bs_dev *bs_dev = NULL;
1874 6 : struct spdk_uuid uuid;
1875 : int rc;
1876 6 : char uuid_str[SPDK_UUID_STRING_LEN] = { 0 };
1877 :
1878 6 : if (esnap_id == NULL) {
1879 1 : SPDK_ERRLOG("lvol %s: NULL esnap ID\n", lvol->unique_id);
1880 1 : return -EINVAL;
1881 : }
1882 :
1883 : /* Guard against arbitrary names and unterminated UUID strings */
1884 5 : if (id_len != SPDK_UUID_STRING_LEN) {
1885 1 : SPDK_ERRLOG("lvol %s: Invalid esnap ID length (%u)\n", lvol->unique_id, id_len);
1886 1 : return -EINVAL;
1887 : }
1888 :
1889 4 : if (spdk_uuid_parse(&uuid, esnap_id)) {
1890 1 : SPDK_ERRLOG("lvol %s: Invalid esnap ID: not a UUID\n", lvol->unique_id);
1891 1 : return -EINVAL;
1892 : }
1893 :
1894 : /* Format the UUID the same as it is in the bdev names tree. */
1895 3 : spdk_uuid_fmt_lower(uuid_str, sizeof(uuid_str), &uuid);
1896 3 : if (strcmp(uuid_str, esnap_id) != 0) {
1897 0 : SPDK_WARNLOG("lvol %s: esnap_id '%*s' does not match parsed uuid '%s'\n",
1898 : lvol->unique_id, SPDK_UUID_STRING_LEN, (const char *)esnap_id,
1899 : uuid_str);
1900 0 : assert(false);
1901 : }
1902 :
1903 3 : rc = spdk_bdev_create_bs_dev(uuid_str, false, NULL, 0,
1904 : vbdev_lvol_esnap_bdev_event_cb, NULL, &bs_dev);
1905 3 : if (rc != 0) {
1906 2 : goto fail;
1907 : }
1908 :
1909 1 : rc = spdk_bs_bdev_claim(bs_dev, &g_lvol_if);
1910 1 : if (rc != 0) {
1911 0 : SPDK_ERRLOG("lvol %s: unable to claim esnap bdev '%s': %d\n", lvol->unique_id,
1912 : uuid_str, rc);
1913 0 : bs_dev->destroy(bs_dev);
1914 0 : goto fail;
1915 : }
1916 :
1917 1 : *_bs_dev = bs_dev;
1918 1 : return 0;
1919 :
1920 2 : fail:
1921 : /* Unable to open or claim the bdev. This lvol is degraded. */
1922 2 : bs_dev = &bs_dev_degraded;
1923 2 : SPDK_NOTICELOG("lvol %s: bdev %s not available: lvol is degraded\n", lvol->unique_id,
1924 : uuid_str);
1925 :
1926 : /*
1927 : * Be sure not to call spdk_lvs_missing_add() on an lvol that is already degraded. This can
1928 : * lead to a cycle in the degraded_lvols tailq.
1929 : */
1930 2 : if (lvol->degraded_set == NULL) {
1931 2 : rc = spdk_lvs_esnap_missing_add(lvs, lvol, uuid_str, sizeof(uuid_str));
1932 2 : if (rc != 0) {
1933 2 : SPDK_NOTICELOG("lvol %s: unable to register missing esnap device %s: "
1934 : "it will not be hotplugged if added later\n",
1935 : lvol->unique_id, uuid_str);
1936 : }
1937 : }
1938 :
1939 2 : *_bs_dev = bs_dev;
1940 2 : return 0;
1941 : }
1942 :
1943 : /* End external snapshot support */
1944 :
1945 : static void
1946 0 : _vbdev_lvol_shallow_copy_base_bdev_event_cb(enum spdk_bdev_event_type type, struct spdk_bdev *bdev,
1947 : void *event_ctx)
1948 : {
1949 0 : }
1950 :
1951 : static void
1952 1 : _vbdev_lvol_shallow_copy_cb(void *cb_arg, int lvolerrno)
1953 : {
1954 1 : struct spdk_lvol_copy_req *req = cb_arg;
1955 1 : struct spdk_lvol *lvol = req->lvol;
1956 :
1957 1 : if (lvolerrno != 0) {
1958 0 : SPDK_ERRLOG("Could not make a shallow copy of lvol %s due to error: %d\n",
1959 : lvol->name, lvolerrno);
1960 : }
1961 :
1962 1 : req->ext_dev->destroy(req->ext_dev);
1963 1 : req->cb_fn(req->cb_arg, lvolerrno);
1964 1 : free(req);
1965 1 : }
1966 :
1967 : int
1968 3 : vbdev_lvol_shallow_copy(struct spdk_lvol *lvol, const char *bdev_name,
1969 : spdk_blob_shallow_copy_status status_cb_fn, void *status_cb_arg,
1970 : spdk_lvol_op_complete cb_fn, void *cb_arg)
1971 : {
1972 3 : struct spdk_bs_dev *ext_dev;
1973 : struct spdk_lvol_copy_req *req;
1974 : int rc;
1975 :
1976 3 : if (lvol == NULL) {
1977 1 : SPDK_ERRLOG("lvol must not be NULL\n");
1978 1 : return -EINVAL;
1979 : }
1980 :
1981 2 : if (bdev_name == NULL) {
1982 1 : SPDK_ERRLOG("lvol %s, bdev name must not be NULL\n", lvol->name);
1983 1 : return -EINVAL;
1984 : }
1985 :
1986 1 : assert(lvol->bdev != NULL);
1987 :
1988 1 : req = calloc(1, sizeof(*req));
1989 1 : if (req == NULL) {
1990 0 : SPDK_ERRLOG("lvol %s, cannot alloc memory for lvol copy request\n", lvol->name);
1991 0 : return -ENOMEM;
1992 : }
1993 :
1994 1 : rc = spdk_bdev_create_bs_dev_ext(bdev_name, _vbdev_lvol_shallow_copy_base_bdev_event_cb,
1995 : NULL, &ext_dev);
1996 1 : if (rc < 0) {
1997 0 : SPDK_ERRLOG("lvol %s, cannot create blobstore block device from bdev %s\n", lvol->name, bdev_name);
1998 0 : free(req);
1999 0 : return rc;
2000 : }
2001 :
2002 1 : rc = spdk_bs_bdev_claim(ext_dev, &g_lvol_if);
2003 1 : if (rc != 0) {
2004 0 : SPDK_ERRLOG("lvol %s, unable to claim bdev %s, error %d\n", lvol->name, bdev_name, rc);
2005 0 : ext_dev->destroy(ext_dev);
2006 0 : free(req);
2007 0 : return rc;
2008 : }
2009 :
2010 1 : req->cb_fn = cb_fn;
2011 1 : req->cb_arg = cb_arg;
2012 1 : req->lvol = lvol;
2013 1 : req->ext_dev = ext_dev;
2014 :
2015 1 : rc = spdk_lvol_shallow_copy(lvol, ext_dev, status_cb_fn, status_cb_arg, _vbdev_lvol_shallow_copy_cb,
2016 : req);
2017 :
2018 1 : if (rc < 0) {
2019 0 : ext_dev->destroy(ext_dev);
2020 0 : free(req);
2021 : }
2022 :
2023 1 : return rc;
2024 : }
2025 :
2026 : void
2027 3 : vbdev_lvol_set_external_parent(struct spdk_lvol *lvol, const char *esnap_name,
2028 : spdk_lvol_op_complete cb_fn, void *cb_arg)
2029 : {
2030 3 : struct spdk_bdev_desc *desc;
2031 : struct spdk_bdev *bdev;
2032 3 : char bdev_uuid[SPDK_UUID_STRING_LEN];
2033 : int rc;
2034 :
2035 3 : rc = spdk_bdev_open_ext(esnap_name, false, ignore_bdev_event_cb, NULL, &desc);
2036 3 : if (rc != 0) {
2037 1 : SPDK_ERRLOG("bdev '%s' could not be opened: error %d\n", esnap_name, rc);
2038 1 : cb_fn(cb_arg, -ENODEV);
2039 1 : return;
2040 : }
2041 2 : bdev = spdk_bdev_desc_get_bdev(desc);
2042 :
2043 2 : rc = spdk_uuid_fmt_lower(bdev_uuid, sizeof(bdev_uuid), spdk_bdev_get_uuid(bdev));
2044 2 : if (rc != 0) {
2045 0 : spdk_bdev_close(desc);
2046 0 : SPDK_ERRLOG("bdev %s: unable to parse UUID\n", esnap_name);
2047 0 : assert(false);
2048 : cb_fn(cb_arg, -ENODEV);
2049 : return;
2050 : }
2051 :
2052 : /*
2053 : * If lvol store is not loaded from disk, and so vbdev_lvs_load is not called, these
2054 : * assignments are necessary to let vbdev_lvol_esnap_dev_create be called.
2055 : */
2056 2 : lvol->lvol_store->load_esnaps = true;
2057 2 : lvol->lvol_store->esnap_bs_dev_create = vbdev_lvol_esnap_dev_create;
2058 :
2059 2 : spdk_lvol_set_external_parent(lvol, bdev_uuid, sizeof(bdev_uuid), cb_fn, cb_arg);
2060 :
2061 2 : spdk_bdev_close(desc);
2062 : }
2063 :
2064 1 : SPDK_LOG_REGISTER_COMPONENT(vbdev_lvol)
|