| .. | .. |
|---|
| 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); |
|---|