* Find or allocate a struct uidinfo for a particular uid. * Returns with uidinfo struct referenced. * uifree() should be called on a struct uidinfo when released. */
| 1366 | * uifree() should be called on a struct uidinfo when released. |
| 1367 | */ |
| 1368 | struct uidinfo * |
| 1369 | uifind(uid_t uid) |
| 1370 | { |
| 1371 | struct uidinfo *new_uip, *uip; |
| 1372 | struct ucred *cred; |
| 1373 | |
| 1374 | cred = curthread->td_ucred; |
| 1375 | if (cred->cr_uidinfo->ui_uid == uid) { |
| 1376 | uip = cred->cr_uidinfo; |
| 1377 | uihold(uip); |
| 1378 | return (uip); |
| 1379 | } else if (cred->cr_ruidinfo->ui_uid == uid) { |
| 1380 | uip = cred->cr_ruidinfo; |
| 1381 | uihold(uip); |
| 1382 | return (uip); |
| 1383 | } |
| 1384 | |
| 1385 | rw_rlock(&uihashtbl_lock); |
| 1386 | uip = uilookup(uid); |
| 1387 | rw_runlock(&uihashtbl_lock); |
| 1388 | if (uip != NULL) |
| 1389 | return (uip); |
| 1390 | |
| 1391 | new_uip = malloc(sizeof(*new_uip), M_UIDINFO, M_WAITOK | M_ZERO); |
| 1392 | racct_create(&new_uip->ui_racct); |
| 1393 | refcount_init(&new_uip->ui_ref, 1); |
| 1394 | new_uip->ui_uid = uid; |
| 1395 | |
| 1396 | rw_wlock(&uihashtbl_lock); |
| 1397 | /* |
| 1398 | * There's a chance someone created our uidinfo while we |
| 1399 | * were in malloc and not holding the lock, so we have to |
| 1400 | * make sure we don't insert a duplicate uidinfo. |
| 1401 | */ |
| 1402 | if ((uip = uilookup(uid)) == NULL) { |
| 1403 | LIST_INSERT_HEAD(UIHASH(uid), new_uip, ui_hash); |
| 1404 | rw_wunlock(&uihashtbl_lock); |
| 1405 | uip = new_uip; |
| 1406 | } else { |
| 1407 | rw_wunlock(&uihashtbl_lock); |
| 1408 | racct_destroy(&new_uip->ui_racct); |
| 1409 | free(new_uip, M_UIDINFO); |
| 1410 | } |
| 1411 | return (uip); |
| 1412 | } |
| 1413 | |
| 1414 | /* |
| 1415 | * Place another refcount on a uidinfo struct. |
no test coverage detected