| .. | .. |
|---|
| 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 | } |
|---|