Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright (C) 2018 Intel Corporation.
3 : : * All rights reserved.
4 : : * Copyright (c) 2022, 2023 NVIDIA CORPORATION & AFFILIATES.
5 : : * All rights reserved.
6 : : */
7 : :
8 : : #include "vbdev_crypto.h"
9 : :
10 : : #include "spdk_internal/assert.h"
11 : : #include "spdk/thread.h"
12 : : #include "spdk/bdev_module.h"
13 : : #include "spdk/likely.h"
14 : :
15 : : /* This namespace UUID was generated using uuid_generate() method. */
16 : : #define BDEV_CRYPTO_NAMESPACE_UUID "078e3cf7-f4b4-4545-b2c3-d40045a64ae2"
17 : :
18 : : struct bdev_names {
19 : : struct vbdev_crypto_opts *opts;
20 : : TAILQ_ENTRY(bdev_names) link;
21 : : };
22 : :
23 : : /* List of crypto_bdev names and their base bdevs via configuration file. */
24 : : static TAILQ_HEAD(, bdev_names) g_bdev_names = TAILQ_HEAD_INITIALIZER(g_bdev_names);
25 : :
26 : : struct vbdev_crypto {
27 : : struct spdk_bdev *base_bdev; /* the thing we're attaching to */
28 : : struct spdk_bdev_desc *base_desc; /* its descriptor we get from open */
29 : : struct spdk_bdev crypto_bdev; /* the crypto virtual bdev */
30 : : struct vbdev_crypto_opts *opts; /* crypto options such as names and DEK */
31 : : TAILQ_ENTRY(vbdev_crypto) link;
32 : : struct spdk_thread *thread; /* thread where base device is opened */
33 : : };
34 : :
35 : : /* List of virtual bdevs and associated info for each. We keep the device friendly name here even
36 : : * though its also in the device struct because we use it early on.
37 : : */
38 : : static TAILQ_HEAD(, vbdev_crypto) g_vbdev_crypto = TAILQ_HEAD_INITIALIZER(g_vbdev_crypto);
39 : :
40 : : /* The crypto vbdev channel struct. It is allocated and freed on my behalf by the io channel code.
41 : : * We store things in here that are needed on per thread basis like the base_channel for this thread.
42 : : */
43 : : struct crypto_io_channel {
44 : : struct spdk_io_channel *base_ch; /* IO channel of base device */
45 : : struct spdk_io_channel *accel_channel; /* Accel engine channel used for crypto ops */
46 : : struct spdk_accel_crypto_key *crypto_key;
47 : : };
48 : :
49 : : enum crypto_io_resubmit_state {
50 : : CRYPTO_IO_DECRYPT_DONE, /* Appended decrypt, need to read */
51 : : CRYPTO_IO_ENCRYPT_DONE, /* Need to write */
52 : : };
53 : :
54 : : /* This is the crypto per IO context that the bdev layer allocates for us opaquely and attaches to
55 : : * each IO for us.
56 : : */
57 : : struct crypto_bdev_io {
58 : : struct crypto_io_channel *crypto_ch; /* need to store for crypto completion handling */
59 : : struct vbdev_crypto *crypto_bdev; /* the crypto node struct associated with this IO */
60 : : /* Used for the single contiguous buffer that serves as the crypto destination target for writes */
61 : : uint64_t aux_num_blocks; /* num of blocks for the contiguous buffer */
62 : : uint64_t aux_offset_blocks; /* block offset on media */
63 : : void *aux_buf_raw; /* raw buffer that the bdev layer gave us for write buffer */
64 : : struct iovec aux_buf_iov; /* iov representing aligned contig write buffer */
65 : : struct spdk_memory_domain *aux_domain; /* memory domain of the aux buf */
66 : : void *aux_domain_ctx; /* memory domain ctx of the aux buf */
67 : : struct spdk_accel_sequence *seq; /* sequence of accel operations */
68 : :
69 : : /* for bdev_io_wait */
70 : : struct spdk_bdev_io_wait_entry bdev_io_wait;
71 : : enum crypto_io_resubmit_state resubmit_state;
72 : : };
73 : :
74 : : static void vbdev_crypto_queue_io(struct spdk_bdev_io *bdev_io,
75 : : enum crypto_io_resubmit_state state);
76 : : static void _complete_internal_io(struct spdk_bdev_io *bdev_io, bool success, void *cb_arg);
77 : : static void vbdev_crypto_examine(struct spdk_bdev *bdev);
78 : : static int vbdev_crypto_claim(const char *bdev_name);
79 : : static void vbdev_crypto_submit_request(struct spdk_io_channel *ch, struct spdk_bdev_io *bdev_io);
80 : :
81 : : static void
82 : 14 : crypto_io_fail(struct crypto_bdev_io *crypto_io)
83 : : {
84 : 14 : struct spdk_bdev_io *bdev_io = spdk_bdev_io_from_ctx(crypto_io);
85 : 14 : struct crypto_io_channel *crypto_ch = crypto_io->crypto_ch;
86 : :
87 [ + + ]: 14 : if (crypto_io->aux_buf_raw) {
88 : 4 : spdk_accel_put_buf(crypto_ch->accel_channel, crypto_io->aux_buf_raw,
89 : : crypto_io->aux_domain, crypto_io->aux_domain_ctx);
90 : : }
91 : :
92 : : /* This function can only be used to fail an IO that hasn't been sent to the base bdev,
93 : : * otherwise accel sequence might have already been executed/aborted. */
94 : 14 : spdk_accel_sequence_abort(crypto_io->seq);
95 : 14 : spdk_bdev_io_complete(bdev_io, SPDK_BDEV_IO_STATUS_FAILED);
96 : 14 : }
97 : :
98 : : static void
99 : 4356273 : crypto_write(struct crypto_io_channel *crypto_ch, struct spdk_bdev_io *bdev_io)
100 : : {
101 : 4356273 : struct vbdev_crypto *crypto_bdev = SPDK_CONTAINEROF(bdev_io->bdev, struct vbdev_crypto,
102 : : crypto_bdev);
103 : 4356273 : struct crypto_bdev_io *crypto_io = (struct crypto_bdev_io *)bdev_io->driver_ctx;
104 : 4356273 : struct spdk_bdev_ext_io_opts opts = {};
105 : : int rc;
106 : :
107 : 4356273 : opts.size = sizeof(opts);
108 : 4356273 : opts.accel_sequence = crypto_io->seq;
109 : 4356273 : opts.memory_domain = crypto_io->aux_domain;
110 : 4356273 : opts.memory_domain_ctx = crypto_io->aux_domain_ctx;
111 : :
112 : : /* Write the encrypted data. */
113 : 4356273 : rc = spdk_bdev_writev_blocks_ext(crypto_bdev->base_desc, crypto_ch->base_ch,
114 : : &crypto_io->aux_buf_iov, 1, crypto_io->aux_offset_blocks,
115 : : crypto_io->aux_num_blocks, _complete_internal_io,
116 : : bdev_io, &opts);
117 [ + + ]: 4356273 : if (spdk_unlikely(rc != 0)) {
118 [ + + ]: 6 : if (rc == -ENOMEM) {
119 [ - + - + ]: 2 : SPDK_DEBUGLOG(vbdev_crypto, "No memory, queue the IO.\n");
120 : 2 : vbdev_crypto_queue_io(bdev_io, CRYPTO_IO_ENCRYPT_DONE);
121 : : } else {
122 : 4 : SPDK_ERRLOG("Failed to submit bdev_io!\n");
123 : 4 : crypto_io_fail(crypto_io);
124 : : }
125 : : }
126 : 4356273 : }
127 : :
128 : : /* We're either encrypting on the way down or decrypting on the way back. */
129 : : static void
130 : 4399538 : crypto_encrypt(struct crypto_io_channel *crypto_ch, struct spdk_bdev_io *bdev_io)
131 : : {
132 : 4399538 : struct crypto_bdev_io *crypto_io = (struct crypto_bdev_io *)bdev_io->driver_ctx;
133 : 4399538 : uint32_t blocklen = crypto_io->crypto_bdev->crypto_bdev.blocklen;
134 : : uint64_t total_length;
135 : : uint64_t alignment;
136 : 4399538 : void *aux_buf = crypto_io->aux_buf_raw;
137 : : int rc;
138 : :
139 : : /* For encryption, we need to prepare a single contiguous buffer as the encryption
140 : : * destination, we'll then pass that along for the write after encryption is done.
141 : : * This is done to avoiding encrypting the provided write buffer which may be
142 : : * undesirable in some use cases.
143 : : */
144 : 4399538 : total_length = bdev_io->u.bdev.num_blocks * blocklen;
145 : 4399538 : alignment = spdk_bdev_get_buf_align(&crypto_io->crypto_bdev->crypto_bdev);
146 : 4399538 : crypto_io->aux_buf_iov.iov_len = total_length;
147 : 4399538 : crypto_io->aux_buf_iov.iov_base = (void *)(((uintptr_t)aux_buf + (alignment - 1)) & ~
148 : : (alignment - 1));
149 : 4399538 : crypto_io->aux_offset_blocks = bdev_io->u.bdev.offset_blocks;
150 : 4399538 : crypto_io->aux_num_blocks = bdev_io->u.bdev.num_blocks;
151 : :
152 : 8799076 : rc = spdk_accel_append_encrypt(&crypto_io->seq, crypto_ch->accel_channel,
153 : : crypto_ch->crypto_key, &crypto_io->aux_buf_iov, 1,
154 : : crypto_io->aux_domain, crypto_io->aux_domain_ctx,
155 : 4399538 : bdev_io->u.bdev.iovs, bdev_io->u.bdev.iovcnt,
156 : : bdev_io->u.bdev.memory_domain,
157 : : bdev_io->u.bdev.memory_domain_ctx,
158 : : bdev_io->u.bdev.offset_blocks, blocklen,
159 : : NULL, NULL);
160 [ + + ]: 4399538 : if (spdk_unlikely(rc != 0)) {
161 : 43269 : spdk_accel_put_buf(crypto_ch->accel_channel, crypto_io->aux_buf_raw,
162 : : crypto_io->aux_domain, crypto_io->aux_domain_ctx);
163 [ + + ]: 43269 : if (rc == -ENOMEM) {
164 [ - + - + ]: 43267 : SPDK_DEBUGLOG(vbdev_crypto, "No memory, queue the IO.\n");
165 : 43267 : spdk_bdev_io_complete(bdev_io, SPDK_BDEV_IO_STATUS_NOMEM);
166 : : } else {
167 : 2 : SPDK_ERRLOG("Failed to submit bdev_io!\n");
168 : 2 : crypto_io_fail(crypto_io);
169 : : }
170 : :
171 : 43269 : return;
172 : : }
173 : :
174 : 4356269 : crypto_write(crypto_ch, bdev_io);
175 : : }
176 : :
177 : : static void
178 : 8105612 : _complete_internal_io(struct spdk_bdev_io *bdev_io, bool success, void *cb_arg)
179 : : {
180 : 8105612 : struct spdk_bdev_io *orig_io = cb_arg;
181 : 8105612 : struct crypto_bdev_io *crypto_io = (struct crypto_bdev_io *)orig_io->driver_ctx;
182 : 8105612 : struct crypto_io_channel *crypto_ch = crypto_io->crypto_ch;
183 : :
184 [ + + ]: 8105612 : if (crypto_io->aux_buf_raw) {
185 : 4356265 : spdk_accel_put_buf(crypto_ch->accel_channel, crypto_io->aux_buf_raw,
186 : : crypto_io->aux_domain, crypto_io->aux_domain_ctx);
187 : : }
188 : :
189 : 8105612 : spdk_bdev_io_complete_base_io_status(orig_io, bdev_io);
190 : 8105612 : spdk_bdev_free_io(bdev_io);
191 : 8105612 : }
192 : :
193 : : static void crypto_read(struct crypto_io_channel *crypto_ch, struct spdk_bdev_io *bdev_io);
194 : :
195 : : static void
196 : 0 : vbdev_crypto_resubmit_io(void *arg)
197 : : {
198 : 0 : struct spdk_bdev_io *bdev_io = (struct spdk_bdev_io *)arg;
199 : 0 : struct crypto_bdev_io *crypto_io = (struct crypto_bdev_io *)bdev_io->driver_ctx;
200 : :
201 [ # # # ]: 0 : switch (crypto_io->resubmit_state) {
202 : 0 : case CRYPTO_IO_ENCRYPT_DONE:
203 : 0 : crypto_write(crypto_io->crypto_ch, bdev_io);
204 : 0 : break;
205 : 0 : case CRYPTO_IO_DECRYPT_DONE:
206 : 0 : crypto_read(crypto_io->crypto_ch, bdev_io);
207 : 0 : break;
208 : 0 : default:
209 : 0 : SPDK_UNREACHABLE();
210 : : }
211 : 0 : }
212 : :
213 : : static void
214 : 4 : vbdev_crypto_queue_io(struct spdk_bdev_io *bdev_io, enum crypto_io_resubmit_state state)
215 : : {
216 : 4 : struct crypto_bdev_io *crypto_io = (struct crypto_bdev_io *)bdev_io->driver_ctx;
217 : : int rc;
218 : :
219 : 4 : crypto_io->bdev_io_wait.bdev = bdev_io->bdev;
220 : 4 : crypto_io->bdev_io_wait.cb_fn = vbdev_crypto_resubmit_io;
221 : 4 : crypto_io->bdev_io_wait.cb_arg = bdev_io;
222 : 4 : crypto_io->resubmit_state = state;
223 : :
224 : 4 : rc = spdk_bdev_queue_io_wait(bdev_io->bdev, crypto_io->crypto_ch->base_ch,
225 : : &crypto_io->bdev_io_wait);
226 [ - + ]: 4 : if (rc != 0) {
227 : 0 : SPDK_ERRLOG("Queue io failed in vbdev_crypto_queue_io, rc=%d.\n", rc);
228 : 0 : crypto_io_fail(crypto_io);
229 : : }
230 : 4 : }
231 : :
232 : : static void
233 : 1957182 : crypto_read(struct crypto_io_channel *crypto_ch, struct spdk_bdev_io *bdev_io)
234 : : {
235 : 1957182 : struct crypto_bdev_io *crypto_io = (struct crypto_bdev_io *)bdev_io->driver_ctx;
236 : 1957182 : struct vbdev_crypto *crypto_bdev = SPDK_CONTAINEROF(bdev_io->bdev, struct vbdev_crypto,
237 : : crypto_bdev);
238 : 1957182 : struct spdk_bdev_ext_io_opts opts = {};
239 : : int rc;
240 : :
241 : 1957182 : opts.size = sizeof(opts);
242 : 1957182 : opts.accel_sequence = crypto_io->seq;
243 : 1957182 : opts.memory_domain = bdev_io->u.bdev.memory_domain;
244 : 1957182 : opts.memory_domain_ctx = bdev_io->u.bdev.memory_domain_ctx;
245 : :
246 : 1957182 : rc = spdk_bdev_readv_blocks_ext(crypto_bdev->base_desc, crypto_ch->base_ch,
247 : : bdev_io->u.bdev.iovs, bdev_io->u.bdev.iovcnt,
248 : : bdev_io->u.bdev.offset_blocks, bdev_io->u.bdev.num_blocks,
249 : : _complete_internal_io, bdev_io, &opts);
250 [ + + ]: 1957182 : if (rc != 0) {
251 [ + + ]: 4 : if (rc == -ENOMEM) {
252 [ - + - + ]: 2 : SPDK_DEBUGLOG(vbdev_crypto, "No memory, queue the IO.\n");
253 : 2 : vbdev_crypto_queue_io(bdev_io, CRYPTO_IO_DECRYPT_DONE);
254 : : } else {
255 : 2 : SPDK_ERRLOG("Failed to submit bdev_io!\n");
256 : 2 : crypto_io_fail(crypto_io);
257 : : }
258 : : }
259 : 1957182 : }
260 : :
261 : : /* Callback for getting a buf from the bdev pool in the event that the caller passed
262 : : * in NULL, we need to own the buffer so it doesn't get freed by another vbdev module
263 : : * beneath us before we're done with it.
264 : : */
265 : : static void
266 : 2012383 : crypto_read_get_buf_cb(struct spdk_io_channel *ch, struct spdk_bdev_io *bdev_io,
267 : : bool success)
268 : : {
269 : 2012383 : struct crypto_io_channel *crypto_ch = spdk_io_channel_get_ctx(ch);
270 : 2012383 : struct crypto_bdev_io *crypto_io = (struct crypto_bdev_io *)bdev_io->driver_ctx;
271 : 2012383 : uint32_t blocklen = crypto_io->crypto_bdev->crypto_bdev.blocklen;
272 : : int rc;
273 : :
274 [ - + ]: 2012383 : if (!success) {
275 : 0 : crypto_io_fail(crypto_io);
276 : 0 : return;
277 : : }
278 : :
279 : 6037149 : rc = spdk_accel_append_decrypt(&crypto_io->seq, crypto_ch->accel_channel,
280 : : crypto_ch->crypto_key,
281 : 2012383 : bdev_io->u.bdev.iovs, bdev_io->u.bdev.iovcnt,
282 : : bdev_io->u.bdev.memory_domain,
283 : : bdev_io->u.bdev.memory_domain_ctx,
284 : 2012383 : bdev_io->u.bdev.iovs, bdev_io->u.bdev.iovcnt,
285 : : bdev_io->u.bdev.memory_domain,
286 : : bdev_io->u.bdev.memory_domain_ctx,
287 : : bdev_io->u.bdev.offset_blocks, blocklen,
288 : : NULL, NULL);
289 [ + + ]: 2012383 : if (rc != 0) {
290 [ + - ]: 55201 : if (rc == -ENOMEM) {
291 [ - + - + ]: 55201 : SPDK_DEBUGLOG(vbdev_crypto, "No memory, queue the IO.\n");
292 : 55201 : spdk_bdev_io_complete(bdev_io, SPDK_BDEV_IO_STATUS_NOMEM);
293 : : } else {
294 : 0 : SPDK_ERRLOG("Failed to submit bdev_io!\n");
295 : 0 : crypto_io_fail(crypto_io);
296 : : }
297 : :
298 : 55201 : return;
299 : : }
300 : :
301 : 1957182 : crypto_read(crypto_ch, bdev_io);
302 : : }
303 : :
304 : : /* Called when someone submits IO to this crypto vbdev. For IO's not relevant to crypto,
305 : : * we're simply passing it on here via SPDK IO calls which in turn allocate another bdev IO
306 : : * and call our cpl callback provided below along with the original bdev_io so that we can
307 : : * complete it once this IO completes. For crypto operations, we'll either encrypt it first
308 : : * (writes) then call back into bdev to submit it or we'll submit a read and then catch it
309 : : * on the way back for decryption.
310 : : */
311 : : static void
312 : 8204092 : vbdev_crypto_submit_request(struct spdk_io_channel *ch, struct spdk_bdev_io *bdev_io)
313 : : {
314 : 8204092 : struct vbdev_crypto *crypto_bdev = SPDK_CONTAINEROF(bdev_io->bdev, struct vbdev_crypto,
315 : : crypto_bdev);
316 : 8204092 : struct crypto_io_channel *crypto_ch = spdk_io_channel_get_ctx(ch);
317 : 8204092 : struct crypto_bdev_io *crypto_io = (struct crypto_bdev_io *)bdev_io->driver_ctx;
318 : 8204092 : int rc = 0;
319 : :
320 [ - + ]: 8204092 : memset(crypto_io, 0, sizeof(struct crypto_bdev_io));
321 : 8204092 : crypto_io->crypto_bdev = crypto_bdev;
322 : 8204092 : crypto_io->crypto_ch = crypto_ch;
323 : 8204092 : crypto_io->seq = bdev_io->u.bdev.accel_sequence;
324 : :
325 [ + + + + : 8204092 : switch (bdev_io->type) {
+ + ]
326 : 2012383 : case SPDK_BDEV_IO_TYPE_READ:
327 : 2012383 : spdk_bdev_io_get_buf(bdev_io, crypto_read_get_buf_cb,
328 : 2012383 : bdev_io->u.bdev.num_blocks * bdev_io->bdev->blocklen);
329 : 2012383 : break;
330 : 4399538 : case SPDK_BDEV_IO_TYPE_WRITE:
331 : : /* For encryption we don't want to encrypt the data in place as the host isn't
332 : : * expecting us to mangle its data buffers so we need to encrypt into the aux accel
333 : : * buffer, then we can use that as the source for the disk data transfer.
334 : : */
335 : 8799076 : rc = spdk_accel_get_buf(crypto_ch->accel_channel,
336 : 4399538 : bdev_io->u.bdev.num_blocks * bdev_io->bdev->blocklen,
337 : : &crypto_io->aux_buf_raw, &crypto_io->aux_domain,
338 : : &crypto_io->aux_domain_ctx);
339 [ + - ]: 4399538 : if (rc == 0) {
340 : 4399538 : crypto_encrypt(crypto_ch, bdev_io);
341 : : }
342 : 4399538 : break;
343 : 1792154 : case SPDK_BDEV_IO_TYPE_UNMAP:
344 : 1792154 : rc = spdk_bdev_unmap_blocks(crypto_bdev->base_desc, crypto_ch->base_ch,
345 : : bdev_io->u.bdev.offset_blocks,
346 : : bdev_io->u.bdev.num_blocks,
347 : : _complete_internal_io, bdev_io);
348 : 1792154 : break;
349 : 4 : case SPDK_BDEV_IO_TYPE_FLUSH:
350 : 4 : rc = spdk_bdev_flush_blocks(crypto_bdev->base_desc, crypto_ch->base_ch,
351 : : bdev_io->u.bdev.offset_blocks,
352 : : bdev_io->u.bdev.num_blocks,
353 : : _complete_internal_io, bdev_io);
354 : 4 : break;
355 : 11 : case SPDK_BDEV_IO_TYPE_RESET:
356 : 11 : rc = spdk_bdev_reset(crypto_bdev->base_desc, crypto_ch->base_ch,
357 : : _complete_internal_io, bdev_io);
358 : 11 : break;
359 : 2 : case SPDK_BDEV_IO_TYPE_WRITE_ZEROES:
360 : : default:
361 : 2 : SPDK_ERRLOG("crypto: unknown I/O type %d\n", bdev_io->type);
362 : 2 : rc = -EINVAL;
363 : 2 : break;
364 : : }
365 : :
366 [ + + ]: 8204092 : if (rc != 0) {
367 [ - + ]: 6 : if (rc == -ENOMEM) {
368 [ # # # # ]: 0 : SPDK_DEBUGLOG(vbdev_crypto, "No memory, queue the IO.\n");
369 : 0 : spdk_bdev_io_complete(bdev_io, SPDK_BDEV_IO_STATUS_NOMEM);
370 : : } else {
371 : 6 : SPDK_ERRLOG("Failed to submit bdev_io!\n");
372 : 6 : crypto_io_fail(crypto_io);
373 : : }
374 : : }
375 : 8204092 : }
376 : :
377 : : /* We'll just call the base bdev and let it answer except for WZ command which
378 : : * we always say we don't support so that the bdev layer will actually send us
379 : : * real writes that we can encrypt.
380 : : */
381 : : static bool
382 : 572040 : vbdev_crypto_io_type_supported(void *ctx, enum spdk_bdev_io_type io_type)
383 : : {
384 : 572040 : struct vbdev_crypto *crypto_bdev = (struct vbdev_crypto *)ctx;
385 : :
386 [ + + ]: 572040 : switch (io_type) {
387 : 205295 : case SPDK_BDEV_IO_TYPE_WRITE:
388 : : case SPDK_BDEV_IO_TYPE_UNMAP:
389 : : case SPDK_BDEV_IO_TYPE_RESET:
390 : : case SPDK_BDEV_IO_TYPE_READ:
391 : : case SPDK_BDEV_IO_TYPE_FLUSH:
392 : 205295 : return spdk_bdev_io_type_supported(crypto_bdev->base_bdev, io_type);
393 : 366745 : case SPDK_BDEV_IO_TYPE_WRITE_ZEROES:
394 : : /* Force the bdev layer to issue actual writes of zeroes so we can
395 : : * encrypt them as regular writes.
396 : : */
397 : : default:
398 : 366745 : return false;
399 : : }
400 : : }
401 : :
402 : : /* Callback for unregistering the IO device. */
403 : : static void
404 : 114 : _device_unregister_cb(void *io_device)
405 : : {
406 : 114 : struct vbdev_crypto *crypto_bdev = io_device;
407 : :
408 : : /* Done with this crypto_bdev. */
409 : 114 : crypto_bdev->opts = NULL;
410 : :
411 : 114 : spdk_bdev_destruct_done(&crypto_bdev->crypto_bdev, 0);
412 : 114 : free(crypto_bdev->crypto_bdev.name);
413 : 114 : free(crypto_bdev);
414 : 114 : }
415 : :
416 : : /* Wrapper for the bdev close operation. */
417 : : static void
418 : 0 : _vbdev_crypto_destruct(void *ctx)
419 : : {
420 : 0 : struct spdk_bdev_desc *desc = ctx;
421 : :
422 : 0 : spdk_bdev_close(desc);
423 : 0 : }
424 : :
425 : : /* Called after we've unregistered following a hot remove callback.
426 : : * Our finish entry point will be called next.
427 : : */
428 : : static int
429 : 114 : vbdev_crypto_destruct(void *ctx)
430 : : {
431 : 114 : struct vbdev_crypto *crypto_bdev = (struct vbdev_crypto *)ctx;
432 : :
433 : : /* Remove this device from the internal list */
434 [ - + ]: 114 : TAILQ_REMOVE(&g_vbdev_crypto, crypto_bdev, link);
435 : :
436 : : /* Unclaim the underlying bdev. */
437 : 114 : spdk_bdev_module_release_bdev(crypto_bdev->base_bdev);
438 : :
439 : : /* Close the underlying bdev on its same opened thread. */
440 [ + - - + ]: 114 : if (crypto_bdev->thread && crypto_bdev->thread != spdk_get_thread()) {
441 : 0 : spdk_thread_send_msg(crypto_bdev->thread, _vbdev_crypto_destruct, crypto_bdev->base_desc);
442 : : } else {
443 : 114 : spdk_bdev_close(crypto_bdev->base_desc);
444 : : }
445 : :
446 : : /* Unregister the io_device. */
447 : 114 : spdk_io_device_unregister(crypto_bdev, _device_unregister_cb);
448 : :
449 : 114 : return 1;
450 : : }
451 : :
452 : : /* We supplied this as an entry point for upper layers who want to communicate to this
453 : : * bdev. This is how they get a channel. We are passed the same context we provided when
454 : : * we created our crypto vbdev in examine() which, for this bdev, is the address of one of
455 : : * our context nodes. From here we'll ask the SPDK channel code to fill out our channel
456 : : * struct and we'll keep it in our crypto node.
457 : : */
458 : : static struct spdk_io_channel *
459 : 242 : vbdev_crypto_get_io_channel(void *ctx)
460 : : {
461 : 242 : struct vbdev_crypto *crypto_bdev = (struct vbdev_crypto *)ctx;
462 : :
463 : : /* The IO channel code will allocate a channel for us which consists of
464 : : * the SPDK channel structure plus the size of our crypto_io_channel struct
465 : : * that we passed in when we registered our IO device. It will then call
466 : : * our channel create callback to populate any elements that we need to
467 : : * update.
468 : : */
469 : 242 : return spdk_get_io_channel(crypto_bdev);
470 : : }
471 : :
472 : : /* This is the output for bdev_get_bdevs() for this vbdev */
473 : : static int
474 : 50 : vbdev_crypto_dump_info_json(void *ctx, struct spdk_json_write_ctx *w)
475 : : {
476 : 50 : struct vbdev_crypto *crypto_bdev = (struct vbdev_crypto *)ctx;
477 : :
478 : 50 : spdk_json_write_name(w, "crypto");
479 : 50 : spdk_json_write_object_begin(w);
480 : 50 : spdk_json_write_named_string(w, "base_bdev_name", spdk_bdev_get_name(crypto_bdev->base_bdev));
481 : 50 : spdk_json_write_named_string(w, "name", spdk_bdev_get_name(&crypto_bdev->crypto_bdev));
482 : 50 : spdk_json_write_named_string(w, "key_name", crypto_bdev->opts->key->param.key_name);
483 : 50 : spdk_json_write_object_end(w);
484 : :
485 : 50 : return 0;
486 : : }
487 : :
488 : : static int
489 : 12 : vbdev_crypto_config_json(struct spdk_json_write_ctx *w)
490 : : {
491 : : struct vbdev_crypto *crypto_bdev;
492 : :
493 [ + + ]: 27 : TAILQ_FOREACH(crypto_bdev, &g_vbdev_crypto, link) {
494 : 15 : spdk_json_write_object_begin(w);
495 : 15 : spdk_json_write_named_string(w, "method", "bdev_crypto_create");
496 : 15 : spdk_json_write_named_object_begin(w, "params");
497 : 15 : spdk_json_write_named_string(w, "base_bdev_name", spdk_bdev_get_name(crypto_bdev->base_bdev));
498 : 15 : spdk_json_write_named_string(w, "name", spdk_bdev_get_name(&crypto_bdev->crypto_bdev));
499 : 15 : spdk_json_write_named_string(w, "key_name", crypto_bdev->opts->key->param.key_name);
500 : 15 : spdk_json_write_object_end(w);
501 : 15 : spdk_json_write_object_end(w);
502 : : }
503 : 12 : return 0;
504 : : }
505 : :
506 : : /* We provide this callback for the SPDK channel code to create a channel using
507 : : * the channel struct we provided in our module get_io_channel() entry point. Here
508 : : * we get and save off an underlying base channel of the device below us so that
509 : : * we can communicate with the base bdev on a per channel basis. We also register the
510 : : * poller used to complete crypto operations from the device.
511 : : */
512 : : static int
513 : 242 : crypto_bdev_ch_create_cb(void *io_device, void *ctx_buf)
514 : : {
515 : 242 : struct crypto_io_channel *crypto_ch = ctx_buf;
516 : 242 : struct vbdev_crypto *crypto_bdev = io_device;
517 : :
518 : 242 : crypto_ch->base_ch = spdk_bdev_get_io_channel(crypto_bdev->base_desc);
519 [ - + ]: 242 : if (crypto_ch->base_ch == NULL) {
520 : 0 : SPDK_ERRLOG("Failed to get base bdev IO channel (bdev: %s)\n",
521 : : crypto_bdev->crypto_bdev.name);
522 : 0 : return -ENOMEM;
523 : : }
524 : :
525 : 242 : crypto_ch->accel_channel = spdk_accel_get_io_channel();
526 [ - + ]: 242 : if (crypto_ch->accel_channel == NULL) {
527 : 0 : SPDK_ERRLOG("Failed to get accel IO channel (bdev: %s)\n",
528 : : crypto_bdev->crypto_bdev.name);
529 : 0 : spdk_put_io_channel(crypto_ch->base_ch);
530 : 0 : return -ENOMEM;
531 : : }
532 : :
533 : 242 : crypto_ch->crypto_key = crypto_bdev->opts->key;
534 : :
535 : 242 : return 0;
536 : : }
537 : :
538 : : /* We provide this callback for the SPDK channel code to destroy a channel
539 : : * created with our create callback. We just need to undo anything we did
540 : : * when we created.
541 : : */
542 : : static void
543 : 242 : crypto_bdev_ch_destroy_cb(void *io_device, void *ctx_buf)
544 : : {
545 : 242 : struct crypto_io_channel *crypto_ch = ctx_buf;
546 : :
547 : 242 : spdk_put_io_channel(crypto_ch->base_ch);
548 : 242 : spdk_put_io_channel(crypto_ch->accel_channel);
549 : 242 : }
550 : :
551 : : /* Create the association from the bdev and vbdev name and insert
552 : : * on the global list. */
553 : : static int
554 : 114 : vbdev_crypto_insert_name(struct vbdev_crypto_opts *opts, struct bdev_names **out)
555 : : {
556 : : struct bdev_names *name;
557 : :
558 [ - + ]: 114 : assert(opts);
559 [ - + ]: 114 : assert(out);
560 : :
561 [ + + ]: 252 : TAILQ_FOREACH(name, &g_bdev_names, link) {
562 [ - + - + : 138 : if (strcmp(opts->vbdev_name, name->opts->vbdev_name) == 0) {
- + ]
563 : 0 : SPDK_ERRLOG("Crypto bdev %s already exists\n", opts->vbdev_name);
564 : 0 : return -EEXIST;
565 : : }
566 : : }
567 : :
568 : 114 : name = calloc(1, sizeof(struct bdev_names));
569 [ - + ]: 114 : if (!name) {
570 : 0 : SPDK_ERRLOG("Failed to allocate memory for bdev_names.\n");
571 : 0 : return -ENOMEM;
572 : : }
573 : :
574 : 114 : name->opts = opts;
575 : 114 : TAILQ_INSERT_TAIL(&g_bdev_names, name, link);
576 : 114 : *out = name;
577 : :
578 : 114 : return 0;
579 : : }
580 : :
581 : : void
582 : 114 : free_crypto_opts(struct vbdev_crypto_opts *opts)
583 : : {
584 : 114 : free(opts->bdev_name);
585 : 114 : free(opts->vbdev_name);
586 : 114 : free(opts);
587 : 114 : }
588 : :
589 : : static void
590 : 114 : vbdev_crypto_delete_name(struct bdev_names *name)
591 : : {
592 [ + + ]: 114 : TAILQ_REMOVE(&g_bdev_names, name, link);
593 [ + - ]: 114 : if (name->opts) {
594 [ - + + + : 114 : if (name->opts->key_owner && name->opts->key) {
+ - ]
595 : 5 : spdk_accel_crypto_key_destroy(name->opts->key);
596 : : }
597 : 114 : free_crypto_opts(name->opts);
598 : 114 : name->opts = NULL;
599 : : }
600 : 114 : free(name);
601 : 114 : }
602 : :
603 : : /* RPC entry point for crypto creation. */
604 : : int
605 : 114 : create_crypto_disk(struct vbdev_crypto_opts *opts)
606 : : {
607 : 114 : struct bdev_names *name = NULL;
608 : : int rc;
609 : :
610 : 114 : rc = vbdev_crypto_insert_name(opts, &name);
611 [ - + ]: 114 : if (rc) {
612 : 0 : return rc;
613 : : }
614 : :
615 : 114 : rc = vbdev_crypto_claim(opts->bdev_name);
616 [ + + ]: 114 : if (rc == -ENODEV) {
617 : 89 : SPDK_NOTICELOG("vbdev creation deferred pending base bdev arrival\n");
618 : 89 : rc = 0;
619 : : }
620 : :
621 [ - + ]: 114 : if (rc) {
622 [ # # ]: 0 : assert(name != NULL);
623 : : /* In case of error we let the caller function to deallocate @opts
624 : : * since it is its responsibility. Setting name->opts = NULL let's
625 : : * vbdev_crypto_delete_name() know it does not have to do anything
626 : : * about @opts.
627 : : */
628 : 0 : name->opts = NULL;
629 : 0 : vbdev_crypto_delete_name(name);
630 : : }
631 : 114 : return rc;
632 : : }
633 : :
634 : : /* Called at driver init time, parses config file to prepare for examine calls,
635 : : * also fully initializes the crypto drivers.
636 : : */
637 : : static int
638 : 193 : vbdev_crypto_init(void)
639 : : {
640 : 193 : return 0;
641 : : }
642 : :
643 : : /* Called when the entire module is being torn down. */
644 : : static void
645 : 193 : vbdev_crypto_finish(void)
646 : : {
647 : : struct bdev_names *name;
648 : :
649 [ + + ]: 301 : while ((name = TAILQ_FIRST(&g_bdev_names))) {
650 : 108 : vbdev_crypto_delete_name(name);
651 : : }
652 : 193 : }
653 : :
654 : : /* During init we'll be asked how much memory we'd like passed to us
655 : : * in bev_io structures as context. Here's where we specify how
656 : : * much context we want per IO.
657 : : */
658 : : static int
659 : 193 : vbdev_crypto_get_ctx_size(void)
660 : : {
661 : 193 : return sizeof(struct crypto_bdev_io);
662 : : }
663 : :
664 : : static void
665 : 0 : vbdev_crypto_base_bdev_hotremove_cb(struct spdk_bdev *bdev_find)
666 : : {
667 : : struct vbdev_crypto *crypto_bdev, *tmp;
668 : :
669 [ # # ]: 0 : TAILQ_FOREACH_SAFE(crypto_bdev, &g_vbdev_crypto, link, tmp) {
670 [ # # ]: 0 : if (bdev_find == crypto_bdev->base_bdev) {
671 : 0 : spdk_bdev_unregister(&crypto_bdev->crypto_bdev, NULL, NULL);
672 : : }
673 : : }
674 : 0 : }
675 : :
676 : : /* Called when the underlying base bdev triggers asynchronous event such as bdev removal. */
677 : : static void
678 : 0 : vbdev_crypto_base_bdev_event_cb(enum spdk_bdev_event_type type, struct spdk_bdev *bdev,
679 : : void *event_ctx)
680 : : {
681 [ # # ]: 0 : switch (type) {
682 : 0 : case SPDK_BDEV_EVENT_REMOVE:
683 : 0 : vbdev_crypto_base_bdev_hotremove_cb(bdev);
684 : 0 : break;
685 : 0 : default:
686 : 0 : SPDK_NOTICELOG("Unsupported bdev event: type %d\n", type);
687 : 0 : break;
688 : : }
689 : 0 : }
690 : :
691 : : static int
692 : 974 : vbdev_crypto_get_memory_domains(void *ctx, struct spdk_memory_domain **domains, int array_size)
693 : : {
694 : 974 : struct vbdev_crypto *crypto_bdev = ctx;
695 : : int num_domains;
696 : :
697 : : /* Report base bdev's memory domains plus accel memory domain */
698 : 974 : num_domains = spdk_bdev_get_memory_domains(crypto_bdev->base_bdev, domains, array_size);
699 [ + + + - ]: 974 : if (domains != NULL && num_domains < array_size) {
700 : 51 : domains[num_domains] = spdk_accel_get_memory_domain();
701 : : }
702 : :
703 : 974 : return num_domains + 1;
704 : : }
705 : :
706 : : static bool
707 : 16527 : vbdev_crypto_sequence_supported(void *ctx, enum spdk_bdev_io_type type)
708 : : {
709 [ + + ]: 16527 : switch (type) {
710 : 1574 : case SPDK_BDEV_IO_TYPE_READ:
711 : : case SPDK_BDEV_IO_TYPE_WRITE:
712 : 1574 : return true;
713 : 14953 : default:
714 : 14953 : return false;
715 : : }
716 : : }
717 : :
718 : : /* When we register our bdev this is how we specify our entry points. */
719 : : static const struct spdk_bdev_fn_table vbdev_crypto_fn_table = {
720 : : .destruct = vbdev_crypto_destruct,
721 : : .submit_request = vbdev_crypto_submit_request,
722 : : .io_type_supported = vbdev_crypto_io_type_supported,
723 : : .get_io_channel = vbdev_crypto_get_io_channel,
724 : : .dump_info_json = vbdev_crypto_dump_info_json,
725 : : .get_memory_domains = vbdev_crypto_get_memory_domains,
726 : : .accel_sequence_supported = vbdev_crypto_sequence_supported,
727 : : };
728 : :
729 : : static struct spdk_bdev_module crypto_if = {
730 : : .name = "crypto",
731 : : .module_init = vbdev_crypto_init,
732 : : .get_ctx_size = vbdev_crypto_get_ctx_size,
733 : : .examine_config = vbdev_crypto_examine,
734 : : .module_fini = vbdev_crypto_finish,
735 : : .config_json = vbdev_crypto_config_json
736 : : };
737 : :
738 : 209 : SPDK_BDEV_MODULE_REGISTER(crypto, &crypto_if)
739 : :
740 : : static int
741 : 1332 : vbdev_crypto_claim(const char *bdev_name)
742 : : {
743 : : struct bdev_names *name;
744 : : struct vbdev_crypto *vbdev;
745 : : struct spdk_bdev *bdev;
746 : 60 : struct spdk_iobuf_opts iobuf_opts;
747 : 1332 : struct spdk_accel_operation_exec_ctx opctx = {};
748 : 60 : struct spdk_uuid ns_uuid;
749 : 1332 : int rc = 0;
750 : :
751 : 1332 : spdk_uuid_parse(&ns_uuid, BDEV_CRYPTO_NAMESPACE_UUID);
752 : :
753 : : /* Limit the max IO size by some reasonable value. Since in write operation we use aux buffer,
754 : : * let's set the limit to the large_bufsize value */
755 : 1332 : spdk_iobuf_get_opts(&iobuf_opts, sizeof(iobuf_opts));
756 : :
757 : : /* Check our list of names from config versus this bdev and if
758 : : * there's a match, create the crypto_bdev & bdev accordingly.
759 : : */
760 [ + + ]: 1976 : TAILQ_FOREACH(name, &g_bdev_names, link) {
761 [ - + - + : 847 : if (strcmp(name->opts->bdev_name, bdev_name) != 0) {
+ + ]
762 : 644 : continue;
763 : : }
764 [ - + - + ]: 203 : SPDK_DEBUGLOG(vbdev_crypto, "Match on %s\n", bdev_name);
765 : :
766 : 203 : vbdev = calloc(1, sizeof(struct vbdev_crypto));
767 [ - + ]: 203 : if (!vbdev) {
768 : 0 : SPDK_ERRLOG("Failed to allocate memory for crypto_bdev.\n");
769 : 0 : return -ENOMEM;
770 : : }
771 : 203 : vbdev->crypto_bdev.product_name = "crypto";
772 : :
773 [ - + ]: 203 : vbdev->crypto_bdev.name = strdup(name->opts->vbdev_name);
774 [ - + ]: 203 : if (!vbdev->crypto_bdev.name) {
775 : 0 : SPDK_ERRLOG("Failed to allocate memory for crypto_bdev name.\n");
776 : 0 : rc = -ENOMEM;
777 : 0 : goto error_bdev_name;
778 : : }
779 : :
780 : 203 : rc = spdk_bdev_open_ext(bdev_name, true, vbdev_crypto_base_bdev_event_cb,
781 : : NULL, &vbdev->base_desc);
782 [ + + ]: 203 : if (rc) {
783 [ - + ]: 89 : if (rc != -ENODEV) {
784 : 0 : SPDK_ERRLOG("Failed to open bdev %s: error %d\n", bdev_name, rc);
785 : : }
786 : 89 : goto error_open;
787 : : }
788 : :
789 : 114 : bdev = spdk_bdev_desc_get_bdev(vbdev->base_desc);
790 : 114 : vbdev->base_bdev = bdev;
791 : :
792 : 114 : vbdev->crypto_bdev.write_cache = bdev->write_cache;
793 : 114 : vbdev->crypto_bdev.optimal_io_boundary = bdev->optimal_io_boundary;
794 [ - + + + : 114 : vbdev->crypto_bdev.max_rw_size = spdk_min(
- + - - -
+ ]
795 : : bdev->max_rw_size ? bdev->max_rw_size : UINT32_MAX,
796 : : iobuf_opts.large_bufsize / bdev->blocklen);
797 : :
798 : 114 : opctx.size = SPDK_SIZEOF(&opctx, block_size);
799 : 114 : opctx.block_size = bdev->blocklen;
800 [ - + - + ]: 342 : vbdev->crypto_bdev.required_alignment =
801 [ - + ]: 342 : spdk_max(bdev->required_alignment,
802 : : spdk_max(spdk_accel_get_buf_align(SPDK_ACCEL_OPC_ENCRYPT, &opctx),
803 : : spdk_accel_get_buf_align(SPDK_ACCEL_OPC_DECRYPT, &opctx)));
804 : :
805 : 114 : vbdev->crypto_bdev.blocklen = bdev->blocklen;
806 : 114 : vbdev->crypto_bdev.blockcnt = bdev->blockcnt;
807 : :
808 : : /* This is the context that is passed to us when the bdev
809 : : * layer calls in so we'll save our crypto_bdev node here.
810 : : */
811 : 114 : vbdev->crypto_bdev.ctxt = vbdev;
812 : 114 : vbdev->crypto_bdev.fn_table = &vbdev_crypto_fn_table;
813 : 114 : vbdev->crypto_bdev.module = &crypto_if;
814 : :
815 : : /* Assign crypto opts from the name. The pointer is valid up to the point
816 : : * the module is unloaded and all names removed from the list. */
817 : 114 : vbdev->opts = name->opts;
818 : :
819 : : /* Generate UUID based on namespace UUID + base bdev UUID */
820 : 114 : rc = spdk_uuid_generate_sha1(&vbdev->crypto_bdev.uuid, &ns_uuid,
821 : 114 : (const char *)&vbdev->base_bdev->uuid, sizeof(struct spdk_uuid));
822 [ - + ]: 114 : if (rc) {
823 : 0 : SPDK_ERRLOG("Unable to generate new UUID for crypto bdev\n");
824 : 0 : goto error_uuid;
825 : : }
826 : :
827 : 114 : TAILQ_INSERT_TAIL(&g_vbdev_crypto, vbdev, link);
828 : :
829 : 114 : spdk_io_device_register(vbdev, crypto_bdev_ch_create_cb, crypto_bdev_ch_destroy_cb,
830 : 114 : sizeof(struct crypto_io_channel), vbdev->crypto_bdev.name);
831 : :
832 : : /* Save the thread where the base device is opened */
833 : 114 : vbdev->thread = spdk_get_thread();
834 : :
835 : 114 : rc = spdk_bdev_module_claim_bdev(bdev, vbdev->base_desc, vbdev->crypto_bdev.module);
836 [ - + ]: 114 : if (rc) {
837 : 0 : SPDK_ERRLOG("Failed to claim bdev %s\n", spdk_bdev_get_name(bdev));
838 : 0 : goto error_claim;
839 : : }
840 : :
841 : 114 : rc = spdk_bdev_register(&vbdev->crypto_bdev);
842 [ - + ]: 114 : if (rc < 0) {
843 : 0 : SPDK_ERRLOG("Failed to register vbdev: error %d\n", rc);
844 : 0 : rc = -EINVAL;
845 : 0 : goto error_bdev_register;
846 : : }
847 [ - + - + ]: 114 : SPDK_DEBUGLOG(vbdev_crypto, "Registered io_device and virtual bdev for: %s\n",
848 : : vbdev->opts->vbdev_name);
849 : 114 : break;
850 : : }
851 : :
852 : 1243 : return rc;
853 : :
854 : : /* Error cleanup paths. */
855 : 0 : error_bdev_register:
856 : 0 : spdk_bdev_module_release_bdev(vbdev->base_bdev);
857 : 0 : error_claim:
858 [ # # ]: 0 : TAILQ_REMOVE(&g_vbdev_crypto, vbdev, link);
859 : 0 : spdk_io_device_unregister(vbdev, NULL);
860 : 0 : error_uuid:
861 : 0 : spdk_bdev_close(vbdev->base_desc);
862 : 89 : error_open:
863 : 89 : free(vbdev->crypto_bdev.name);
864 : 89 : error_bdev_name:
865 : 89 : free(vbdev);
866 : :
867 : 89 : return rc;
868 : : }
869 : :
870 : : struct crypto_delete_disk_ctx {
871 : : spdk_delete_crypto_complete cb_fn;
872 : : void *cb_arg;
873 : : char *bdev_name;
874 : : };
875 : :
876 : : static void
877 : 6 : delete_crypto_disk_bdev_name(void *ctx, int rc)
878 : : {
879 : : struct bdev_names *name;
880 : 6 : struct crypto_delete_disk_ctx *disk_ctx = ctx;
881 : :
882 : : /* Remove the association (vbdev, bdev) from g_bdev_names. This is required so that the
883 : : * vbdev does not get re-created if the same bdev is constructed at some other time,
884 : : * unless the underlying bdev was hot-removed. */
885 [ + - ]: 6 : TAILQ_FOREACH(name, &g_bdev_names, link) {
886 [ - + - + : 6 : if (strcmp(name->opts->vbdev_name, disk_ctx->bdev_name) == 0) {
+ - ]
887 : 6 : vbdev_crypto_delete_name(name);
888 : 6 : break;
889 : : }
890 : : }
891 : :
892 : 6 : disk_ctx->cb_fn(disk_ctx->cb_arg, rc);
893 : :
894 : 6 : free(disk_ctx->bdev_name);
895 : 6 : free(disk_ctx);
896 : 6 : }
897 : :
898 : : /* RPC entry for deleting a crypto vbdev. */
899 : : void
900 : 6 : delete_crypto_disk(const char *bdev_name, spdk_delete_crypto_complete cb_fn,
901 : : void *cb_arg)
902 : : {
903 : : int rc;
904 : : struct crypto_delete_disk_ctx *ctx;
905 : :
906 : 6 : ctx = calloc(1, sizeof(struct crypto_delete_disk_ctx));
907 [ - + ]: 6 : if (!ctx) {
908 : 0 : SPDK_ERRLOG("Failed to allocate delete crypto disk ctx\n");
909 : 0 : cb_fn(cb_arg, -ENOMEM);
910 : 0 : return;
911 : : }
912 : :
913 [ - + ]: 6 : ctx->bdev_name = strdup(bdev_name);
914 [ - + ]: 6 : if (!ctx->bdev_name) {
915 : 0 : SPDK_ERRLOG("Failed to copy bdev_name\n");
916 : 0 : free(ctx);
917 : 0 : cb_fn(cb_arg, -ENOMEM);
918 : 0 : return;
919 : : }
920 : 6 : ctx->cb_arg = cb_arg;
921 : 6 : ctx->cb_fn = cb_fn;
922 : : /* Some cleanup happens in the destruct callback. */
923 : 6 : rc = spdk_bdev_unregister_by_name(bdev_name, &crypto_if, delete_crypto_disk_bdev_name, ctx);
924 [ - + ]: 6 : if (rc != 0) {
925 : 0 : SPDK_ERRLOG("Encountered an error during bdev unregistration\n");
926 : 0 : cb_fn(cb_arg, rc);
927 : 0 : free(ctx->bdev_name);
928 : 0 : free(ctx);
929 : : }
930 : : }
931 : :
932 : : /* Because we specified this function in our crypto bdev function table when we
933 : : * registered our crypto bdev, we'll get this call anytime a new bdev shows up.
934 : : * Here we need to decide if we care about it and if so what to do. We
935 : : * parsed the config file at init so we check the new bdev against the list
936 : : * we built up at that time and if the user configured us to attach to this
937 : : * bdev, here's where we do it.
938 : : */
939 : : static void
940 : 1218 : vbdev_crypto_examine(struct spdk_bdev *bdev)
941 : : {
942 : 1218 : vbdev_crypto_claim(spdk_bdev_get_name(bdev));
943 : 1218 : spdk_bdev_module_examine_done(&crypto_if);
944 : 1218 : }
945 : :
946 : 209 : SPDK_LOG_REGISTER_COMPONENT(vbdev_crypto)
|