Use the refcount API to manage the reference count for user credentials
rather than using pool mutexes. Tested on: i386, alpha, sparc64
This commit is contained in:
parent
b2149bde1f
commit
7e9e371f2d
@ -54,6 +54,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/mac.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/refcount.h>
|
||||
#include <sys/sx.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/sysproto.h>
|
||||
@ -1841,8 +1842,7 @@ crget(void)
|
||||
register struct ucred *cr;
|
||||
|
||||
MALLOC(cr, struct ucred *, sizeof(*cr), M_CRED, M_WAITOK | M_ZERO);
|
||||
cr->cr_ref = 1;
|
||||
cr->cr_mtxp = mtx_pool_find(mtxpool_sleep, cr);
|
||||
refcount_init(&cr->cr_ref, 1);
|
||||
#ifdef MAC
|
||||
mac_init_cred(cr);
|
||||
#endif
|
||||
@ -1857,9 +1857,7 @@ struct ucred *
|
||||
crhold(struct ucred *cr)
|
||||
{
|
||||
|
||||
mtx_lock(cr->cr_mtxp);
|
||||
cr->cr_ref++;
|
||||
mtx_unlock(cr->cr_mtxp);
|
||||
refcount_acquire(&cr->cr_ref);
|
||||
return (cr);
|
||||
}
|
||||
|
||||
@ -1871,12 +1869,10 @@ crhold(struct ucred *cr)
|
||||
void
|
||||
crfree(struct ucred *cr)
|
||||
{
|
||||
struct mtx *mtxp = cr->cr_mtxp;
|
||||
|
||||
mtx_lock(mtxp);
|
||||
KASSERT(cr->cr_ref > 0, ("bad ucred refcount: %d", cr->cr_ref));
|
||||
if (--cr->cr_ref == 0) {
|
||||
mtx_unlock(mtxp);
|
||||
KASSERT(cr->cr_ref != 0xdeadc0de, ("dangling reference to ucred"));
|
||||
if (refcount_release(&cr->cr_ref)) {
|
||||
/*
|
||||
* Some callers of crget(), such as nfs_statfs(),
|
||||
* allocate a temporary credential, but don't
|
||||
@ -1895,8 +1891,6 @@ crfree(struct ucred *cr)
|
||||
mac_destroy_cred(cr);
|
||||
#endif
|
||||
FREE(cr, M_CRED);
|
||||
} else {
|
||||
mtx_unlock(mtxp);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1907,12 +1901,8 @@ crfree(struct ucred *cr)
|
||||
int
|
||||
crshared(struct ucred *cr)
|
||||
{
|
||||
int shared;
|
||||
|
||||
mtx_lock(cr->cr_mtxp);
|
||||
shared = (cr->cr_ref > 1);
|
||||
mtx_unlock(cr->cr_mtxp);
|
||||
return (shared);
|
||||
return (cr->cr_ref > 1);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -46,6 +46,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/refcount.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/vnode.h>
|
||||
@ -115,7 +116,7 @@ vfs_hang_addrlist(mp, nep, argp)
|
||||
np->netc_anon.cr_ngroups = argp->ex_anon.cr_ngroups;
|
||||
bcopy(argp->ex_anon.cr_groups, np->netc_anon.cr_groups,
|
||||
sizeof(np->netc_anon.cr_groups));
|
||||
np->netc_anon.cr_ref = 1;
|
||||
refcount_init(&np->netc_anon.cr_ref, 1);
|
||||
mp->mnt_flag |= MNT_DEFEXPORTED;
|
||||
return (0);
|
||||
}
|
||||
@ -174,7 +175,7 @@ vfs_hang_addrlist(mp, nep, argp)
|
||||
np->netc_anon.cr_ngroups = argp->ex_anon.cr_ngroups;
|
||||
bcopy(argp->ex_anon.cr_groups, np->netc_anon.cr_groups,
|
||||
sizeof(np->netc_anon.cr_groups));
|
||||
np->netc_anon.cr_ref = 1;
|
||||
refcount_init(&np->netc_anon.cr_ref, 1);
|
||||
return (0);
|
||||
out:
|
||||
free(np, M_NETADDR);
|
||||
|
@ -49,6 +49,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/protosw.h>
|
||||
#include <sys/refcount.h>
|
||||
#include <sys/signalvar.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/socketvar.h>
|
||||
@ -364,12 +365,11 @@ nfs_getreq(struct nfsrv_descript *nd, struct nfsd *nfsd, int has_header)
|
||||
/*
|
||||
* XXX: This credential should be managed using crget(9)
|
||||
* and related calls. Right now, this tramples on any
|
||||
* extensible data in the ucred, fails to initialize the
|
||||
* mutex, and worse. This must be fixed before FreeBSD
|
||||
* 5.3-RELEASE.
|
||||
* extensible data in the ucred, and worse. This wasn't
|
||||
* fixed before FreeBSD 5.3-RELEASE.
|
||||
*/
|
||||
bzero((caddr_t)&nd->nd_cr, sizeof (struct ucred));
|
||||
nd->nd_cr.cr_ref = 1;
|
||||
refcount_init(&nd->nd_cr.cr_ref, 1);
|
||||
nd->nd_cr.cr_uid = fxdr_unsigned(uid_t, *tl++);
|
||||
nd->nd_cr.cr_gid = fxdr_unsigned(gid_t, *tl++);
|
||||
len = fxdr_unsigned(int, *tl);
|
||||
|
@ -53,6 +53,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/vnode.h>
|
||||
#include <sys/namei.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/refcount.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/malloc.h>
|
||||
@ -1257,7 +1258,7 @@ nfsrv_setcred(struct ucred *incred, struct ucred *outcred)
|
||||
NFSD_LOCK_DONTCARE();
|
||||
|
||||
bzero((caddr_t)outcred, sizeof (struct ucred));
|
||||
outcred->cr_ref = 1;
|
||||
refcount_init(&outcred->cr_ref, 1);
|
||||
outcred->cr_uid = incred->cr_uid;
|
||||
outcred->cr_ngroups = incred->cr_ngroups;
|
||||
for (i = 0; i < incred->cr_ngroups; i++)
|
||||
|
@ -55,7 +55,6 @@ struct ucred {
|
||||
struct prison *cr_prison; /* jail(2) */
|
||||
#define cr_endcopy cr_label
|
||||
struct label *cr_label; /* MAC label */
|
||||
struct mtx *cr_mtxp; /* protect refcount */
|
||||
};
|
||||
#define NOCRED ((struct ucred *)0) /* no credential available */
|
||||
#define FSCRED ((struct ucred *)-1) /* filesystem credential */
|
||||
|
@ -53,6 +53,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/bio.h>
|
||||
#include <sys/buf.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/refcount.h>
|
||||
#include <sys/unistd.h>
|
||||
#include <sys/vnode.h>
|
||||
#include <sys/dirent.h>
|
||||
@ -1364,7 +1365,7 @@ ufs_mkdir(ap)
|
||||
* XXX This seems to never be accessed out of
|
||||
* our context so a stack variable is ok.
|
||||
*/
|
||||
ucred.cr_ref = 1;
|
||||
refcount_init(&ucred.cr_ref, 1);
|
||||
ucred.cr_uid = ip->i_uid;
|
||||
ucred.cr_ngroups = 1;
|
||||
ucred.cr_groups[0] = dp->i_gid;
|
||||
@ -2195,7 +2196,7 @@ ufs_makeinode(mode, dvp, vpp, cnp)
|
||||
* XXX This seems to never be accessed out of our
|
||||
* context so a stack variable is ok.
|
||||
*/
|
||||
ucred.cr_ref = 1;
|
||||
refcount_init(&ucred.cr_ref, 1);
|
||||
ucred.cr_uid = ip->i_uid;
|
||||
ucred.cr_ngroups = 1;
|
||||
ucred.cr_groups[0] = pdir->i_gid;
|
||||
|
Loading…
Reference in New Issue
Block a user