hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/block/blk-crypto.c
....@@ -13,6 +13,7 @@
1313 #include <linux/blkdev.h>
1414 #include <linux/keyslot-manager.h>
1515 #include <linux/module.h>
16
+#include <linux/ratelimit.h>
1617 #include <linux/slab.h>
1718
1819 #include "blk-crypto-internal.h"
....@@ -217,26 +218,26 @@
217218 return true;
218219 }
219220
220
-blk_status_t __blk_crypto_init_request(struct request *rq)
221
+blk_status_t __blk_crypto_rq_get_keyslot(struct request *rq)
221222 {
222223 return blk_ksm_get_slot_for_key(rq->q->ksm, rq->crypt_ctx->bc_key,
223224 &rq->crypt_keyslot);
224225 }
225226
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)
236228 {
237229 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
+
238239 mempool_free(rq->crypt_ctx, bio_crypt_ctx_pool);
239
- blk_crypto_rq_set_defaults(rq);
240
+ rq->crypt_ctx = NULL;
240241 }
241242
242243 /**
....@@ -409,29 +410,39 @@
409410 EXPORT_SYMBOL_GPL(blk_crypto_start_using_key);
410411
411412 /**
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
417416 *
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.
421421 *
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.
423427 */
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)
426430 {
427
- if (blk_ksm_crypto_cfg_supported(q->ksm, &key->crypto_cfg))
428
- return blk_ksm_evict_key(q->ksm, key);
431
+ int err;
429432
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);
430437 /*
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.
434444 */
435
- return blk_crypto_fallback_evict_key(key);
445
+ if (err)
446
+ pr_warn_ratelimited("error %d evicting key\n", err);
436447 }
437448 EXPORT_SYMBOL_GPL(blk_crypto_evict_key);