.. | .. |
---|
13 | 13 | #include <linux/blkdev.h> |
---|
14 | 14 | #include <linux/keyslot-manager.h> |
---|
15 | 15 | #include <linux/module.h> |
---|
| 16 | +#include <linux/ratelimit.h> |
---|
16 | 17 | #include <linux/slab.h> |
---|
17 | 18 | |
---|
18 | 19 | #include "blk-crypto-internal.h" |
---|
.. | .. |
---|
217 | 218 | return true; |
---|
218 | 219 | } |
---|
219 | 220 | |
---|
220 | | -blk_status_t __blk_crypto_init_request(struct request *rq) |
---|
| 221 | +blk_status_t __blk_crypto_rq_get_keyslot(struct request *rq) |
---|
221 | 222 | { |
---|
222 | 223 | return blk_ksm_get_slot_for_key(rq->q->ksm, rq->crypt_ctx->bc_key, |
---|
223 | 224 | &rq->crypt_keyslot); |
---|
224 | 225 | } |
---|
225 | 226 | |
---|
226 | | -/** |
---|
227 | | - * __blk_crypto_free_request - Uninitialize the crypto fields of a request. |
---|
228 | | - * |
---|
229 | | - * @rq: The request whose crypto fields to uninitialize. |
---|
230 | | - * |
---|
231 | | - * Completely uninitializes the crypto fields of a request. If a keyslot has |
---|
232 | | - * been programmed into some inline encryption hardware, that keyslot is |
---|
233 | | - * released. The rq->crypt_ctx is also freed. |
---|
234 | | - */ |
---|
235 | | -void __blk_crypto_free_request(struct request *rq) |
---|
| 227 | +void __blk_crypto_rq_put_keyslot(struct request *rq) |
---|
236 | 228 | { |
---|
237 | 229 | blk_ksm_put_slot(rq->crypt_keyslot); |
---|
| 230 | + rq->crypt_keyslot = NULL; |
---|
| 231 | +} |
---|
| 232 | + |
---|
| 233 | +void __blk_crypto_free_request(struct request *rq) |
---|
| 234 | +{ |
---|
| 235 | + /* The keyslot, if one was needed, should have been released earlier. */ |
---|
| 236 | + if (WARN_ON_ONCE(rq->crypt_keyslot)) |
---|
| 237 | + __blk_crypto_rq_put_keyslot(rq); |
---|
| 238 | + |
---|
238 | 239 | mempool_free(rq->crypt_ctx, bio_crypt_ctx_pool); |
---|
239 | | - blk_crypto_rq_set_defaults(rq); |
---|
| 240 | + rq->crypt_ctx = NULL; |
---|
240 | 241 | } |
---|
241 | 242 | |
---|
242 | 243 | /** |
---|
.. | .. |
---|
409 | 410 | EXPORT_SYMBOL_GPL(blk_crypto_start_using_key); |
---|
410 | 411 | |
---|
411 | 412 | /** |
---|
412 | | - * blk_crypto_evict_key() - Evict a key from any inline encryption hardware |
---|
413 | | - * it may have been programmed into |
---|
414 | | - * @q: The request queue who's associated inline encryption hardware this key |
---|
415 | | - * might have been programmed into |
---|
416 | | - * @key: The key to evict |
---|
| 413 | + * blk_crypto_evict_key() - Evict a blk_crypto_key from a request_queue |
---|
| 414 | + * @q: a request_queue on which I/O using the key may have been done |
---|
| 415 | + * @key: the key to evict |
---|
417 | 416 | * |
---|
418 | | - * Upper layers (filesystems) must call this function to ensure that a key is |
---|
419 | | - * evicted from any hardware that it might have been programmed into. The key |
---|
420 | | - * must not be in use by any in-flight IO when this function is called. |
---|
| 417 | + * For a given request_queue, this function removes the given blk_crypto_key |
---|
| 418 | + * from the keyslot management structures and evicts it from any underlying |
---|
| 419 | + * hardware keyslot(s) or blk-crypto-fallback keyslot it may have been |
---|
| 420 | + * programmed into. |
---|
421 | 421 | * |
---|
422 | | - * Return: 0 on success or if key is not present in the q's ksm, -err on error. |
---|
| 422 | + * Upper layers must call this before freeing the blk_crypto_key. It must be |
---|
| 423 | + * called for every request_queue the key may have been used on. The key must |
---|
| 424 | + * no longer be in use by any I/O when this function is called. |
---|
| 425 | + * |
---|
| 426 | + * Context: May sleep. |
---|
423 | 427 | */ |
---|
424 | | -int blk_crypto_evict_key(struct request_queue *q, |
---|
425 | | - const struct blk_crypto_key *key) |
---|
| 428 | +void blk_crypto_evict_key(struct request_queue *q, |
---|
| 429 | + const struct blk_crypto_key *key) |
---|
426 | 430 | { |
---|
427 | | - if (blk_ksm_crypto_cfg_supported(q->ksm, &key->crypto_cfg)) |
---|
428 | | - return blk_ksm_evict_key(q->ksm, key); |
---|
| 431 | + int err; |
---|
429 | 432 | |
---|
| 433 | + if (blk_ksm_crypto_cfg_supported(q->ksm, &key->crypto_cfg)) |
---|
| 434 | + err = blk_ksm_evict_key(q->ksm, key); |
---|
| 435 | + else |
---|
| 436 | + err = blk_crypto_fallback_evict_key(key); |
---|
430 | 437 | /* |
---|
431 | | - * If the request queue's associated inline encryption hardware didn't |
---|
432 | | - * have support for the key, then the key might have been programmed |
---|
433 | | - * into the fallback keyslot manager, so try to evict from there. |
---|
| 438 | + * An error can only occur here if the key failed to be evicted from a |
---|
| 439 | + * keyslot (due to a hardware or driver issue) or is allegedly still in |
---|
| 440 | + * use by I/O (due to a kernel bug). Even in these cases, the key is |
---|
| 441 | + * still unlinked from the keyslot management structures, and the caller |
---|
| 442 | + * is allowed and expected to free it right away. There's nothing |
---|
| 443 | + * callers can do to handle errors, so just log them and return void. |
---|
434 | 444 | */ |
---|
435 | | - return blk_crypto_fallback_evict_key(key); |
---|
| 445 | + if (err) |
---|
| 446 | + pr_warn_ratelimited("error %d evicting key\n", err); |
---|
436 | 447 | } |
---|
437 | 448 | EXPORT_SYMBOL_GPL(blk_crypto_evict_key); |
---|