.. | .. |
---|
350 | 350 | return true; |
---|
351 | 351 | } |
---|
352 | 352 | |
---|
353 | | -/** |
---|
354 | | - * blk_ksm_evict_key() - Evict a key from the lower layer device. |
---|
355 | | - * @ksm: The keyslot manager to evict from |
---|
356 | | - * @key: The key to evict |
---|
357 | | - * |
---|
358 | | - * Find the keyslot that the specified key was programmed into, and evict that |
---|
359 | | - * slot from the lower layer device. The slot must not be in use by any |
---|
360 | | - * in-flight IO when this function is called. |
---|
361 | | - * |
---|
362 | | - * Context: Process context. Takes and releases ksm->lock. |
---|
363 | | - * Return: 0 on success or if there's no keyslot with the specified key, -EBUSY |
---|
364 | | - * if the keyslot is still in use, or another -errno value on other |
---|
365 | | - * error. |
---|
| 353 | +/* |
---|
| 354 | + * This is an internal function that evicts a key from an inline encryption |
---|
| 355 | + * device that can be either a real device or the blk-crypto-fallback "device". |
---|
| 356 | + * It is used only by blk_crypto_evict_key(); see that function for details. |
---|
366 | 357 | */ |
---|
367 | 358 | int blk_ksm_evict_key(struct blk_keyslot_manager *ksm, |
---|
368 | 359 | const struct blk_crypto_key *key) |
---|
369 | 360 | { |
---|
370 | 361 | struct blk_ksm_keyslot *slot; |
---|
371 | | - int err = 0; |
---|
| 362 | + int err; |
---|
372 | 363 | |
---|
373 | 364 | if (blk_ksm_is_passthrough(ksm)) { |
---|
374 | 365 | if (ksm->ksm_ll_ops.keyslot_evict) { |
---|
.. | .. |
---|
382 | 373 | |
---|
383 | 374 | blk_ksm_hw_enter(ksm); |
---|
384 | 375 | slot = blk_ksm_find_keyslot(ksm, key); |
---|
385 | | - if (!slot) |
---|
386 | | - goto out_unlock; |
---|
| 376 | + if (!slot) { |
---|
| 377 | + /* |
---|
| 378 | + * Not an error, since a key not in use by I/O is not guaranteed |
---|
| 379 | + * to be in a keyslot. There can be more keys than keyslots. |
---|
| 380 | + */ |
---|
| 381 | + err = 0; |
---|
| 382 | + goto out; |
---|
| 383 | + } |
---|
387 | 384 | |
---|
388 | 385 | if (WARN_ON_ONCE(atomic_read(&slot->slot_refs) != 0)) { |
---|
| 386 | + /* BUG: key is still in use by I/O */ |
---|
389 | 387 | err = -EBUSY; |
---|
390 | | - goto out_unlock; |
---|
| 388 | + goto out_remove; |
---|
391 | 389 | } |
---|
392 | 390 | err = ksm->ksm_ll_ops.keyslot_evict(ksm, key, |
---|
393 | 391 | blk_ksm_get_slot_idx(slot)); |
---|
394 | | - if (err) |
---|
395 | | - goto out_unlock; |
---|
396 | | - |
---|
| 392 | +out_remove: |
---|
| 393 | + /* |
---|
| 394 | + * Callers free the key even on error, so unlink the key from the hash |
---|
| 395 | + * table and clear slot->key even on error. |
---|
| 396 | + */ |
---|
397 | 397 | hlist_del(&slot->hash_node); |
---|
398 | 398 | slot->key = NULL; |
---|
399 | | - err = 0; |
---|
400 | | -out_unlock: |
---|
| 399 | +out: |
---|
401 | 400 | blk_ksm_hw_exit(ksm); |
---|
402 | 401 | return err; |
---|
403 | 402 | } |
---|