patch-2.4.0-test10 linux/kernel/user.c
Next file: linux/mm/Makefile
Previous file: linux/kernel/timer.c
Back to the patch index
Back to the overall index
- Lines: 120
- Date:
Thu Oct 12 14:19:32 2000
- Orig file:
v2.4.0-test9/linux/kernel/user.c
- Orig date:
Mon Aug 7 13:30:15 2000
diff -u --recursive --new-file v2.4.0-test9/linux/kernel/user.c linux/kernel/user.c
@@ -17,11 +17,15 @@
* UID task count cache, to get fast user lookup in "alloc_uid"
* when changing user ID's (ie setuid() and friends).
*/
-#define UIDHASH_SZ (256)
+#define UIDHASH_BITS 8
+#define UIDHASH_SZ (1 << UIDHASH_BITS)
+#define UIDHASH_MASK (UIDHASH_SZ - 1)
+#define __uidhashfn(uid) (((uid >> UIDHASH_BITS) ^ uid) & UIDHASH_MASK)
+#define uidhashentry(uid) (uidhash_table + __uidhashfn(uid))
-static struct user_struct *uidhash[UIDHASH_SZ];
-
-spinlock_t uidhash_lock = SPIN_LOCK_UNLOCKED;
+static kmem_cache_t *uid_cachep;
+static struct user_struct *uidhash_table[UIDHASH_SZ];
+static spinlock_t uidhash_lock = SPIN_LOCK_UNLOCKED;
struct user_struct root_user = {
__count: ATOMIC_INIT(1),
@@ -29,49 +33,50 @@
files: ATOMIC_INIT(0)
};
-static kmem_cache_t *uid_cachep;
-
-#define uidhashfn(uid) (((uid >> 8) ^ uid) & (UIDHASH_SZ - 1))
-
/*
* These routines must be called with the uidhash spinlock held!
*/
-static inline void uid_hash_insert(struct user_struct *up, unsigned int hashent)
+static inline void uid_hash_insert(struct user_struct *up, struct user_struct **hashent)
{
- if((up->next = uidhash[hashent]) != NULL)
- uidhash[hashent]->pprev = &up->next;
- up->pprev = &uidhash[hashent];
- uidhash[hashent] = up;
+ struct user_struct *next = *hashent;
+
+ up->next = next;
+ if (next)
+ next->pprev = &up->next;
+ up->pprev = hashent;
+ *hashent = up;
}
static inline void uid_hash_remove(struct user_struct *up)
{
- if(up->next)
- up->next->pprev = up->pprev;
- *up->pprev = up->next;
+ struct user_struct *next = up->next;
+ struct user_struct **pprev = up->pprev;
+
+ if (next)
+ next->pprev = pprev;
+ *pprev = next;
}
-static inline struct user_struct *uid_hash_find(unsigned short uid, unsigned int hashent)
+static inline struct user_struct *uid_hash_find(uid_t uid, struct user_struct **hashent)
{
- struct user_struct *up, *next;
+ struct user_struct *next;
- next = uidhash[hashent];
+ next = *hashent;
for (;;) {
- up = next;
+ struct user_struct *up = next;
if (next) {
next = up->next;
if (up->uid != uid)
continue;
atomic_inc(&up->__count);
}
- break;
+ return up;
}
- return up;
}
/*
* For SMP, we need to re-test the user struct counter
- * after having aquired the spinlock. This allows us to do
+ * after having acquired the spinlock. This allows us to do
* the common case (not freeing anything) without having
* any locking.
*/
@@ -97,7 +102,7 @@
struct user_struct * alloc_uid(uid_t uid)
{
- unsigned int hashent = uidhashfn(uid);
+ struct user_struct **hashent = uidhashentry(uid);
struct user_struct *up;
spin_lock(&uidhash_lock);
@@ -136,19 +141,14 @@
static int __init uid_cache_init(void)
{
- int i;
-
uid_cachep = kmem_cache_create("uid_cache", sizeof(struct user_struct),
0,
SLAB_HWCACHE_ALIGN, NULL, NULL);
if(!uid_cachep)
panic("Cannot create uid taskcount SLAB cache\n");
- for(i = 0; i < UIDHASH_SZ; i++)
- uidhash[i] = 0;
-
/* Insert the root user immediately - init already runs with this */
- uid_hash_insert(&root_user, uidhashfn(0));
+ uid_hash_insert(&root_user, uidhashentry(0));
return 0;
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)