+ MALLOC(unp_list, struct unpcb **, n * sizeof (*unp_list),
+ M_TEMP, M_WAITOK);
+ if (unp_list == 0) {
+ lck_rw_done(unp_list_mtx);
+ return (ENOMEM);
+ }
+
+ for (unp = head->lh_first, i = 0; unp && i < n;
+ unp = unp->unp_link.le_next) {
+ if (unp->unp_gencnt <= gencnt)
+ unp_list[i++] = unp;
+ }
+ n = i; /* in case we lost some during malloc */
+
+ error = 0;
+ for (i = 0; i < n; i++) {
+ unp = unp_list[i];
+ if (unp->unp_gencnt <= gencnt) {
+ struct xunpcb64 xu;
+ size_t xu_len = sizeof(struct xunpcb64);
+
+ bzero(&xu, xu_len);
+ xu.xu_len = xu_len;
+ xu.xu_unpp = (u_int64_t)VM_KERNEL_ADDRPERM(unp);
+ xu.xunp_link.le_next = (u_int64_t)
+ VM_KERNEL_ADDRPERM(unp->unp_link.le_next);
+ xu.xunp_link.le_prev = (u_int64_t)
+ VM_KERNEL_ADDRPERM(unp->unp_link.le_prev);
+ xu.xunp_socket = (u_int64_t)
+ VM_KERNEL_ADDRPERM(unp->unp_socket);
+ xu.xunp_vnode = (u_int64_t)
+ VM_KERNEL_ADDRPERM(unp->unp_vnode);
+ xu.xunp_ino = unp->unp_ino;
+ xu.xunp_conn = (u_int64_t)
+ VM_KERNEL_ADDRPERM(unp->unp_conn);
+ xu.xunp_refs = (u_int64_t)
+ VM_KERNEL_ADDRPERM(unp->unp_refs.lh_first);
+ xu.xunp_reflink.le_next = (u_int64_t)
+ VM_KERNEL_ADDRPERM(unp->unp_reflink.le_next);
+ xu.xunp_reflink.le_prev = (u_int64_t)
+ VM_KERNEL_ADDRPERM(unp->unp_reflink.le_prev);
+ xu.xunp_cc = unp->unp_cc;
+ xu.xunp_mbcnt = unp->unp_mbcnt;
+ xu.xunp_gencnt = unp->unp_gencnt;
+
+ if (unp->unp_socket)
+ sotoxsocket64(unp->unp_socket, &xu.xu_socket);
+
+ /*
+ * XXX - need more locking here to protect against
+ * connect/disconnect races for SMP.
+ */
+ if (unp->unp_addr)
+ bcopy(unp->unp_addr, &xu.xunp_addr,
+ unp->unp_addr->sun_len);
+ if (unp->unp_conn && unp->unp_conn->unp_addr)
+ bcopy(unp->unp_conn->unp_addr,
+ &xu.xunp_caddr,
+ unp->unp_conn->unp_addr->sun_len);
+
+ error = SYSCTL_OUT(req, &xu, xu_len);
+ }
+ }
+ if (!error) {
+ /*
+ * Give the user an updated idea of our state.
+ * If the generation differs from what we told
+ * her before, she knows that something happened
+ * while we were processing this request, and it
+ * might be necessary to retry.
+ */
+ bzero(&xug, sizeof (xug));
+ xug.xug_len = sizeof (xug);
+ xug.xug_gen = unp_gencnt;
+ xug.xug_sogen = so_gencnt;
+ xug.xug_count = unp_count;
+ error = SYSCTL_OUT(req, &xug, sizeof (xug));
+ }
+ FREE(unp_list, M_TEMP);
+ lck_rw_done(unp_list_mtx);
+ return (error);