keys: Break bits out of key_unlink()
Break bits out of key_unlink() into helper functions so that they can be used in implementing key_move(). Signed-off-by: David Howells <dhowells@redhat.com>
This commit is contained in:
Родитель
3be59f7451
Коммит
eb0f68cb70
|
@ -1382,6 +1382,65 @@ int key_link(struct key *keyring, struct key *key)
|
|||
}
|
||||
EXPORT_SYMBOL(key_link);
|
||||
|
||||
/*
|
||||
* Lock a keyring for unlink.
|
||||
*/
|
||||
static int __key_unlink_lock(struct key *keyring)
|
||||
__acquires(&keyring->sem)
|
||||
{
|
||||
if (keyring->type != &key_type_keyring)
|
||||
return -ENOTDIR;
|
||||
|
||||
down_write(&keyring->sem);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Begin the process of unlinking a key from a keyring.
|
||||
*/
|
||||
static int __key_unlink_begin(struct key *keyring, struct key *key,
|
||||
struct assoc_array_edit **_edit)
|
||||
{
|
||||
struct assoc_array_edit *edit;
|
||||
|
||||
BUG_ON(*_edit != NULL);
|
||||
|
||||
edit = assoc_array_delete(&keyring->keys, &keyring_assoc_array_ops,
|
||||
&key->index_key);
|
||||
if (IS_ERR(edit))
|
||||
return PTR_ERR(edit);
|
||||
|
||||
if (!edit)
|
||||
return -ENOENT;
|
||||
|
||||
*_edit = edit;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Apply an unlink change.
|
||||
*/
|
||||
static void __key_unlink(struct key *keyring, struct key *key,
|
||||
struct assoc_array_edit **_edit)
|
||||
{
|
||||
assoc_array_apply_edit(*_edit);
|
||||
*_edit = NULL;
|
||||
key_payload_reserve(keyring, keyring->datalen - KEYQUOTA_LINK_BYTES);
|
||||
}
|
||||
|
||||
/*
|
||||
* Finish unlinking a key from to a keyring.
|
||||
*/
|
||||
static void __key_unlink_end(struct key *keyring,
|
||||
struct key *key,
|
||||
struct assoc_array_edit *edit)
|
||||
__releases(&keyring->sem)
|
||||
{
|
||||
if (edit)
|
||||
assoc_array_cancel_edit(edit);
|
||||
up_write(&keyring->sem);
|
||||
}
|
||||
|
||||
/**
|
||||
* key_unlink - Unlink the first link to a key from a keyring.
|
||||
* @keyring: The keyring to remove the link from.
|
||||
|
@ -1401,33 +1460,20 @@ EXPORT_SYMBOL(key_link);
|
|||
*/
|
||||
int key_unlink(struct key *keyring, struct key *key)
|
||||
{
|
||||
struct assoc_array_edit *edit;
|
||||
struct assoc_array_edit *edit = NULL;
|
||||
int ret;
|
||||
|
||||
key_check(keyring);
|
||||
key_check(key);
|
||||
|
||||
if (keyring->type != &key_type_keyring)
|
||||
return -ENOTDIR;
|
||||
ret = __key_unlink_lock(keyring);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
down_write(&keyring->sem);
|
||||
|
||||
edit = assoc_array_delete(&keyring->keys, &keyring_assoc_array_ops,
|
||||
&key->index_key);
|
||||
if (IS_ERR(edit)) {
|
||||
ret = PTR_ERR(edit);
|
||||
goto error;
|
||||
}
|
||||
ret = -ENOENT;
|
||||
if (edit == NULL)
|
||||
goto error;
|
||||
|
||||
assoc_array_apply_edit(edit);
|
||||
key_payload_reserve(keyring, keyring->datalen - KEYQUOTA_LINK_BYTES);
|
||||
ret = 0;
|
||||
|
||||
error:
|
||||
up_write(&keyring->sem);
|
||||
ret = __key_unlink_begin(keyring, key, &edit);
|
||||
if (ret == 0)
|
||||
__key_unlink(keyring, key, &edit);
|
||||
__key_unlink_end(keyring, key, edit);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(key_unlink);
|
||||
|
|
Загрузка…
Ссылка в новой задаче