diff options
author | David Howells <dhowells@redhat.com> | 2012-05-11 10:56:56 +0100 |
---|---|---|
committer | David Howells <dhowells@redhat.com> | 2012-05-11 10:56:56 +0100 |
commit | 65d87fe68abf2fc226a9e96be61160f65d6b4680 (patch) | |
tree | 23881b6daf54c7522178363f0ae32ddb6c836784 /include/linux | |
parent | 1eb1bcf5bfad001128293b86d891c9d6f2f27333 (diff) |
KEYS: Perform RCU synchronisation on keys prior to key destruction
Make the keys garbage collector invoke synchronize_rcu() prior to destroying
keys with a zero usage count. This means that a key can be examined under the
RCU read lock in the safe knowledge that it won't get deallocated until after
the lock is released - even if its usage count becomes zero whilst we're
looking at it.
This is useful in keyring search vs key link. Consider a keyring containing a
link to a key. That link can be replaced in-place in the keyring without
requiring an RCU copy-and-replace on the keyring contents without breaking a
search underway on that keyring when the displaced key is released, provided
the key is actually destroyed only after the RCU read lock held by the search
algorithm is released.
This permits __key_link() to replace a key without having to reallocate the key
payload. A key gets replaced if a new key being linked into a keyring has the
same type and description.
Signed-off-by: David Howells <dhowells@redhat.com>
Acked-by: Jeff Layton <jlayton@redhat.com>
Diffstat (limited to 'include/linux')
-rw-r--r-- | include/linux/key.h | 5 |
1 files changed, 4 insertions, 1 deletions
diff --git a/include/linux/key.h b/include/linux/key.h index 96933b1e5d24..c505f83c9691 100644 --- a/include/linux/key.h +++ b/include/linux/key.h @@ -124,7 +124,10 @@ static inline unsigned long is_key_possessed(const key_ref_t key_ref) struct key { atomic_t usage; /* number of references */ key_serial_t serial; /* key serial number */ - struct rb_node serial_node; + union { + struct list_head graveyard_link; + struct rb_node serial_node; + }; struct key_type *type; /* type of key */ struct rw_semaphore sem; /* change vs change sem */ struct key_user *user; /* owner of this key */ |