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:
parent
c0031f4db1
commit
a1b56e9811
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user