/* * Called with a modifying token held, but must still obtain p_spin to * actually replace p_ucred to handle races against syscall entry from * other threads which cache p_ucred->td_ucred. * * (the threads will only get the spin-lock, and they only need to in * the case where td_ucred != p_ucred so this is optimal). */ struct ucred * cratom_proc(struct proc *p) { struct ucred *oldcr; struct ucred *newcr; oldcr = p->p_ucred; if (oldcr->cr_ref == 1) return(oldcr); newcr = crget(); /* this might block */ oldcr = p->p_ucred; /* so re-cache oldcr (do not re-test) */ *newcr = *oldcr; if (newcr->cr_uidinfo) uihold(newcr->cr_uidinfo); if (newcr->cr_ruidinfo) uihold(newcr->cr_ruidinfo); if (jailed(newcr)) prison_hold(newcr->cr_prison); newcr->cr_ref = 1; spin_lock(&p->p_spin); p->p_ucred = newcr; spin_unlock(&p->p_spin); crfree(oldcr); return newcr; }
/* * Dup cred struct to a new held one. */ struct ucred * crdup(struct ucred *cr) { struct ucred *newcr; newcr = crget(); *newcr = *cr; if (newcr->cr_uidinfo) uihold(newcr->cr_uidinfo); if (newcr->cr_ruidinfo) uihold(newcr->cr_ruidinfo); if (jailed(newcr)) prison_hold(newcr->cr_prison); newcr->cr_ref = 1; return (newcr); }
/* * Copy cred structure to a new one and free the old one. * * MPSAFE (*cr must be stable) */ struct ucred * crcopy(struct ucred *cr) { struct ucred *newcr; if (cr->cr_ref == 1) return (cr); newcr = crget(); *newcr = *cr; if (newcr->cr_uidinfo) uihold(newcr->cr_uidinfo); if (newcr->cr_ruidinfo) uihold(newcr->cr_ruidinfo); if (jailed(newcr)) prison_hold(newcr->cr_prison); newcr->cr_ref = 1; crfree(cr); return (newcr); }
/* * Atomize a cred structure so it can be modified without polluting * other references to it. * * MPSAFE (however, *pcr must be stable) */ struct ucred * cratom(struct ucred **pcr) { struct ucred *oldcr; struct ucred *newcr; oldcr = *pcr; if (oldcr->cr_ref == 1) return (oldcr); newcr = crget(); *newcr = *oldcr; if (newcr->cr_uidinfo) uihold(newcr->cr_uidinfo); if (newcr->cr_ruidinfo) uihold(newcr->cr_ruidinfo); if (jailed(newcr)) prison_hold(newcr->cr_prison); newcr->cr_ref = 1; crfree(oldcr); *pcr = newcr; return (newcr); }
/* * Atomize a cred structure so it can be modified without polluting * other references to it. * * MPSAFE (however, *pcr must be stable) */ struct ucred * cratom(struct ucred **pcr) { struct ucred *oldcr; struct ucred *newcr; oldcr = *pcr; if (oldcr->cr_ref == 1) return (oldcr); newcr = crget(); /* this might block */ oldcr = *pcr; /* re-cache after potentially blocking */ *newcr = *oldcr; if (newcr->cr_uidinfo) uihold(newcr->cr_uidinfo); if (newcr->cr_ruidinfo) uihold(newcr->cr_ruidinfo); if (jailed(newcr)) prison_hold(newcr->cr_prison); newcr->cr_ref = 1; crfree(oldcr); *pcr = newcr; return (newcr); }