1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 28*7c478bd9Sstevel@tonic-gate 29*7c478bd9Sstevel@tonic-gate #include <sys/types.h> 30*7c478bd9Sstevel@tonic-gate #include <sys/vnode.h> 31*7c478bd9Sstevel@tonic-gate #include <sys/kmem.h> 32*7c478bd9Sstevel@tonic-gate #include <fs/fs_subr.h> 33*7c478bd9Sstevel@tonic-gate #include <sys/proc.h> 34*7c478bd9Sstevel@tonic-gate #include <sys/kstat.h> 35*7c478bd9Sstevel@tonic-gate #include <sys/port_impl.h> 36*7c478bd9Sstevel@tonic-gate 37*7c478bd9Sstevel@tonic-gate /* local functions */ 38*7c478bd9Sstevel@tonic-gate static int port_open(struct vnode **, int, cred_t *); 39*7c478bd9Sstevel@tonic-gate static int port_close(struct vnode *, int, int, offset_t, cred_t *); 40*7c478bd9Sstevel@tonic-gate static int port_getattr(struct vnode *, struct vattr *, int, cred_t *); 41*7c478bd9Sstevel@tonic-gate static int port_access(struct vnode *, int, int, cred_t *); 42*7c478bd9Sstevel@tonic-gate static int port_realvp(vnode_t *, vnode_t **); 43*7c478bd9Sstevel@tonic-gate static int port_poll(vnode_t *, short, int, short *, struct pollhead **); 44*7c478bd9Sstevel@tonic-gate static void port_inactive(struct vnode *, cred_t *); 45*7c478bd9Sstevel@tonic-gate 46*7c478bd9Sstevel@tonic-gate const fs_operation_def_t port_vnodeops_template[] = { 47*7c478bd9Sstevel@tonic-gate VOPNAME_OPEN, port_open, 48*7c478bd9Sstevel@tonic-gate VOPNAME_CLOSE, port_close, 49*7c478bd9Sstevel@tonic-gate VOPNAME_GETATTR, port_getattr, 50*7c478bd9Sstevel@tonic-gate VOPNAME_ACCESS, port_access, 51*7c478bd9Sstevel@tonic-gate VOPNAME_INACTIVE, (fs_generic_func_p) port_inactive, 52*7c478bd9Sstevel@tonic-gate VOPNAME_FRLOCK, fs_error, 53*7c478bd9Sstevel@tonic-gate VOPNAME_REALVP, port_realvp, 54*7c478bd9Sstevel@tonic-gate VOPNAME_POLL, (fs_generic_func_p) port_poll, 55*7c478bd9Sstevel@tonic-gate VOPNAME_PATHCONF, fs_error, 56*7c478bd9Sstevel@tonic-gate VOPNAME_DISPOSE, fs_error, 57*7c478bd9Sstevel@tonic-gate VOPNAME_GETSECATTR, fs_error, 58*7c478bd9Sstevel@tonic-gate VOPNAME_SHRLOCK, fs_error, 59*7c478bd9Sstevel@tonic-gate NULL, NULL 60*7c478bd9Sstevel@tonic-gate }; 61*7c478bd9Sstevel@tonic-gate 62*7c478bd9Sstevel@tonic-gate /* ARGSUSED */ 63*7c478bd9Sstevel@tonic-gate static int 64*7c478bd9Sstevel@tonic-gate port_open(struct vnode **vpp, int flag, cred_t *cr) 65*7c478bd9Sstevel@tonic-gate { 66*7c478bd9Sstevel@tonic-gate return (0); 67*7c478bd9Sstevel@tonic-gate } 68*7c478bd9Sstevel@tonic-gate 69*7c478bd9Sstevel@tonic-gate /* 70*7c478bd9Sstevel@tonic-gate * port_discard_events() scans the port event queue for events owned 71*7c478bd9Sstevel@tonic-gate * by current proc. Non-shareable events will be discarded, all other 72*7c478bd9Sstevel@tonic-gate * events remain in the event queue. 73*7c478bd9Sstevel@tonic-gate */ 74*7c478bd9Sstevel@tonic-gate void 75*7c478bd9Sstevel@tonic-gate port_discard_events(port_queue_t *portq) 76*7c478bd9Sstevel@tonic-gate { 77*7c478bd9Sstevel@tonic-gate port_kevent_t *kevp; 78*7c478bd9Sstevel@tonic-gate pid_t pid = curproc->p_pid; 79*7c478bd9Sstevel@tonic-gate 80*7c478bd9Sstevel@tonic-gate /* 81*7c478bd9Sstevel@tonic-gate * Both mutexes are required to avoid interaction with other threads 82*7c478bd9Sstevel@tonic-gate * in port_get(n). 83*7c478bd9Sstevel@tonic-gate */ 84*7c478bd9Sstevel@tonic-gate mutex_enter(&portq->portq_mutex); 85*7c478bd9Sstevel@tonic-gate mutex_enter(&portq->portq_block_mutex); 86*7c478bd9Sstevel@tonic-gate port_push_eventq(portq); /* empty temporary queue */ 87*7c478bd9Sstevel@tonic-gate kevp = list_head(&portq->portq_list); 88*7c478bd9Sstevel@tonic-gate while (kevp) { 89*7c478bd9Sstevel@tonic-gate if (kevp->portkev_pid == pid) { 90*7c478bd9Sstevel@tonic-gate /* own event, check if it is shareable */ 91*7c478bd9Sstevel@tonic-gate if (kevp->portkev_flags & PORT_KEV_NOSHARE) 92*7c478bd9Sstevel@tonic-gate kevp->portkev_flags |= PORT_KEV_FREE; 93*7c478bd9Sstevel@tonic-gate } 94*7c478bd9Sstevel@tonic-gate kevp = list_next(&portq->portq_list, kevp); 95*7c478bd9Sstevel@tonic-gate } 96*7c478bd9Sstevel@tonic-gate mutex_exit(&portq->portq_block_mutex); 97*7c478bd9Sstevel@tonic-gate mutex_exit(&portq->portq_mutex); 98*7c478bd9Sstevel@tonic-gate } 99*7c478bd9Sstevel@tonic-gate 100*7c478bd9Sstevel@tonic-gate /* 101*7c478bd9Sstevel@tonic-gate * Called from port_close(). 102*7c478bd9Sstevel@tonic-gate * Free all kernel events structures which are still in the event queue. 103*7c478bd9Sstevel@tonic-gate */ 104*7c478bd9Sstevel@tonic-gate static void 105*7c478bd9Sstevel@tonic-gate port_close_events(port_queue_t *portq) 106*7c478bd9Sstevel@tonic-gate { 107*7c478bd9Sstevel@tonic-gate port_kevent_t *pkevp; 108*7c478bd9Sstevel@tonic-gate int events; /* ignore events */ 109*7c478bd9Sstevel@tonic-gate 110*7c478bd9Sstevel@tonic-gate mutex_enter(&portq->portq_mutex); 111*7c478bd9Sstevel@tonic-gate while (pkevp = list_head(&portq->portq_list)) { 112*7c478bd9Sstevel@tonic-gate portq->portq_nent--; 113*7c478bd9Sstevel@tonic-gate list_remove(&portq->portq_list, pkevp); 114*7c478bd9Sstevel@tonic-gate if (pkevp->portkev_callback) { 115*7c478bd9Sstevel@tonic-gate (void) (*pkevp->portkev_callback)(pkevp->portkev_arg, 116*7c478bd9Sstevel@tonic-gate &events, pkevp->portkev_pid, PORT_CALLBACK_CLOSE, 117*7c478bd9Sstevel@tonic-gate pkevp); 118*7c478bd9Sstevel@tonic-gate } 119*7c478bd9Sstevel@tonic-gate mutex_exit(&portq->portq_mutex); 120*7c478bd9Sstevel@tonic-gate port_free_event_local(pkevp, 0); 121*7c478bd9Sstevel@tonic-gate mutex_enter(&portq->portq_mutex); 122*7c478bd9Sstevel@tonic-gate } 123*7c478bd9Sstevel@tonic-gate mutex_exit(&portq->portq_mutex); 124*7c478bd9Sstevel@tonic-gate } 125*7c478bd9Sstevel@tonic-gate 126*7c478bd9Sstevel@tonic-gate /* 127*7c478bd9Sstevel@tonic-gate * The port_close() function is called from standard close(2) when 128*7c478bd9Sstevel@tonic-gate * the file descriptor is of type S_IFPORT/VPORT. 129*7c478bd9Sstevel@tonic-gate * Port file descriptors behave like standard file descriptors. It means, 130*7c478bd9Sstevel@tonic-gate * the port file/vnode is only destroyed on last close. 131*7c478bd9Sstevel@tonic-gate * If the reference counter is > 1 then 132*7c478bd9Sstevel@tonic-gate * - sources associated with the port will be notified about the close, 133*7c478bd9Sstevel@tonic-gate * - objects associated with the port will be dissociated, 134*7c478bd9Sstevel@tonic-gate * - pending and delivered events will be discarded. 135*7c478bd9Sstevel@tonic-gate * On last close all references and caches will be removed. The vnode itself 136*7c478bd9Sstevel@tonic-gate * will be destroyed with VOP_RELE(). 137*7c478bd9Sstevel@tonic-gate */ 138*7c478bd9Sstevel@tonic-gate /* ARGSUSED */ 139*7c478bd9Sstevel@tonic-gate static int 140*7c478bd9Sstevel@tonic-gate port_close(struct vnode *vp, int flag, int count, offset_t offset, cred_t *cr) 141*7c478bd9Sstevel@tonic-gate { 142*7c478bd9Sstevel@tonic-gate port_t *pp; 143*7c478bd9Sstevel@tonic-gate port_queue_t *portq; 144*7c478bd9Sstevel@tonic-gate port_source_t *ps; 145*7c478bd9Sstevel@tonic-gate port_source_t *ps_next; 146*7c478bd9Sstevel@tonic-gate int source; 147*7c478bd9Sstevel@tonic-gate 148*7c478bd9Sstevel@tonic-gate pp = VTOEP(vp); 149*7c478bd9Sstevel@tonic-gate mutex_enter(&pp->port_mutex); 150*7c478bd9Sstevel@tonic-gate if (pp->port_flags & PORT_CLOSED) { 151*7c478bd9Sstevel@tonic-gate mutex_exit(&pp->port_mutex); 152*7c478bd9Sstevel@tonic-gate return (0); 153*7c478bd9Sstevel@tonic-gate } 154*7c478bd9Sstevel@tonic-gate mutex_exit(&pp->port_mutex); 155*7c478bd9Sstevel@tonic-gate 156*7c478bd9Sstevel@tonic-gate portq = &pp->port_queue; 157*7c478bd9Sstevel@tonic-gate if (count > 1) { 158*7c478bd9Sstevel@tonic-gate /* 159*7c478bd9Sstevel@tonic-gate * It is not the last close. 160*7c478bd9Sstevel@tonic-gate * Remove/free all event resources owned by the current proc 161*7c478bd9Sstevel@tonic-gate * First notify all with the port associated sources about the 162*7c478bd9Sstevel@tonic-gate * close(2). The last argument of the close callback function 163*7c478bd9Sstevel@tonic-gate * advises the source about the type of of the close. 164*7c478bd9Sstevel@tonic-gate * If the port was set in alert mode by the curren process then 165*7c478bd9Sstevel@tonic-gate * remove the alert mode. 166*7c478bd9Sstevel@tonic-gate */ 167*7c478bd9Sstevel@tonic-gate 168*7c478bd9Sstevel@tonic-gate /* check alert mode of the port */ 169*7c478bd9Sstevel@tonic-gate mutex_enter(&portq->portq_mutex); 170*7c478bd9Sstevel@tonic-gate if ((portq->portq_flags & PORTQ_ALERT) && 171*7c478bd9Sstevel@tonic-gate (portq->portq_alert.portal_pid == curproc->p_pid)) 172*7c478bd9Sstevel@tonic-gate portq->portq_flags &= ~PORTQ_ALERT; 173*7c478bd9Sstevel@tonic-gate mutex_exit(&portq->portq_mutex); 174*7c478bd9Sstevel@tonic-gate 175*7c478bd9Sstevel@tonic-gate /* notify all event sources about port_close() */ 176*7c478bd9Sstevel@tonic-gate mutex_enter(&portq->portq_source_mutex); 177*7c478bd9Sstevel@tonic-gate for (source = 0; source < PORT_SCACHE_SIZE; source++) { 178*7c478bd9Sstevel@tonic-gate ps = portq->portq_scache[PORT_SHASH(source)]; 179*7c478bd9Sstevel@tonic-gate for (; ps != NULL; ps = ps->portsrc_next) { 180*7c478bd9Sstevel@tonic-gate if (ps->portsrc_close != NULL) 181*7c478bd9Sstevel@tonic-gate (*ps->portsrc_close) 182*7c478bd9Sstevel@tonic-gate (ps->portsrc_closearg, pp->port_fd, 183*7c478bd9Sstevel@tonic-gate curproc->p_pid, 0); 184*7c478bd9Sstevel@tonic-gate } 185*7c478bd9Sstevel@tonic-gate } 186*7c478bd9Sstevel@tonic-gate mutex_exit(&portq->portq_source_mutex); 187*7c478bd9Sstevel@tonic-gate port_discard_events(&pp->port_queue); 188*7c478bd9Sstevel@tonic-gate return (0); 189*7c478bd9Sstevel@tonic-gate } 190*7c478bd9Sstevel@tonic-gate 191*7c478bd9Sstevel@tonic-gate /* 192*7c478bd9Sstevel@tonic-gate * We are executing the last close of the port -> discard everything 193*7c478bd9Sstevel@tonic-gate * Make sure that all threads/processes accessing this port leave 194*7c478bd9Sstevel@tonic-gate * the kernel immediately. 195*7c478bd9Sstevel@tonic-gate */ 196*7c478bd9Sstevel@tonic-gate 197*7c478bd9Sstevel@tonic-gate mutex_enter(&portq->portq_mutex); 198*7c478bd9Sstevel@tonic-gate portq->portq_flags |= PORTQ_CLOSE; 199*7c478bd9Sstevel@tonic-gate while (portq->portq_thrcnt > 0) { 200*7c478bd9Sstevel@tonic-gate if (portq->portq_thread != NULL) 201*7c478bd9Sstevel@tonic-gate cv_signal(&portq->portq_thread->portget_cv); 202*7c478bd9Sstevel@tonic-gate cv_wait(&portq->portq_closecv, &portq->portq_mutex); 203*7c478bd9Sstevel@tonic-gate } 204*7c478bd9Sstevel@tonic-gate mutex_exit(&portq->portq_mutex); 205*7c478bd9Sstevel@tonic-gate 206*7c478bd9Sstevel@tonic-gate /* 207*7c478bd9Sstevel@tonic-gate * Send "last close" message to associated sources. 208*7c478bd9Sstevel@tonic-gate * - new event allocation requests are being denied since uf_file entry 209*7c478bd9Sstevel@tonic-gate * was set to NULL in closeandsetf(). 210*7c478bd9Sstevel@tonic-gate * - all still allocated event structures must be returned to the 211*7c478bd9Sstevel@tonic-gate * port immediately: 212*7c478bd9Sstevel@tonic-gate * - call port_free_event(*event) or 213*7c478bd9Sstevel@tonic-gate * - call port_send_event(*event) to complete event operations 214*7c478bd9Sstevel@tonic-gate * which need activities in a dedicated process environment. 215*7c478bd9Sstevel@tonic-gate * The port_close() function waits until all allocated event structures 216*7c478bd9Sstevel@tonic-gate * are delivered back to the port. 217*7c478bd9Sstevel@tonic-gate */ 218*7c478bd9Sstevel@tonic-gate 219*7c478bd9Sstevel@tonic-gate mutex_enter(&portq->portq_source_mutex); 220*7c478bd9Sstevel@tonic-gate for (source = 0; source < PORT_SCACHE_SIZE; source++) { 221*7c478bd9Sstevel@tonic-gate ps = portq->portq_scache[PORT_SHASH(source)]; 222*7c478bd9Sstevel@tonic-gate for (; ps != NULL; ps = ps_next) { 223*7c478bd9Sstevel@tonic-gate ps_next = ps->portsrc_next; 224*7c478bd9Sstevel@tonic-gate if (ps->portsrc_close != NULL) 225*7c478bd9Sstevel@tonic-gate (*ps->portsrc_close)(ps->portsrc_closearg, 226*7c478bd9Sstevel@tonic-gate pp->port_fd, curproc->p_pid, 1); 227*7c478bd9Sstevel@tonic-gate kmem_free(ps, sizeof (port_source_t)); 228*7c478bd9Sstevel@tonic-gate } 229*7c478bd9Sstevel@tonic-gate } 230*7c478bd9Sstevel@tonic-gate kmem_free(portq->portq_scache, 231*7c478bd9Sstevel@tonic-gate PORT_SCACHE_SIZE * sizeof (port_source_t *)); 232*7c478bd9Sstevel@tonic-gate portq->portq_scache = NULL; 233*7c478bd9Sstevel@tonic-gate mutex_exit(&portq->portq_source_mutex); 234*7c478bd9Sstevel@tonic-gate 235*7c478bd9Sstevel@tonic-gate mutex_enter(&portq->portq_mutex); 236*7c478bd9Sstevel@tonic-gate /* Wait for outstanding events */ 237*7c478bd9Sstevel@tonic-gate while (pp->port_curr > portq->portq_nent) 238*7c478bd9Sstevel@tonic-gate cv_wait(&portq->portq_closecv, &portq->portq_mutex); 239*7c478bd9Sstevel@tonic-gate mutex_exit(&portq->portq_mutex); 240*7c478bd9Sstevel@tonic-gate 241*7c478bd9Sstevel@tonic-gate /* 242*7c478bd9Sstevel@tonic-gate * If PORT_SOURCE_FD objects were not associated with the port then 243*7c478bd9Sstevel@tonic-gate * it is necessary to free the port_fdcache structure here. 244*7c478bd9Sstevel@tonic-gate */ 245*7c478bd9Sstevel@tonic-gate 246*7c478bd9Sstevel@tonic-gate if (portq->portq_pcp != NULL) { 247*7c478bd9Sstevel@tonic-gate mutex_destroy(&portq->portq_pcp->pc_lock); 248*7c478bd9Sstevel@tonic-gate kmem_free(portq->portq_pcp, sizeof (port_fdcache_t)); 249*7c478bd9Sstevel@tonic-gate portq->portq_pcp = NULL; 250*7c478bd9Sstevel@tonic-gate } 251*7c478bd9Sstevel@tonic-gate 252*7c478bd9Sstevel@tonic-gate /* 253*7c478bd9Sstevel@tonic-gate * Now all events are passed back to the port, 254*7c478bd9Sstevel@tonic-gate * discard remaining events in the port queue 255*7c478bd9Sstevel@tonic-gate */ 256*7c478bd9Sstevel@tonic-gate 257*7c478bd9Sstevel@tonic-gate port_close_events(portq); 258*7c478bd9Sstevel@tonic-gate return (0); 259*7c478bd9Sstevel@tonic-gate } 260*7c478bd9Sstevel@tonic-gate 261*7c478bd9Sstevel@tonic-gate /* 262*7c478bd9Sstevel@tonic-gate * The port_poll() function is the VOP_POLL() entry of event ports. 263*7c478bd9Sstevel@tonic-gate * Event ports return: 264*7c478bd9Sstevel@tonic-gate * POLLIN : events are available in the event queue 265*7c478bd9Sstevel@tonic-gate * POLLOUT : event queue can still accept events 266*7c478bd9Sstevel@tonic-gate */ 267*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 268*7c478bd9Sstevel@tonic-gate static int 269*7c478bd9Sstevel@tonic-gate port_poll(vnode_t *vp, short events, int anyyet, short *reventsp, 270*7c478bd9Sstevel@tonic-gate struct pollhead **phpp) 271*7c478bd9Sstevel@tonic-gate { 272*7c478bd9Sstevel@tonic-gate port_t *pp; 273*7c478bd9Sstevel@tonic-gate port_queue_t *portq; 274*7c478bd9Sstevel@tonic-gate short levents; 275*7c478bd9Sstevel@tonic-gate 276*7c478bd9Sstevel@tonic-gate pp = VTOEP(vp); 277*7c478bd9Sstevel@tonic-gate portq = &pp->port_queue; 278*7c478bd9Sstevel@tonic-gate levents = 0; 279*7c478bd9Sstevel@tonic-gate mutex_enter(&portq->portq_mutex); 280*7c478bd9Sstevel@tonic-gate if (portq->portq_nent) 281*7c478bd9Sstevel@tonic-gate levents = POLLIN; 282*7c478bd9Sstevel@tonic-gate if (pp->port_curr < pp->port_max_events) 283*7c478bd9Sstevel@tonic-gate levents |= POLLOUT; 284*7c478bd9Sstevel@tonic-gate levents &= events; 285*7c478bd9Sstevel@tonic-gate *reventsp = levents; 286*7c478bd9Sstevel@tonic-gate if (levents == 0) { 287*7c478bd9Sstevel@tonic-gate if (!anyyet) { 288*7c478bd9Sstevel@tonic-gate *phpp = &pp->port_pollhd; 289*7c478bd9Sstevel@tonic-gate portq->portq_flags |= 290*7c478bd9Sstevel@tonic-gate events & POLLIN ? PORTQ_POLLIN : 0; 291*7c478bd9Sstevel@tonic-gate portq->portq_flags |= 292*7c478bd9Sstevel@tonic-gate events & POLLOUT ? PORTQ_POLLOUT : 0; 293*7c478bd9Sstevel@tonic-gate } 294*7c478bd9Sstevel@tonic-gate } 295*7c478bd9Sstevel@tonic-gate mutex_exit(&portq->portq_mutex); 296*7c478bd9Sstevel@tonic-gate return (0); 297*7c478bd9Sstevel@tonic-gate } 298*7c478bd9Sstevel@tonic-gate 299*7c478bd9Sstevel@tonic-gate 300*7c478bd9Sstevel@tonic-gate /* ARGSUSED */ 301*7c478bd9Sstevel@tonic-gate static int 302*7c478bd9Sstevel@tonic-gate port_getattr(struct vnode *vp, struct vattr *vap, int flags, cred_t *cr) 303*7c478bd9Sstevel@tonic-gate { 304*7c478bd9Sstevel@tonic-gate port_t *pp; 305*7c478bd9Sstevel@tonic-gate extern dev_t portdev; 306*7c478bd9Sstevel@tonic-gate 307*7c478bd9Sstevel@tonic-gate pp = VTOEP(vp); 308*7c478bd9Sstevel@tonic-gate 309*7c478bd9Sstevel@tonic-gate vap->va_mask = 0; /* bit-mask of attributes */ 310*7c478bd9Sstevel@tonic-gate vap->va_type = vp->v_type; /* vnode type (for create) */ 311*7c478bd9Sstevel@tonic-gate vap->va_mode = 0; /* file access mode */ 312*7c478bd9Sstevel@tonic-gate vap->va_uid = pp->port_uid; /* owner user id */ 313*7c478bd9Sstevel@tonic-gate vap->va_gid = pp->port_gid; /* owner group id */ 314*7c478bd9Sstevel@tonic-gate vap->va_fsid = portdev; /* file system id */ 315*7c478bd9Sstevel@tonic-gate vap->va_nodeid = (ino64_t)0; /* node id */ 316*7c478bd9Sstevel@tonic-gate vap->va_nlink = vp->v_count; /* number of references to file */ 317*7c478bd9Sstevel@tonic-gate vap->va_size = (u_offset_t)pp->port_queue.portq_nent; /* file size */ 318*7c478bd9Sstevel@tonic-gate vap->va_atime = pp->port_ctime; /* time of last access */ 319*7c478bd9Sstevel@tonic-gate vap->va_mtime = pp->port_ctime; /* time of last modification */ 320*7c478bd9Sstevel@tonic-gate vap->va_ctime = pp->port_ctime; /* time file ``created'' */ 321*7c478bd9Sstevel@tonic-gate vap->va_rdev = portdev; /* device the file represents */ 322*7c478bd9Sstevel@tonic-gate vap->va_blksize = 0; /* fundamental block size */ 323*7c478bd9Sstevel@tonic-gate vap->va_nblocks = (fsblkcnt64_t)0; /* # of blocks allocated */ 324*7c478bd9Sstevel@tonic-gate vap->va_seq = 0; /* sequence number */ 325*7c478bd9Sstevel@tonic-gate 326*7c478bd9Sstevel@tonic-gate return (0); 327*7c478bd9Sstevel@tonic-gate } 328*7c478bd9Sstevel@tonic-gate 329*7c478bd9Sstevel@tonic-gate /* 330*7c478bd9Sstevel@tonic-gate * Destroy the port. 331*7c478bd9Sstevel@tonic-gate */ 332*7c478bd9Sstevel@tonic-gate /* ARGSUSED */ 333*7c478bd9Sstevel@tonic-gate static void 334*7c478bd9Sstevel@tonic-gate port_inactive(struct vnode *vp, cred_t *cr) 335*7c478bd9Sstevel@tonic-gate { 336*7c478bd9Sstevel@tonic-gate port_t *pp = VTOEP(vp); 337*7c478bd9Sstevel@tonic-gate extern port_kstat_t port_kstat; 338*7c478bd9Sstevel@tonic-gate 339*7c478bd9Sstevel@tonic-gate mutex_enter(&port_control.pc_mutex); 340*7c478bd9Sstevel@tonic-gate port_control.pc_nents--; 341*7c478bd9Sstevel@tonic-gate curproc->p_portcnt--; 342*7c478bd9Sstevel@tonic-gate port_kstat.pks_ports.value.ui32--; 343*7c478bd9Sstevel@tonic-gate mutex_exit(&port_control.pc_mutex); 344*7c478bd9Sstevel@tonic-gate vn_free(vp); 345*7c478bd9Sstevel@tonic-gate mutex_destroy(&pp->port_mutex); 346*7c478bd9Sstevel@tonic-gate mutex_destroy(&pp->port_queue.portq_mutex); 347*7c478bd9Sstevel@tonic-gate mutex_destroy(&pp->port_queue.portq_source_mutex); 348*7c478bd9Sstevel@tonic-gate kmem_free(pp, sizeof (port_t)); 349*7c478bd9Sstevel@tonic-gate } 350*7c478bd9Sstevel@tonic-gate 351*7c478bd9Sstevel@tonic-gate /* ARGSUSED */ 352*7c478bd9Sstevel@tonic-gate static int 353*7c478bd9Sstevel@tonic-gate port_access(struct vnode *vp, int mode, int flags, cred_t *cr) 354*7c478bd9Sstevel@tonic-gate { 355*7c478bd9Sstevel@tonic-gate return (0); 356*7c478bd9Sstevel@tonic-gate } 357*7c478bd9Sstevel@tonic-gate 358*7c478bd9Sstevel@tonic-gate /* ARGSUSED */ 359*7c478bd9Sstevel@tonic-gate static int 360*7c478bd9Sstevel@tonic-gate port_realvp(vnode_t *vp, vnode_t **vpp) 361*7c478bd9Sstevel@tonic-gate { 362*7c478bd9Sstevel@tonic-gate *vpp = vp; 363*7c478bd9Sstevel@tonic-gate return (0); 364*7c478bd9Sstevel@tonic-gate } 365