opal: pull LSP activation in separate function.

This commit is contained in:
Ondrej Kozina
2025-07-31 15:18:55 +02:00
parent 346db2e42a
commit 32b33541a8

View File

@@ -402,53 +402,15 @@ static int opal_enabled(struct crypt_device *cd, struct device *dev)
return opal_query_status(cd, dev, OPAL_FL_LOCKING_ENABLED);
}
/* requires opal lock */
int opal_setup_ranges(struct crypt_device *cd,
struct device *dev,
const struct volume_key *vk,
uint64_t range_start_blocks,
uint64_t range_length_blocks,
uint32_t opal_block_bytes,
uint32_t segment_number,
const void *admin_key,
size_t admin_key_len)
static int opal_activate_lsp(struct crypt_device *cd, int fd,
const void *admin_key, size_t admin_key_len)
{
struct opal_lr_act *activate = NULL;
struct opal_session_info *user_session = NULL;
struct opal_lock_unlock *user_add_to_lr = NULL, *lock = NULL;
struct opal_new_pw *new_pw = NULL;
struct opal_user_lr_setup *setup = NULL;
int r, fd;
int r;
struct opal_lr_act *activate = crypt_safe_alloc(sizeof(*activate));
assert(cd);
assert(dev);
assert(vk);
assert(admin_key);
assert(crypt_volume_key_length(vk) <= OPAL_KEY_MAX);
assert(opal_block_bytes >= SECTOR_SIZE);
if (!activate)
return -ENOMEM;
if (admin_key_len > OPAL_KEY_MAX)
return -EINVAL;
if (((UINT64_MAX / opal_block_bytes) < range_start_blocks) ||
((UINT64_MAX / opal_block_bytes) < range_length_blocks))
return -EINVAL;
fd = device_open(cd, dev, O_RDONLY);
if (fd < 0)
return -EIO;
r = opal_enabled(cd, dev);
if (r < 0)
return r;
/* If OPAL has never been enabled, we need to take ownership and do basic setup first */
if (r == 0) {
activate = crypt_safe_alloc(sizeof(struct opal_lr_act));
if (!activate) {
r = -ENOMEM;
goto out;
}
*activate = (struct opal_lr_act) {
.key = {
.key_len = admin_key_len,
@@ -485,9 +447,56 @@ int opal_setup_ranges(struct crypt_device *cd,
log_dbg(cd, "Failed to activate OPAL device '%s': %s",
crypt_get_device_name(cd), opal_status_to_string(r));
r = -EINVAL;
goto out;
}
} else {
out:
crypt_safe_free(activate);
return r;
}
/* requires opal lock */
int opal_setup_ranges(struct crypt_device *cd,
struct device *dev,
const struct volume_key *vk,
uint64_t range_start_blocks,
uint64_t range_length_blocks,
uint32_t opal_block_bytes,
uint32_t segment_number,
const void *admin_key,
size_t admin_key_len)
{
struct opal_session_info *user_session = NULL;
struct opal_lock_unlock *user_add_to_lr = NULL, *lock = NULL;
struct opal_new_pw *new_pw = NULL;
struct opal_user_lr_setup *setup = NULL;
int r, fd;
assert(cd);
assert(dev);
assert(vk);
assert(admin_key);
assert(crypt_volume_key_length(vk) <= OPAL_KEY_MAX);
assert(opal_block_bytes >= SECTOR_SIZE);
if (admin_key_len > OPAL_KEY_MAX)
return -EINVAL;
if (((UINT64_MAX / opal_block_bytes) < range_start_blocks) ||
((UINT64_MAX / opal_block_bytes) < range_length_blocks))
return -EINVAL;
fd = device_open(cd, dev, O_RDONLY);
if (fd < 0)
return -EIO;
r = opal_enabled(cd, dev);
if (r < 0)
return r;
/* If OPAL has never been enabled, we need to take ownership and do basic setup first */
if (r == 0)
r = opal_activate_lsp(cd, fd, admin_key, admin_key_len);
else {
/* If it is already enabled, wipe the locking range first */
user_session = crypt_safe_alloc(sizeof(struct opal_session_info));
if (!user_session) {
@@ -667,7 +676,6 @@ int opal_setup_ranges(struct crypt_device *cd,
&(uint64_t) {range_length_blocks * opal_block_bytes / SECTOR_SIZE},
&(bool) {true}, &(bool){true}, NULL, NULL);
out:
crypt_safe_free(activate);
crypt_safe_free(user_session);
crypt_safe_free(user_add_to_lr);
crypt_safe_free(new_pw);