Lines 557-564
Link Here
|
557 |
void *op; |
557 |
void *op; |
558 |
#endif |
558 |
#endif |
559 |
unsigned long hid; |
559 |
unsigned long hid; |
560 |
size_t namelen, onamelen; |
560 |
size_t namelen, onamelen, pnamelen; |
561 |
int created, cuflags, descend, enforce, error, errmsg_len, errmsg_pos; |
561 |
int born, created, cuflags, descend, enforce; |
|
|
562 |
int error, errmsg_len, errmsg_pos; |
562 |
int gotchildmax, gotenforce, gothid, gotrsnum, gotslevel; |
563 |
int gotchildmax, gotenforce, gothid, gotrsnum, gotslevel; |
563 |
int fi, jid, jsys, len, level; |
564 |
int fi, jid, jsys, len, level; |
564 |
int childmax, osreldt, rsnum, slevel; |
565 |
int childmax, osreldt, rsnum, slevel; |
Lines 581-587
Link Here
|
581 |
error = priv_check(td, PRIV_JAIL_ATTACH); |
582 |
error = priv_check(td, PRIV_JAIL_ATTACH); |
582 |
if (error) |
583 |
if (error) |
583 |
return (error); |
584 |
return (error); |
584 |
mypr = ppr = td->td_ucred->cr_prison; |
585 |
mypr = td->td_ucred->cr_prison; |
585 |
if ((flags & JAIL_CREATE) && mypr->pr_childmax == 0) |
586 |
if ((flags & JAIL_CREATE) && mypr->pr_childmax == 0) |
586 |
return (EPERM); |
587 |
return (EPERM); |
587 |
if (flags & ~JAIL_SET_MASK) |
588 |
if (flags & ~JAIL_SET_MASK) |
Lines 608-613
Link Here
|
608 |
#endif |
609 |
#endif |
609 |
g_path = NULL; |
610 |
g_path = NULL; |
610 |
|
611 |
|
|
|
612 |
cuflags = flags & (JAIL_CREATE | JAIL_UPDATE); |
613 |
if (!cuflags) { |
614 |
error = EINVAL; |
615 |
vfs_opterror(opts, "no valid operation (create or update)"); |
616 |
goto done_errmsg; |
617 |
} |
618 |
|
611 |
error = vfs_copyopt(opts, "jid", &jid, sizeof(jid)); |
619 |
error = vfs_copyopt(opts, "jid", &jid, sizeof(jid)); |
612 |
if (error == ENOENT) |
620 |
if (error == ENOENT) |
613 |
jid = 0; |
621 |
jid = 0; |
Lines 1013-1048
Link Here
|
1013 |
} |
1021 |
} |
1014 |
|
1022 |
|
1015 |
/* |
1023 |
/* |
1016 |
* Grab the allprison lock before letting modules check their |
1024 |
* Find the specified jail, or at least its parent. |
1017 |
* parameters. Once we have it, do not let go so we'll have a |
|
|
1018 |
* consistent view of the OSD list. |
1019 |
*/ |
1020 |
sx_xlock(&allprison_lock); |
1021 |
error = osd_jail_call(NULL, PR_METHOD_CHECK, opts); |
1022 |
if (error) |
1023 |
goto done_unlock_list; |
1024 |
|
1025 |
/* By now, all parameters should have been noted. */ |
1026 |
TAILQ_FOREACH(opt, opts, link) { |
1027 |
if (!opt->seen && strcmp(opt->name, "errmsg")) { |
1028 |
error = EINVAL; |
1029 |
vfs_opterror(opts, "unknown parameter: %s", opt->name); |
1030 |
goto done_unlock_list; |
1031 |
} |
1032 |
} |
1033 |
|
1034 |
/* |
1035 |
* See if we are creating a new record or updating an existing one. |
1036 |
* This abuses the file error codes ENOENT and EEXIST. |
1025 |
* This abuses the file error codes ENOENT and EEXIST. |
1037 |
*/ |
1026 |
*/ |
1038 |
cuflags = flags & (JAIL_CREATE | JAIL_UPDATE); |
|
|
1039 |
if (!cuflags) { |
1040 |
error = EINVAL; |
1041 |
vfs_opterror(opts, "no valid operation (create or update)"); |
1042 |
goto done_unlock_list; |
1043 |
} |
1044 |
pr = NULL; |
1027 |
pr = NULL; |
1045 |
namelc = NULL; |
1028 |
ppr = mypr; |
1046 |
if (cuflags == JAIL_CREATE && jid == 0 && name != NULL) { |
1029 |
if (cuflags == JAIL_CREATE && jid == 0 && name != NULL) { |
1047 |
namelc = strrchr(name, '.'); |
1030 |
namelc = strrchr(name, '.'); |
1048 |
jid = strtoul(namelc != NULL ? namelc + 1 : name, &p, 10); |
1031 |
jid = strtoul(namelc != NULL ? namelc + 1 : name, &p, 10); |
Lines 1049-1054
Link Here
|
1049 |
if (*p != '\0') |
1032 |
if (*p != '\0') |
1050 |
jid = 0; |
1033 |
jid = 0; |
1051 |
} |
1034 |
} |
|
|
1035 |
sx_xlock(&allprison_lock); |
1052 |
if (jid != 0) { |
1036 |
if (jid != 0) { |
1053 |
/* |
1037 |
/* |
1054 |
* See if a requested jid already exists. There is an |
1038 |
* See if a requested jid already exists. There is an |
Lines 1114-1119
Link Here
|
1114 |
* and updates keyed by the name itself (where the name must exist |
1098 |
* and updates keyed by the name itself (where the name must exist |
1115 |
* because that is the jail being updated). |
1099 |
* because that is the jail being updated). |
1116 |
*/ |
1100 |
*/ |
|
|
1101 |
namelc = NULL; |
1117 |
if (name != NULL) { |
1102 |
if (name != NULL) { |
1118 |
namelc = strrchr(name, '.'); |
1103 |
namelc = strrchr(name, '.'); |
1119 |
if (namelc == NULL) |
1104 |
if (namelc == NULL) |
Lines 1124-1130
Link Here
|
1124 |
* parent and child names, and make sure the parent |
1109 |
* parent and child names, and make sure the parent |
1125 |
* exists or matches an already found jail. |
1110 |
* exists or matches an already found jail. |
1126 |
*/ |
1111 |
*/ |
1127 |
*namelc = '\0'; |
|
|
1128 |
if (pr != NULL) { |
1112 |
if (pr != NULL) { |
1129 |
if (strncmp(name, ppr->pr_name, namelc - name) |
1113 |
if (strncmp(name, ppr->pr_name, namelc - name) |
1130 |
|| ppr->pr_name[namelc - name] != '\0') { |
1114 |
|| ppr->pr_name[namelc - name] != '\0') { |
Lines 1135-1140
Link Here
|
1135 |
goto done_unlock_list; |
1119 |
goto done_unlock_list; |
1136 |
} |
1120 |
} |
1137 |
} else { |
1121 |
} else { |
|
|
1122 |
*namelc = '\0'; |
1138 |
ppr = prison_find_name(mypr, name); |
1123 |
ppr = prison_find_name(mypr, name); |
1139 |
if (ppr == NULL) { |
1124 |
if (ppr == NULL) { |
1140 |
error = ENOENT; |
1125 |
error = ENOENT; |
Lines 1143-1159
Link Here
|
1143 |
goto done_unlock_list; |
1128 |
goto done_unlock_list; |
1144 |
} |
1129 |
} |
1145 |
mtx_unlock(&ppr->pr_mtx); |
1130 |
mtx_unlock(&ppr->pr_mtx); |
|
|
1131 |
*namelc = '.'; |
1146 |
} |
1132 |
} |
1147 |
name = ++namelc; |
1133 |
namelc++; |
1148 |
} |
1134 |
} |
1149 |
if (name[0] != '\0') { |
1135 |
if (namelc[0] != '\0') { |
1150 |
namelen = |
1136 |
pnamelen = |
1151 |
(ppr == &prison0) ? 0 : strlen(ppr->pr_name) + 1; |
1137 |
(ppr == &prison0) ? 0 : strlen(ppr->pr_name) + 1; |
1152 |
name_again: |
1138 |
name_again: |
1153 |
deadpr = NULL; |
1139 |
deadpr = NULL; |
1154 |
FOREACH_PRISON_CHILD(ppr, tpr) { |
1140 |
FOREACH_PRISON_CHILD(ppr, tpr) { |
1155 |
if (tpr != pr && tpr->pr_ref > 0 && |
1141 |
if (tpr != pr && tpr->pr_ref > 0 && |
1156 |
!strcmp(tpr->pr_name + namelen, name)) { |
1142 |
!strcmp(tpr->pr_name + pnamelen, namelc)) { |
1157 |
if (pr == NULL && |
1143 |
if (pr == NULL && |
1158 |
cuflags != JAIL_CREATE) { |
1144 |
cuflags != JAIL_CREATE) { |
1159 |
mtx_lock(&tpr->pr_mtx); |
1145 |
mtx_lock(&tpr->pr_mtx); |
Lines 1227-1236
Link Here
|
1227 |
} |
1213 |
} |
1228 |
created = 1; |
1214 |
created = 1; |
1229 |
mtx_lock(&ppr->pr_mtx); |
1215 |
mtx_lock(&ppr->pr_mtx); |
1230 |
if (ppr->pr_ref == 0 || (ppr->pr_flags & PR_REMOVE)) { |
1216 |
if (ppr->pr_ref == 0) { |
1231 |
mtx_unlock(&ppr->pr_mtx); |
1217 |
mtx_unlock(&ppr->pr_mtx); |
1232 |
error = ENOENT; |
1218 |
error = ENOENT; |
1233 |
vfs_opterror(opts, "parent jail went away!"); |
1219 |
vfs_opterror(opts, "jail \"%s\" not found", |
|
|
1220 |
prison_name(mypr, ppr)); |
1234 |
goto done_unlock_list; |
1221 |
goto done_unlock_list; |
1235 |
} |
1222 |
} |
1236 |
ppr->pr_ref++; |
1223 |
ppr->pr_ref++; |
Lines 1284-1291
Link Here
|
1284 |
pr->pr_id = jid; |
1271 |
pr->pr_id = jid; |
1285 |
|
1272 |
|
1286 |
/* Set some default values, and inherit some from the parent. */ |
1273 |
/* Set some default values, and inherit some from the parent. */ |
1287 |
if (name == NULL) |
1274 |
if (namelc == NULL) |
1288 |
name = ""; |
1275 |
namelc = ""; |
1289 |
if (path == NULL) { |
1276 |
if (path == NULL) { |
1290 |
path = "/"; |
1277 |
path = "/"; |
1291 |
root = mypr->pr_root; |
1278 |
root = mypr->pr_root; |
Lines 1365-1371
Link Here
|
1365 |
mtx_lock(&pr->pr_mtx); |
1352 |
mtx_lock(&pr->pr_mtx); |
1366 |
/* |
1353 |
/* |
1367 |
* New prisons do not yet have a reference, because we do not |
1354 |
* New prisons do not yet have a reference, because we do not |
1368 |
* want other to see the incomplete prison once the |
1355 |
* want others to see the incomplete prison once the |
1369 |
* allprison_lock is downgraded. |
1356 |
* allprison_lock is downgraded. |
1370 |
*/ |
1357 |
*/ |
1371 |
} else { |
1358 |
} else { |
Lines 1579-1591
Link Here
|
1579 |
} |
1566 |
} |
1580 |
#endif |
1567 |
#endif |
1581 |
onamelen = namelen = 0; |
1568 |
onamelen = namelen = 0; |
1582 |
if (name != NULL) { |
1569 |
if (namelc != NULL) { |
1583 |
/* Give a default name of the jid. Also allow the name to be |
1570 |
/* Give a default name of the jid. Also allow the name to be |
1584 |
* explicitly the jid - but not any other number, and only in |
1571 |
* explicitly the jid - but not any other number, and only in |
1585 |
* normal form (no leading zero/etc). |
1572 |
* normal form (no leading zero/etc). |
1586 |
*/ |
1573 |
*/ |
1587 |
if (name[0] == '\0') |
1574 |
if (namelc[0] == '\0') |
1588 |
snprintf(name = numbuf, sizeof(numbuf), "%d", jid); |
1575 |
snprintf(namelc = numbuf, sizeof(numbuf), "%d", jid); |
1589 |
else if ((strtoul(namelc, &p, 10) != jid || |
1576 |
else if ((strtoul(namelc, &p, 10) != jid || |
1590 |
namelc[0] < '1' || namelc[0] > '9') && *p == '\0') { |
1577 |
namelc[0] < '1' || namelc[0] > '9') && *p == '\0') { |
1591 |
error = EINVAL; |
1578 |
error = EINVAL; |
Lines 1597-1605
Link Here
|
1597 |
* Make sure the name isn't too long for the prison or its |
1584 |
* Make sure the name isn't too long for the prison or its |
1598 |
* children. |
1585 |
* children. |
1599 |
*/ |
1586 |
*/ |
1600 |
onamelen = strlen(pr->pr_name); |
1587 |
pnamelen = (ppr == &prison0) ? 0 : strlen(ppr->pr_name) + 1; |
1601 |
namelen = strlen(name); |
1588 |
onamelen = strlen(pr->pr_name + pnamelen); |
1602 |
if (strlen(ppr->pr_name) + namelen + 2 > sizeof(pr->pr_name)) { |
1589 |
namelen = strlen(namelc); |
|
|
1590 |
if (pnamelen + namelen + 1 > sizeof(pr->pr_name)) { |
1603 |
error = ENAMETOOLONG; |
1591 |
error = ENAMETOOLONG; |
1604 |
goto done_deref_locked; |
1592 |
goto done_deref_locked; |
1605 |
} |
1593 |
} |
Lines 1616-1621
Link Here
|
1616 |
goto done_deref_locked; |
1604 |
goto done_deref_locked; |
1617 |
} |
1605 |
} |
1618 |
|
1606 |
|
|
|
1607 |
/* |
1608 |
* Let modules check their parameters. This requires unlocking and |
1609 |
* then re-locking the prison, but this is still a valid state as long |
1610 |
* as allprison_lock remains xlocked. |
1611 |
*/ |
1612 |
mtx_unlock(&pr->pr_mtx); |
1613 |
error = osd_jail_call(pr, PR_METHOD_CHECK, opts); |
1614 |
if (error != 0) { |
1615 |
prison_deref(pr, created |
1616 |
? PD_LIST_XLOCKED |
1617 |
: PD_DEREF | PD_LIST_XLOCKED); |
1618 |
goto done_releroot; |
1619 |
} |
1620 |
mtx_lock(&pr->pr_mtx); |
1621 |
|
1622 |
/* At this point, all valid parameters should have been noted. */ |
1623 |
TAILQ_FOREACH(opt, opts, link) { |
1624 |
if (!opt->seen && strcmp(opt->name, "errmsg")) { |
1625 |
error = EINVAL; |
1626 |
vfs_opterror(opts, "unknown parameter: %s", opt->name); |
1627 |
goto done_deref_locked; |
1628 |
} |
1629 |
} |
1630 |
|
1619 |
/* Set the parameters of the prison. */ |
1631 |
/* Set the parameters of the prison. */ |
1620 |
#ifdef INET |
1632 |
#ifdef INET |
1621 |
redo_ip4 = 0; |
1633 |
redo_ip4 = 0; |
Lines 1689-1700
Link Here
|
1689 |
FOREACH_PRISON_DESCENDANT_LOCKED(pr, tpr, descend) |
1701 |
FOREACH_PRISON_DESCENDANT_LOCKED(pr, tpr, descend) |
1690 |
tpr->pr_devfs_rsnum = rsnum; |
1702 |
tpr->pr_devfs_rsnum = rsnum; |
1691 |
} |
1703 |
} |
1692 |
if (name != NULL) { |
1704 |
if (namelc != NULL) { |
1693 |
if (ppr == &prison0) |
1705 |
if (ppr == &prison0) |
1694 |
strlcpy(pr->pr_name, name, sizeof(pr->pr_name)); |
1706 |
strlcpy(pr->pr_name, namelc, sizeof(pr->pr_name)); |
1695 |
else |
1707 |
else |
1696 |
snprintf(pr->pr_name, sizeof(pr->pr_name), "%s.%s", |
1708 |
snprintf(pr->pr_name, sizeof(pr->pr_name), "%s.%s", |
1697 |
ppr->pr_name, name); |
1709 |
ppr->pr_name, namelc); |
1698 |
/* Change this component of child names. */ |
1710 |
/* Change this component of child names. */ |
1699 |
FOREACH_PRISON_DESCENDANT_LOCKED(pr, tpr, descend) { |
1711 |
FOREACH_PRISON_DESCENDANT_LOCKED(pr, tpr, descend) { |
1700 |
bcopy(tpr->pr_name + onamelen, tpr->pr_name + namelen, |
1712 |
bcopy(tpr->pr_name + onamelen, tpr->pr_name + namelen, |
Lines 1772-1777
Link Here
|
1772 |
* for now, so new ones will remain unseen until after the module |
1784 |
* for now, so new ones will remain unseen until after the module |
1773 |
* handlers have completed. |
1785 |
* handlers have completed. |
1774 |
*/ |
1786 |
*/ |
|
|
1787 |
born = pr->pr_uref == 0; |
1775 |
if (!created && (ch_flags & PR_PERSIST & (pr_flags ^ pr->pr_flags))) { |
1788 |
if (!created && (ch_flags & PR_PERSIST & (pr_flags ^ pr->pr_flags))) { |
1776 |
if (pr_flags & PR_PERSIST) { |
1789 |
if (pr_flags & PR_PERSIST) { |
1777 |
pr->pr_ref++; |
1790 |
pr->pr_ref++; |
Lines 1841-1855
Link Here
|
1841 |
|
1854 |
|
1842 |
/* Let the modules do their work. */ |
1855 |
/* Let the modules do their work. */ |
1843 |
sx_downgrade(&allprison_lock); |
1856 |
sx_downgrade(&allprison_lock); |
1844 |
if (created) { |
1857 |
if (born) { |
1845 |
error = osd_jail_call(pr, PR_METHOD_CREATE, opts); |
1858 |
error = osd_jail_call(pr, PR_METHOD_CREATE, opts); |
1846 |
if (error) { |
1859 |
if (error) { |
1847 |
prison_deref(pr, PD_LIST_SLOCKED); |
1860 |
(void)osd_jail_call(pr, PR_METHOD_REMOVE, NULL); |
|
|
1861 |
prison_deref(pr, created |
1862 |
? PD_LIST_SLOCKED |
1863 |
: PD_DEREF | PD_LIST_SLOCKED); |
1848 |
goto done_errmsg; |
1864 |
goto done_errmsg; |
1849 |
} |
1865 |
} |
1850 |
} |
1866 |
} |
1851 |
error = osd_jail_call(pr, PR_METHOD_SET, opts); |
1867 |
error = osd_jail_call(pr, PR_METHOD_SET, opts); |
1852 |
if (error) { |
1868 |
if (error) { |
|
|
1869 |
if (born) |
1870 |
(void)osd_jail_call(pr, PR_METHOD_REMOVE, NULL); |
1853 |
prison_deref(pr, created |
1871 |
prison_deref(pr, created |
1854 |
? PD_LIST_SLOCKED |
1872 |
? PD_LIST_SLOCKED |
1855 |
: PD_DEREF | PD_LIST_SLOCKED); |
1873 |
: PD_DEREF | PD_LIST_SLOCKED); |
Lines 1901-1907
Link Here
|
1901 |
sx_sunlock(&allprison_lock); |
1919 |
sx_sunlock(&allprison_lock); |
1902 |
} |
1920 |
} |
1903 |
|
1921 |
|
1904 |
goto done_errmsg; |
1922 |
goto done_free; |
1905 |
|
1923 |
|
1906 |
done_deref_locked: |
1924 |
done_deref_locked: |
1907 |
prison_deref(pr, created |
1925 |
prison_deref(pr, created |
Lines 2281-2287
Link Here
|
2281 |
|
2299 |
|
2282 |
/* Remove all descendants of this prison, then remove this prison. */ |
2300 |
/* Remove all descendants of this prison, then remove this prison. */ |
2283 |
pr->pr_ref++; |
2301 |
pr->pr_ref++; |
2284 |
pr->pr_flags |= PR_REMOVE; |
|
|
2285 |
if (!LIST_EMPTY(&pr->pr_children)) { |
2302 |
if (!LIST_EMPTY(&pr->pr_children)) { |
2286 |
mtx_unlock(&pr->pr_mtx); |
2303 |
mtx_unlock(&pr->pr_mtx); |
2287 |
lpr = NULL; |
2304 |
lpr = NULL; |
Lines 2290-2296
Link Here
|
2290 |
if (cpr->pr_ref > 0) { |
2307 |
if (cpr->pr_ref > 0) { |
2291 |
tpr = cpr; |
2308 |
tpr = cpr; |
2292 |
cpr->pr_ref++; |
2309 |
cpr->pr_ref++; |
2293 |
cpr->pr_flags |= PR_REMOVE; |
|
|
2294 |
} else { |
2310 |
} else { |
2295 |
/* Already removed - do not do it again. */ |
2311 |
/* Already removed - do not do it again. */ |
2296 |
tpr = NULL; |
2312 |
tpr = NULL; |
Lines 2606-2611
Link Here
|
2606 |
prison_deref(struct prison *pr, int flags) |
2622 |
prison_deref(struct prison *pr, int flags) |
2607 |
{ |
2623 |
{ |
2608 |
struct prison *ppr, *tpr; |
2624 |
struct prison *ppr, *tpr; |
|
|
2625 |
int ref, lasturef; |
2609 |
|
2626 |
|
2610 |
if (!(flags & PD_LOCKED)) |
2627 |
if (!(flags & PD_LOCKED)) |
2611 |
mtx_lock(&pr->pr_mtx); |
2628 |
mtx_lock(&pr->pr_mtx); |
Lines 2612-2624
Link Here
|
2612 |
for (;;) { |
2629 |
for (;;) { |
2613 |
if (flags & PD_DEUREF) { |
2630 |
if (flags & PD_DEUREF) { |
2614 |
pr->pr_uref--; |
2631 |
pr->pr_uref--; |
|
|
2632 |
lasturef = pr->pr_uref == 0; |
2633 |
if (lasturef) |
2634 |
pr->pr_ref++; |
2615 |
KASSERT(prison0.pr_uref != 0, ("prison0 pr_uref=0")); |
2635 |
KASSERT(prison0.pr_uref != 0, ("prison0 pr_uref=0")); |
2616 |
} |
2636 |
} else |
|
|
2637 |
lasturef = 0; |
2617 |
if (flags & PD_DEREF) |
2638 |
if (flags & PD_DEREF) |
2618 |
pr->pr_ref--; |
2639 |
pr->pr_ref--; |
|
|
2640 |
ref = pr->pr_ref; |
2641 |
mtx_unlock(&pr->pr_mtx); |
2642 |
|
2643 |
/* |
2644 |
* Tell the modules if the last user reference was removed |
2645 |
* (even it sticks around in dying state). |
2646 |
*/ |
2647 |
if (lasturef) { |
2648 |
if (!(flags & (PD_LIST_SLOCKED | PD_LIST_XLOCKED))) { |
2649 |
if (ref > 1) { |
2650 |
sx_slock(&allprison_lock); |
2651 |
flags |= PD_LIST_SLOCKED; |
2652 |
} else { |
2653 |
sx_xlock(&allprison_lock); |
2654 |
flags |= PD_LIST_XLOCKED; |
2655 |
} |
2656 |
} |
2657 |
(void)osd_jail_call(pr, PR_METHOD_REMOVE, NULL); |
2658 |
mtx_lock(&pr->pr_mtx); |
2659 |
ref = --pr->pr_ref; |
2660 |
mtx_unlock(&pr->pr_mtx); |
2661 |
} |
2662 |
|
2619 |
/* If the prison still has references, nothing else to do. */ |
2663 |
/* If the prison still has references, nothing else to do. */ |
2620 |
if (pr->pr_ref > 0) { |
2664 |
if (ref > 0) { |
2621 |
mtx_unlock(&pr->pr_mtx); |
|
|
2622 |
if (flags & PD_LIST_SLOCKED) |
2665 |
if (flags & PD_LIST_SLOCKED) |
2623 |
sx_sunlock(&allprison_lock); |
2666 |
sx_sunlock(&allprison_lock); |
2624 |
else if (flags & PD_LIST_XLOCKED) |
2667 |
else if (flags & PD_LIST_XLOCKED) |
Lines 2626-2632
Link Here
|
2626 |
return; |
2669 |
return; |
2627 |
} |
2670 |
} |
2628 |
|
2671 |
|
2629 |
mtx_unlock(&pr->pr_mtx); |
|
|
2630 |
if (flags & PD_LIST_SLOCKED) { |
2672 |
if (flags & PD_LIST_SLOCKED) { |
2631 |
if (!sx_try_upgrade(&allprison_lock)) { |
2673 |
if (!sx_try_upgrade(&allprison_lock)) { |
2632 |
sx_sunlock(&allprison_lock); |
2674 |
sx_sunlock(&allprison_lock); |