[PATCH] Keys: Doc update on locking

From: David Howells
Date: Fri Feb 25 2005 - 09:04:25 EST



The attached patch updates the documentation on the kernel keys to describe the
locking associated with keys and key type operations.

Signed-Off-By: David Howells <dhowells@xxxxxxxxxx>
---
warthog>diffstat -p1 keys-lock-doc-2611rc4.diff
Documentation/keys.txt | 55 +++++++++++++++++++++++++++++++++++++++----------
1 files changed, 44 insertions(+), 11 deletions(-)

diff -uNr linux-2.6.11-rc4/Documentation/keys.txt linux-2.6.11-rc4-keys-task/Documentation/keys.txt
--- linux-2.6.11-rc4/Documentation/keys.txt 2005-01-04 11:12:42.000000000 +0000
+++ linux-2.6.11-rc4-keys-task/Documentation/keys.txt 2005-02-25 13:48:17.387035408 +0000
@@ -606,8 +606,12 @@
due to two different users opening the same file is left to the filesystem
author to solve.

-When accessing a key's payload data, the key->lock should be at least read
-locked, or else the data may be changed by update during the access.
+When accessing a key's payload data, key->lock should be at least read locked,
+or else the data may be changed by an update being performed from userspace
+whilst the driver or filesystem is trying to access it. If no update method is
+supplied, then the key's payload may be accessed without holding a lock as
+there is no way to change it, provided it can be guaranteed that the key's
+type definition won't go away.

(*) To search for a key, call:

@@ -719,13 +723,19 @@

(*) int (*instantiate)(struct key *key, const void *data, size_t datalen);

- This method is called to attach a payload to a key during
- construction. The payload attached need not bear any relation to the data
- passed to this function.
+ This method is called to attach a payload to a key during construction.
+ The payload attached need not bear any relation to the data passed to
+ this function.

If the amount of data attached to the key differs from the size in
keytype->def_datalen, then key_payload_reserve() should be called.

+ This method does not have to lock the key in order to attach a payload.
+ The fact that KEY_FLAG_INSTANTIATED is not set in key->flags prevents
+ anything else from gaining access to the key.
+
+ This method may sleep if it wishes.
+

(*) int (*duplicate)(struct key *key, const struct key *source);

@@ -734,8 +744,8 @@
the new key. The data length on the new key will have been updated and
the quota adjusted already.

- The source key will be locked against change on the source->sem, so it is
- safe to sleep here.
+ This method will be called with the source key's semaphore read-locked to
+ prevent its payload from being changed. It is safe to sleep here.


(*) int (*update)(struct key *key, const void *data, size_t datalen);
@@ -749,30 +759,47 @@
type is committed to changing the key because it's already been altered,
so all memory allocation must be done first.

- The key will be locked against other changers on key->sem, so it is safe
- to sleep here.
-
key_payload_reserve() should be called with the key->lock write locked,
and the changes to the key's attached payload should be made before the
key is locked.

+ The key will have its semaphore write-locked before this method is
+ called. Any changes to the key should be made with the key's rwlock
+ write-locked also. It is safe to sleep here.
+

(*) int (*match)(const struct key *key, const void *desc);

This method is called to match a key against a description. It should
return non-zero if the two match, zero if they don't.

+ This method should not need to lock the key in any way. The type and
+ description can be considered invariant, and the payload should not be
+ accessed (the key may not yet be instantiated).
+
+ It is not safe to sleep in this method; the caller may hold spinlocks.
+

(*) void (*destroy)(struct key *key);

This method is optional. It is called to discard the payload data on a
key when it is being destroyed.

+ This method does not need to lock the key; it can consider the key as
+ being inaccessible. Note that the key's type may have changed before this
+ function is called.
+
+ It is not safe to sleep in this method; the caller may hold spinlocks.
+

(*) void (*describe)(const struct key *key, struct seq_file *p);

This method is optional. It is called during /proc/keys reading to
- summarise a key in text form.
+ summarise a key's description and payload in text form.
+
+ This method will be called with the key's rwlock read-locked. This will
+ prevent the key's payload and state changing; also the description should
+ not change. This also means it is not safe to sleep in this method.


(*) long (*read)(const struct key *key, char __user *buffer, size_t buflen);
@@ -785,6 +812,12 @@
If successful, the blob size that could be produced should be returned
rather than the size copied.

+ This method will be called with the key's semaphore read-locked. This
+ will prevent the key's payload changing. It is not necessary to also
+ read-lock key->lock when accessing the key's payload. It is safe to sleep
+ in this method, such as might happen when the userspace buffer is
+ accessed.
+

============================
REQUEST-KEY CALLBACK SERVICE
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/