ucred system overhaul:

1) mpsafe (protect the refcount with a mutex).
2) reduce duplicated code by removing the inlined crdup() from crcopy()
   and make crcopy() call crdup().
3) use M_ZERO flag when allocating initial structs instead of calling bzero
   after allocation.
4) expand the size of the refcount from a u_short to an u_int, by using
   shorts we might have an overflow.

Glanced at by: jake
This commit is contained in:
alfred 2000-11-27 00:09:16 +00:00
parent a7e1babad9
commit 614730a418
2 changed files with 25 additions and 10 deletions

View File

@ -1131,9 +1131,9 @@ crget()
{
register struct ucred *cr;
MALLOC(cr, struct ucred *, sizeof(*cr), M_CRED, M_WAITOK);
bzero((caddr_t)cr, sizeof(*cr));
MALLOC(cr, struct ucred *, sizeof(*cr), M_CRED, M_WAITOK|M_ZERO);
cr->cr_ref = 1;
mtx_init(&cr->cr_mtx, "ucred", MTX_DEF);
return (cr);
}
@ -1145,7 +1145,10 @@ void
crfree(cr)
struct ucred *cr;
{
mtx_enter(&cr->cr_mtx, MTX_DEF);
if (--cr->cr_ref == 0) {
mtx_destroy(&cr->cr_mtx);
/*
* Some callers of crget(), such as nfs_statfs(),
* allocate a temporary credential, but don't
@ -1154,6 +1157,8 @@ crfree(cr)
if (cr->cr_uidinfo != NULL)
uifree(cr->cr_uidinfo);
FREE((caddr_t)cr, M_CRED);
} else {
mtx_exit(&cr->cr_mtx, MTX_DEF);
}
}
@ -1166,13 +1171,14 @@ crcopy(cr)
{
struct ucred *newcr;
if (cr->cr_ref == 1)
mtx_enter(&cr->cr_mtx, MTX_DEF);
if (cr->cr_ref == 1) {
mtx_exit(&cr->cr_mtx, MTX_DEF);
return (cr);
newcr = crget();
*newcr = *cr;
uihold(newcr->cr_uidinfo);
}
mtx_exit(&cr->cr_mtx, MTX_DEF);
newcr = crdup(cr);
crfree(cr);
newcr->cr_ref = 1;
return (newcr);
}
@ -1185,8 +1191,9 @@ crdup(cr)
{
struct ucred *newcr;
newcr = crget();
MALLOC(newcr, struct ucred *, sizeof(*cr), M_CRED, M_WAITOK);
*newcr = *cr;
mtx_init(&newcr->cr_mtx, "ucred", MTX_DEF);
uihold(newcr->cr_uidinfo);
newcr->cr_ref = 1;
return (newcr);

View File

@ -37,6 +37,8 @@
#ifndef _SYS_UCRED_H_
#define _SYS_UCRED_H_
#include <sys/mutex.h>
/*
* Credentials.
*
@ -44,7 +46,8 @@
* Only the suser()/suser_xxx() function should be used for this.
*/
struct ucred {
u_short cr_ref; /* reference count */
struct mtx cr_mtx; /* protect refcount */
u_int cr_ref; /* reference count */
uid_t cr_uid; /* effective user id */
short cr_ngroups; /* number of groups */
gid_t cr_groups[NGROUPS]; /* groups */
@ -55,7 +58,12 @@ struct ucred {
#define FSCRED ((struct ucred *)-1) /* filesystem credential */
#ifdef _KERNEL
#define crhold(cr) (cr)->cr_ref++
#define crhold(cr) \
do { \
mtx_enter(&(cr)->cr_mtx, MTX_DEF); \
(cr)->cr_ref++; \
mtx_exit(&(cr)->cr_mtx, MTX_DEF); \
} while (0)
struct proc;