*/
int key_payload_reserve(struct key *key, size_t datalen)
{
- int delta = (int) datalen - key->datalen;
+ int delta = (int)datalen - key->datalen;
int ret = 0;
key_check(key);
const void *data,
size_t datalen,
struct key *keyring,
- struct key *authkey)
+ struct key *authkey,
+ struct keyring_list **_prealloc)
{
int ret, awaken;
/* and link it into the destination keyring */
if (keyring)
- ret = __key_link(keyring, key);
+ __key_link(keyring, key, _prealloc);
/* disable the authorisation key */
if (authkey)
struct key *keyring,
struct key *authkey)
{
+ struct keyring_list *prealloc;
int ret;
- if (keyring)
- down_write(&keyring->sem);
+ if (keyring) {
+ ret = __key_link_begin(keyring, key->type, key->description,
+ &prealloc);
+ if (ret < 0)
+ return ret;
+ }
- ret = __key_instantiate_and_link(key, data, datalen, keyring, authkey);
+ ret = __key_instantiate_and_link(key, data, datalen, keyring, authkey,
+ &prealloc);
if (keyring)
- up_write(&keyring->sem);
+ __key_link_end(keyring, key->type, prealloc);
return ret;
struct key *keyring,
struct key *authkey)
{
+ struct keyring_list *prealloc;
struct timespec now;
- int ret, awaken;
+ int ret, awaken, link_ret = 0;
key_check(key);
key_check(keyring);
ret = -EBUSY;
if (keyring)
- down_write(&keyring->sem);
+ link_ret = __key_link_begin(keyring, key->type,
+ key->description, &prealloc);
mutex_lock(&key_construction_mutex);
ret = 0;
/* and link it into the destination keyring */
- if (keyring)
- ret = __key_link(keyring, key);
+ if (keyring && link_ret == 0)
+ __key_link(keyring, key, &prealloc);
/* disable the authorisation key */
if (authkey)
mutex_unlock(&key_construction_mutex);
if (keyring)
- up_write(&keyring->sem);
+ __key_link_end(keyring, key->type, prealloc);
/* wake up anyone waiting for a key to be constructed */
if (awaken)
wake_up_bit(&key->flags, KEY_FLAG_USER_CONSTRUCT);
- return ret;
+ return ret == 0 ? link_ret : ret;
} /* end key_negate_and_link() */
key_perm_t perm,
unsigned long flags)
{
+ struct keyring_list *prealloc;
const struct cred *cred = current_cred();
struct key_type *ktype;
struct key *keyring, *key = NULL;
if (keyring->type != &key_type_keyring)
goto error_2;
- down_write(&keyring->sem);
+ ret = __key_link_begin(keyring, ktype, description, &prealloc);
+ if (ret < 0)
+ goto error_2;
/* if we're going to allocate a new key, we're going to have
* to modify the keyring */
}
/* instantiate it and link it into the target keyring */
- ret = __key_instantiate_and_link(key, payload, plen, keyring, NULL);
+ ret = __key_instantiate_and_link(key, payload, plen, keyring, NULL,
+ &prealloc);
if (ret < 0) {
key_put(key);
key_ref = ERR_PTR(ret);
key_ref = make_key_ref(key, is_key_possessed(keyring_ref));
error_3:
- up_write(&keyring->sem);
+ __key_link_end(keyring, ktype, prealloc);
error_2:
key_type_put(ktype);
error:
/* we found a matching key, so we're going to try to update it
* - we can drop the locks first as we have the key pinned
*/
- up_write(&keyring->sem);
+ __key_link_end(keyring, ktype, prealloc);
key_type_put(ktype);
key_ref = __key_update(key_ref, payload, plen);