Deleted Added
full compact
uipc_usrreq.c (87821) uipc_usrreq.c (89306)
1/*
2 * Copyright (c) 1982, 1986, 1989, 1991, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 17 unchanged lines hidden (view full) ---

26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 *
33 * From: @(#)uipc_usrreq.c 8.3 (Berkeley) 1/4/94
1/*
2 * Copyright (c) 1982, 1986, 1989, 1991, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 17 unchanged lines hidden (view full) ---

26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 *
33 * From: @(#)uipc_usrreq.c 8.3 (Berkeley) 1/4/94
34 * $FreeBSD: head/sys/kern/uipc_usrreq.c 87821 2001-12-13 22:09:37Z rwatson $
34 * $FreeBSD: head/sys/kern/uipc_usrreq.c 89306 2002-01-13 11:58:06Z alfred $
35 */
36
37#include <sys/param.h>
38#include <sys/systm.h>
39#include <sys/kernel.h>
40#include <sys/fcntl.h>
41#include <sys/domain.h>
42#include <sys/filedesc.h>

--- 9 unchanged lines hidden (view full) ---

52#include <sys/socketvar.h>
53#include <sys/resourcevar.h>
54#include <sys/stat.h>
55#include <sys/sysctl.h>
56#include <sys/un.h>
57#include <sys/unpcb.h>
58#include <sys/vnode.h>
59#include <sys/jail.h>
35 */
36
37#include <sys/param.h>
38#include <sys/systm.h>
39#include <sys/kernel.h>
40#include <sys/fcntl.h>
41#include <sys/domain.h>
42#include <sys/filedesc.h>

--- 9 unchanged lines hidden (view full) ---

52#include <sys/socketvar.h>
53#include <sys/resourcevar.h>
54#include <sys/stat.h>
55#include <sys/sysctl.h>
56#include <sys/un.h>
57#include <sys/unpcb.h>
58#include <sys/vnode.h>
59#include <sys/jail.h>
60#include <sys/sx.h>
60
61#include <vm/vm_zone.h>
62
63static struct vm_zone *unp_zone;
64static unp_gen_t unp_gencnt;
65static u_int unp_count;
66
67static struct unp_head unp_shead, unp_dhead;

--- 462 unchanged lines hidden (view full) ---

530 unp = zalloc(unp_zone);
531 if (unp == NULL)
532 return (ENOBUFS);
533 bzero(unp, sizeof *unp);
534 unp->unp_gencnt = ++unp_gencnt;
535 unp_count++;
536 LIST_INIT(&unp->unp_refs);
537 unp->unp_socket = so;
61
62#include <vm/vm_zone.h>
63
64static struct vm_zone *unp_zone;
65static unp_gen_t unp_gencnt;
66static u_int unp_count;
67
68static struct unp_head unp_shead, unp_dhead;

--- 462 unchanged lines hidden (view full) ---

531 unp = zalloc(unp_zone);
532 if (unp == NULL)
533 return (ENOBUFS);
534 bzero(unp, sizeof *unp);
535 unp->unp_gencnt = ++unp_gencnt;
536 unp_count++;
537 LIST_INIT(&unp->unp_refs);
538 unp->unp_socket = so;
539 FILEDESC_LOCK(curproc->p_fd);
538 unp->unp_rvnode = curthread->td_proc->p_fd->fd_rdir;
540 unp->unp_rvnode = curthread->td_proc->p_fd->fd_rdir;
541 FILEDESC_UNLOCK(curproc->p_fd);
539 LIST_INSERT_HEAD(so->so_type == SOCK_DGRAM ? &unp_dhead
540 : &unp_shead, unp, unp_link);
541 so->so_pcb = (caddr_t)unp;
542 return (0);
543}
544
545static void
546unp_detach(unp)

--- 76 unchanged lines hidden (view full) ---

623 if (error) {
624 free(buf, M_TEMP);
625 return (error);
626 }
627 goto restart;
628 }
629 VATTR_NULL(&vattr);
630 vattr.va_type = VSOCK;
542 LIST_INSERT_HEAD(so->so_type == SOCK_DGRAM ? &unp_dhead
543 : &unp_shead, unp, unp_link);
544 so->so_pcb = (caddr_t)unp;
545 return (0);
546}
547
548static void
549unp_detach(unp)

--- 76 unchanged lines hidden (view full) ---

626 if (error) {
627 free(buf, M_TEMP);
628 return (error);
629 }
630 goto restart;
631 }
632 VATTR_NULL(&vattr);
633 vattr.va_type = VSOCK;
634 FILEDESC_LOCK(td->td_proc->p_fd);
631 vattr.va_mode = (ACCESSPERMS & ~td->td_proc->p_fd->fd_cmask);
635 vattr.va_mode = (ACCESSPERMS & ~td->td_proc->p_fd->fd_cmask);
636 FILEDESC_UNLOCK(td->td_proc->p_fd);
632 VOP_LEASE(nd.ni_dvp, td, td->td_proc->p_ucred, LEASE_WRITE);
633 error = VOP_CREATE(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr);
634 NDFREE(&nd, NDF_ONLY_PNBUF);
635 vput(nd.ni_dvp);
636 if (error) {
637 free(buf, M_TEMP);
638 return (error);
639 }

--- 361 unchanged lines hidden (view full) ---

1001 newfds = datalen / sizeof(struct file *);
1002 rp = data;
1003
1004 /* If we're not outputting the discriptors free them. */
1005 if (error || controlp == NULL) {
1006 unp_freerights(rp, newfds);
1007 goto next;
1008 }
637 VOP_LEASE(nd.ni_dvp, td, td->td_proc->p_ucred, LEASE_WRITE);
638 error = VOP_CREATE(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr);
639 NDFREE(&nd, NDF_ONLY_PNBUF);
640 vput(nd.ni_dvp);
641 if (error) {
642 free(buf, M_TEMP);
643 return (error);
644 }

--- 361 unchanged lines hidden (view full) ---

1006 newfds = datalen / sizeof(struct file *);
1007 rp = data;
1008
1009 /* If we're not outputting the discriptors free them. */
1010 if (error || controlp == NULL) {
1011 unp_freerights(rp, newfds);
1012 goto next;
1013 }
1014 FILEDESC_LOCK(td->td_proc->p_fd);
1009 /* if the new FD's will not fit free them. */
1010 if (!fdavail(td, newfds)) {
1015 /* if the new FD's will not fit free them. */
1016 if (!fdavail(td, newfds)) {
1017 FILEDESC_UNLOCK(td->td_proc->p_fd);
1011 error = EMSGSIZE;
1012 unp_freerights(rp, newfds);
1013 goto next;
1014 }
1015 /*
1016 * now change each pointer to an fd in the global
1017 * table to an integer that is the index to the
1018 * local fd table entry that we set up to point
1019 * to the global one we are transferring.
1020 */
1021 newlen = newfds * sizeof(int);
1022 *controlp = sbcreatecontrol(NULL, newlen,
1023 SCM_RIGHTS, SOL_SOCKET);
1024 if (*controlp == NULL) {
1018 error = EMSGSIZE;
1019 unp_freerights(rp, newfds);
1020 goto next;
1021 }
1022 /*
1023 * now change each pointer to an fd in the global
1024 * table to an integer that is the index to the
1025 * local fd table entry that we set up to point
1026 * to the global one we are transferring.
1027 */
1028 newlen = newfds * sizeof(int);
1029 *controlp = sbcreatecontrol(NULL, newlen,
1030 SCM_RIGHTS, SOL_SOCKET);
1031 if (*controlp == NULL) {
1032 FILEDESC_UNLOCK(td->td_proc->p_fd);
1025 error = E2BIG;
1026 unp_freerights(rp, newfds);
1027 goto next;
1028 }
1029
1030 fdp = (int *)
1031 CMSG_DATA(mtod(*controlp, struct cmsghdr *));
1032 for (i = 0; i < newfds; i++) {
1033 if (fdalloc(td, 0, &f))
1034 panic("unp_externalize fdalloc failed");
1035 fp = *rp++;
1036 td->td_proc->p_fd->fd_ofiles[f] = fp;
1033 error = E2BIG;
1034 unp_freerights(rp, newfds);
1035 goto next;
1036 }
1037
1038 fdp = (int *)
1039 CMSG_DATA(mtod(*controlp, struct cmsghdr *));
1040 for (i = 0; i < newfds; i++) {
1041 if (fdalloc(td, 0, &f))
1042 panic("unp_externalize fdalloc failed");
1043 fp = *rp++;
1044 td->td_proc->p_fd->fd_ofiles[f] = fp;
1045 FILE_LOCK(fp);
1037 fp->f_msgcount--;
1046 fp->f_msgcount--;
1047 FILE_UNLOCK(fp);
1038 unp_rights--;
1039 *fdp++ = f;
1040 }
1048 unp_rights--;
1049 *fdp++ = f;
1050 }
1051 FILEDESC_UNLOCK(td->td_proc->p_fd);
1041 } else { /* We can just copy anything else across */
1042 if (error || controlp == NULL)
1043 goto next;
1044 *controlp = sbcreatecontrol(NULL, datalen,
1045 cm->cmsg_type, cm->cmsg_level);
1046 if (*controlp == NULL) {
1047 error = ENOBUFS;
1048 goto next;

--- 10 unchanged lines hidden (view full) ---

1059 clen -= CMSG_SPACE(datalen);
1060 cm = (struct cmsghdr *)
1061 ((caddr_t)cm + CMSG_SPACE(datalen));
1062 } else {
1063 clen = 0;
1064 cm = NULL;
1065 }
1066 }
1052 } else { /* We can just copy anything else across */
1053 if (error || controlp == NULL)
1054 goto next;
1055 *controlp = sbcreatecontrol(NULL, datalen,
1056 cm->cmsg_type, cm->cmsg_level);
1057 if (*controlp == NULL) {
1058 error = ENOBUFS;
1059 goto next;

--- 10 unchanged lines hidden (view full) ---

1070 clen -= CMSG_SPACE(datalen);
1071 cm = (struct cmsghdr *)
1072 ((caddr_t)cm + CMSG_SPACE(datalen));
1073 } else {
1074 clen = 0;
1075 cm = NULL;
1076 }
1077 }
1078 FILEDESC_UNLOCK(td->td_proc->p_fd);
1067
1068 m_freem(control);
1069
1070 return (error);
1071}
1072
1073void
1074unp_init(void)

--- 68 unchanged lines hidden (view full) ---

1143
1144 case SCM_RIGHTS:
1145 oldfds = datalen / sizeof (int);
1146 /*
1147 * check that all the FDs passed in refer to legal files
1148 * If not, reject the entire operation.
1149 */
1150 fdp = data;
1079
1080 m_freem(control);
1081
1082 return (error);
1083}
1084
1085void
1086unp_init(void)

--- 68 unchanged lines hidden (view full) ---

1155
1156 case SCM_RIGHTS:
1157 oldfds = datalen / sizeof (int);
1158 /*
1159 * check that all the FDs passed in refer to legal files
1160 * If not, reject the entire operation.
1161 */
1162 fdp = data;
1163 FILEDESC_LOCK(fdescp);
1151 for (i = 0; i < oldfds; i++) {
1152 fd = *fdp++;
1153 if ((unsigned)fd >= fdescp->fd_nfiles ||
1154 fdescp->fd_ofiles[fd] == NULL) {
1164 for (i = 0; i < oldfds; i++) {
1165 fd = *fdp++;
1166 if ((unsigned)fd >= fdescp->fd_nfiles ||
1167 fdescp->fd_ofiles[fd] == NULL) {
1168 FILEDESC_UNLOCK(fdescp);
1155 error = EBADF;
1156 goto out;
1157 }
1158 }
1159 /*
1160 * Now replace the integer FDs with pointers to
1161 * the associated global file table entry..
1162 */
1163 newlen = oldfds * sizeof(struct file *);
1164 *controlp = sbcreatecontrol(NULL, newlen,
1165 SCM_RIGHTS, SOL_SOCKET);
1166 if (*controlp == NULL) {
1169 error = EBADF;
1170 goto out;
1171 }
1172 }
1173 /*
1174 * Now replace the integer FDs with pointers to
1175 * the associated global file table entry..
1176 */
1177 newlen = oldfds * sizeof(struct file *);
1178 *controlp = sbcreatecontrol(NULL, newlen,
1179 SCM_RIGHTS, SOL_SOCKET);
1180 if (*controlp == NULL) {
1181 FILEDESC_UNLOCK(fdescp);
1167 error = E2BIG;
1168 goto out;
1169 }
1170
1171 fdp = data;
1172 rp = (struct file **)
1173 CMSG_DATA(mtod(*controlp, struct cmsghdr *));
1174 for (i = 0; i < oldfds; i++) {
1175 fp = fdescp->fd_ofiles[*fdp++];
1176 *rp++ = fp;
1182 error = E2BIG;
1183 goto out;
1184 }
1185
1186 fdp = data;
1187 rp = (struct file **)
1188 CMSG_DATA(mtod(*controlp, struct cmsghdr *));
1189 for (i = 0; i < oldfds; i++) {
1190 fp = fdescp->fd_ofiles[*fdp++];
1191 *rp++ = fp;
1192 FILE_LOCK(fp);
1177 fp->f_count++;
1178 fp->f_msgcount++;
1193 fp->f_count++;
1194 fp->f_msgcount++;
1195 FILE_UNLOCK(fp);
1179 unp_rights++;
1180 }
1196 unp_rights++;
1197 }
1198 FILEDESC_UNLOCK(fdescp);
1181 break;
1182
1183 case SCM_TIMESTAMP:
1184 *controlp = sbcreatecontrol(NULL, sizeof(*tv),
1185 SCM_TIMESTAMP, SOL_SOCKET);
1186 if (*controlp == NULL) {
1187 error = ENOBUFS;
1188 goto out;

--- 39 unchanged lines hidden (view full) ---

1228 if (unp_gcing)
1229 return;
1230 unp_gcing = 1;
1231 unp_defer = 0;
1232 /*
1233 * before going through all this, set all FDs to
1234 * be NOT defered and NOT externally accessible
1235 */
1199 break;
1200
1201 case SCM_TIMESTAMP:
1202 *controlp = sbcreatecontrol(NULL, sizeof(*tv),
1203 SCM_TIMESTAMP, SOL_SOCKET);
1204 if (*controlp == NULL) {
1205 error = ENOBUFS;
1206 goto out;

--- 39 unchanged lines hidden (view full) ---

1246 if (unp_gcing)
1247 return;
1248 unp_gcing = 1;
1249 unp_defer = 0;
1250 /*
1251 * before going through all this, set all FDs to
1252 * be NOT defered and NOT externally accessible
1253 */
1254 sx_slock(&filelist_lock);
1236 LIST_FOREACH(fp, &filehead, f_list)
1255 LIST_FOREACH(fp, &filehead, f_list)
1237 fp->f_flag &= ~(FMARK|FDEFER);
1256 fp->f_gcflag &= ~(FMARK|FDEFER);
1238 do {
1239 LIST_FOREACH(fp, &filehead, f_list) {
1257 do {
1258 LIST_FOREACH(fp, &filehead, f_list) {
1259 FILE_LOCK(fp);
1240 /*
1241 * If the file is not open, skip it
1242 */
1260 /*
1261 * If the file is not open, skip it
1262 */
1243 if (fp->f_count == 0)
1263 if (fp->f_count == 0) {
1264 FILE_UNLOCK(fp);
1244 continue;
1265 continue;
1266 }
1245 /*
1246 * If we already marked it as 'defer' in a
1247 * previous pass, then try process it this time
1248 * and un-mark it
1249 */
1267 /*
1268 * If we already marked it as 'defer' in a
1269 * previous pass, then try process it this time
1270 * and un-mark it
1271 */
1250 if (fp->f_flag & FDEFER) {
1251 fp->f_flag &= ~FDEFER;
1272 if (fp->f_gcflag & FDEFER) {
1273 fp->f_gcflag &= ~FDEFER;
1252 unp_defer--;
1253 } else {
1254 /*
1255 * if it's not defered, then check if it's
1256 * already marked.. if so skip it
1257 */
1274 unp_defer--;
1275 } else {
1276 /*
1277 * if it's not defered, then check if it's
1278 * already marked.. if so skip it
1279 */
1258 if (fp->f_flag & FMARK)
1280 if (fp->f_gcflag & FMARK) {
1281 FILE_UNLOCK(fp);
1259 continue;
1282 continue;
1283 }
1260 /*
1261 * If all references are from messages
1262 * in transit, then skip it. it's not
1263 * externally accessible.
1264 */
1284 /*
1285 * If all references are from messages
1286 * in transit, then skip it. it's not
1287 * externally accessible.
1288 */
1265 if (fp->f_count == fp->f_msgcount)
1289 if (fp->f_count == fp->f_msgcount) {
1290 FILE_UNLOCK(fp);
1266 continue;
1291 continue;
1292 }
1267 /*
1268 * If it got this far then it must be
1269 * externally accessible.
1270 */
1293 /*
1294 * If it got this far then it must be
1295 * externally accessible.
1296 */
1271 fp->f_flag |= FMARK;
1297 fp->f_gcflag |= FMARK;
1272 }
1273 /*
1274 * either it was defered, or it is externally
1275 * accessible and not already marked so.
1276 * Now check if it is possibly one of OUR sockets.
1277 */
1278 if (fp->f_type != DTYPE_SOCKET ||
1298 }
1299 /*
1300 * either it was defered, or it is externally
1301 * accessible and not already marked so.
1302 * Now check if it is possibly one of OUR sockets.
1303 */
1304 if (fp->f_type != DTYPE_SOCKET ||
1279 (so = (struct socket *)fp->f_data) == 0)
1305 (so = (struct socket *)fp->f_data) == 0) {
1306 FILE_UNLOCK(fp);
1280 continue;
1307 continue;
1308 }
1309 FILE_UNLOCK(fp);
1281 if (so->so_proto->pr_domain != &localdomain ||
1282 (so->so_proto->pr_flags&PR_RIGHTS) == 0)
1283 continue;
1284#ifdef notdef
1285 if (so->so_rcv.sb_flags & SB_LOCK) {
1286 /*
1287 * This is problematical; it's not clear
1288 * we need to wait for the sockbuf to be

--- 13 unchanged lines hidden (view full) ---

1302 * accessible (or was defered). Now we look
1303 * to see if we hold any file descriptors in its
1304 * message buffers. Follow those links and mark them
1305 * as accessible too.
1306 */
1307 unp_scan(so->so_rcv.sb_mb, unp_mark);
1308 }
1309 } while (unp_defer);
1310 if (so->so_proto->pr_domain != &localdomain ||
1311 (so->so_proto->pr_flags&PR_RIGHTS) == 0)
1312 continue;
1313#ifdef notdef
1314 if (so->so_rcv.sb_flags & SB_LOCK) {
1315 /*
1316 * This is problematical; it's not clear
1317 * we need to wait for the sockbuf to be

--- 13 unchanged lines hidden (view full) ---

1331 * accessible (or was defered). Now we look
1332 * to see if we hold any file descriptors in its
1333 * message buffers. Follow those links and mark them
1334 * as accessible too.
1335 */
1336 unp_scan(so->so_rcv.sb_mb, unp_mark);
1337 }
1338 } while (unp_defer);
1339 sx_sunlock(&filelist_lock);
1310 /*
1311 * We grab an extra reference to each of the file table entries
1312 * that are not otherwise accessible and then free the rights
1313 * that are stored in messages on them.
1314 *
1315 * The bug in the orginal code is a little tricky, so I'll describe
1316 * what's wrong with it here.
1317 *

--- 24 unchanged lines hidden (view full) ---

1342 * it is a Unix domain socket anyhow. After we destroy all the
1343 * rights carried in messages, we do a last closef to get rid
1344 * of our extra reference. This is the last close, and the
1345 * unp_detach etc will shut down the socket.
1346 *
1347 * 91/09/19, bsy@cs.cmu.edu
1348 */
1349 extra_ref = malloc(nfiles * sizeof(struct file *), M_FILE, M_WAITOK);
1340 /*
1341 * We grab an extra reference to each of the file table entries
1342 * that are not otherwise accessible and then free the rights
1343 * that are stored in messages on them.
1344 *
1345 * The bug in the orginal code is a little tricky, so I'll describe
1346 * what's wrong with it here.
1347 *

--- 24 unchanged lines hidden (view full) ---

1372 * it is a Unix domain socket anyhow. After we destroy all the
1373 * rights carried in messages, we do a last closef to get rid
1374 * of our extra reference. This is the last close, and the
1375 * unp_detach etc will shut down the socket.
1376 *
1377 * 91/09/19, bsy@cs.cmu.edu
1378 */
1379 extra_ref = malloc(nfiles * sizeof(struct file *), M_FILE, M_WAITOK);
1380 sx_slock(&filelist_lock);
1350 for (nunref = 0, fp = LIST_FIRST(&filehead), fpp = extra_ref; fp != 0;
1351 fp = nextfp) {
1352 nextfp = LIST_NEXT(fp, f_list);
1381 for (nunref = 0, fp = LIST_FIRST(&filehead), fpp = extra_ref; fp != 0;
1382 fp = nextfp) {
1383 nextfp = LIST_NEXT(fp, f_list);
1384 FILE_LOCK(fp);
1353 /*
1354 * If it's not open, skip it
1355 */
1385 /*
1386 * If it's not open, skip it
1387 */
1356 if (fp->f_count == 0)
1388 if (fp->f_count == 0) {
1389 FILE_UNLOCK(fp);
1357 continue;
1390 continue;
1391 }
1358 /*
1359 * If all refs are from msgs, and it's not marked accessible
1360 * then it must be referenced from some unreachable cycle
1361 * of (shut-down) FDs, so include it in our
1362 * list of FDs to remove
1363 */
1392 /*
1393 * If all refs are from msgs, and it's not marked accessible
1394 * then it must be referenced from some unreachable cycle
1395 * of (shut-down) FDs, so include it in our
1396 * list of FDs to remove
1397 */
1364 if (fp->f_count == fp->f_msgcount && !(fp->f_flag & FMARK)) {
1398 if (fp->f_count == fp->f_msgcount && !(fp->f_gcflag & FMARK)) {
1365 *fpp++ = fp;
1366 nunref++;
1367 fp->f_count++;
1368 }
1399 *fpp++ = fp;
1400 nunref++;
1401 fp->f_count++;
1402 }
1403 FILE_UNLOCK(fp);
1369 }
1404 }
1405 sx_sunlock(&filelist_lock);
1370 /*
1371 * for each FD on our hit list, do the following two things
1372 */
1373 for (i = nunref, fpp = extra_ref; --i >= 0; ++fpp) {
1374 struct file *tfp = *fpp;
1406 /*
1407 * for each FD on our hit list, do the following two things
1408 */
1409 for (i = nunref, fpp = extra_ref; --i >= 0; ++fpp) {
1410 struct file *tfp = *fpp;
1375 if (tfp->f_type == DTYPE_SOCKET && tfp->f_data != NULL)
1411 FILE_LOCK(tfp);
1412 if (tfp->f_type == DTYPE_SOCKET && tfp->f_data != NULL) {
1413 FILE_UNLOCK(tfp);
1376 sorflush((struct socket *)(tfp->f_data));
1414 sorflush((struct socket *)(tfp->f_data));
1415 } else
1416 FILE_UNLOCK(tfp);
1377 }
1378 for (i = nunref, fpp = extra_ref; --i >= 0; ++fpp)
1379 closef(*fpp, (struct thread *) NULL);
1380 free((caddr_t)extra_ref, M_FILE);
1381 unp_gcing = 0;
1382}
1383
1384void

--- 70 unchanged lines hidden (view full) ---

1455 m0 = m0->m_act;
1456 }
1457}
1458
1459static void
1460unp_mark(fp)
1461 struct file *fp;
1462{
1417 }
1418 for (i = nunref, fpp = extra_ref; --i >= 0; ++fpp)
1419 closef(*fpp, (struct thread *) NULL);
1420 free((caddr_t)extra_ref, M_FILE);
1421 unp_gcing = 0;
1422}
1423
1424void

--- 70 unchanged lines hidden (view full) ---

1495 m0 = m0->m_act;
1496 }
1497}
1498
1499static void
1500unp_mark(fp)
1501 struct file *fp;
1502{
1463
1464 if (fp->f_flag & FMARK)
1503 if (fp->f_gcflag & FMARK)
1465 return;
1466 unp_defer++;
1504 return;
1505 unp_defer++;
1467 fp->f_flag |= (FMARK|FDEFER);
1506 fp->f_gcflag |= (FMARK|FDEFER);
1468}
1469
1470static void
1471unp_discard(fp)
1472 struct file *fp;
1473{
1507}
1508
1509static void
1510unp_discard(fp)
1511 struct file *fp;
1512{
1474
1513 FILE_LOCK(fp);
1475 fp->f_msgcount--;
1476 unp_rights--;
1514 fp->f_msgcount--;
1515 unp_rights--;
1516 FILE_UNLOCK(fp);
1477 (void) closef(fp, (struct thread *)NULL);
1478}
1517 (void) closef(fp, (struct thread *)NULL);
1518}