usr/src/uts/common/fs/sockfs/sockvnops.c
changeset 741 40027a3621ac
parent 0 68f95e015346
child 898 64b2a371a6bd
equal deleted inserted replaced
740:70e4862c9a1a 741:40027a3621ac
    51 #include <sys/vnode.h>
    51 #include <sys/vnode.h>
    52 #include <sys/poll.h>
    52 #include <sys/poll.h>
    53 #include <sys/stropts.h>
    53 #include <sys/stropts.h>
    54 #include <sys/stream.h>
    54 #include <sys/stream.h>
    55 #include <sys/strsubr.h>
    55 #include <sys/strsubr.h>
       
    56 #include <sys/strsun.h>
    56 #include <sys/suntpi.h>
    57 #include <sys/suntpi.h>
    57 #include <sys/ioctl.h>
    58 #include <sys/ioctl.h>
    58 #include <sys/sockio.h>
    59 #include <sys/sockio.h>
    59 #include <sys/filio.h>
    60 #include <sys/filio.h>
    60 #include <sys/stat.h>
    61 #include <sys/stat.h>
    84 
    85 
    85 #include <sys/esunddi.h>
    86 #include <sys/esunddi.h>
    86 #include <sys/autoconf.h>
    87 #include <sys/autoconf.h>
    87 
    88 
    88 #include <fs/sockfs/nl7c.h>
    89 #include <fs/sockfs/nl7c.h>
       
    90 
       
    91 #include <inet/udp_impl.h>
       
    92 #include <inet/tcp_impl.h>
    89 
    93 
    90 static int socktpi_close(struct vnode *, int, int, offset_t, struct cred *);
    94 static int socktpi_close(struct vnode *, int, int, offset_t, struct cred *);
    91 static int socktpi_read(struct vnode *, struct uio *, int, struct cred *,
    95 static int socktpi_read(struct vnode *, struct uio *, int, struct cred *,
    92 	struct caller_context *);
    96 	struct caller_context *);
    93 static int socktpi_write(struct vnode *, struct uio *, int, struct cred *,
    97 static int socktpi_write(struct vnode *, struct uio *, int, struct cred *,
   138 	VOPNAME_DISPOSE, fs_error,
   142 	VOPNAME_DISPOSE, fs_error,
   139 	NULL, NULL
   143 	NULL, NULL
   140 };
   144 };
   141 
   145 
   142 /*
   146 /*
       
   147  * Do direct function call to the transport layer below; this would
       
   148  * also allow the transport to utilize read-side synchronous stream
       
   149  * interface if necessary.  This is a /etc/system tunable that must
       
   150  * not be modified on a running system.  By default this is enabled
       
   151  * for performance reasons and may be disabled for debugging purposes.
       
   152  */
       
   153 boolean_t socktpi_direct = B_TRUE;
       
   154 
       
   155 /*
   143  * Open routine used by socket() call. Note that vn_open checks for
   156  * Open routine used by socket() call. Note that vn_open checks for
   144  * VSOCK and fails the open (and VOP_OPEN is fs_nosys). The VSOCK check is
   157  * VSOCK and fails the open (and VOP_OPEN is fs_nosys). The VSOCK check is
   145  * needed since VSOCK type vnodes exist in various underlying filesystems as
   158  * needed since VSOCK type vnodes exist in various underlying filesystems as
   146  * a result of an AF_UNIX bind to a pathname.
   159  * a result of an AF_UNIX bind to a pathname.
   147  *
   160  *
   203 			return (ENOTTY);	/* XXX */
   216 			return (ENOTTY);	/* XXX */
   204 		}
   217 		}
   205 
   218 
   206 		ASSERT(stp->sd_wrq != NULL);
   219 		ASSERT(stp->sd_wrq != NULL);
   207 		so->so_provinfo = tpi_findprov(stp->sd_wrq);
   220 		so->so_provinfo = tpi_findprov(stp->sd_wrq);
       
   221 
       
   222 		/*
       
   223 		 * If caller is interested in doing direct function call
       
   224 		 * interface to/from transport module, probe the module
       
   225 		 * directly beneath the streamhead to see if it qualifies.
       
   226 		 *
       
   227 		 * We turn off direct interface when qualifications fail;
       
   228 		 * note that we do these checks for everything other than
       
   229 		 * the tcp acceptor case, because the acceptor inherits
       
   230 		 * the capabilities of the listener and we've already done
       
   231 		 * the checks against the listening socket.
       
   232 		 */
       
   233 		if (!(flag & SO_ACCEPTOR) && (so->so_state & SS_DIRECT)) {
       
   234 			queue_t *tq = stp->sd_wrq->q_next;
       
   235 
       
   236 			/*
       
   237 			 * SS_DIRECT is currently supported and tested
       
   238 			 * only for tcp/udp; this is the main reason to
       
   239 			 * have the following assertions.
       
   240 			 */
       
   241 			ASSERT(so->so_family == AF_INET ||
       
   242 			    so->so_family == AF_INET6);
       
   243 			ASSERT(so->so_protocol == IPPROTO_UDP ||
       
   244 			    so->so_protocol == IPPROTO_TCP ||
       
   245 			    so->so_protocol == IPPROTO_IP);
       
   246 			ASSERT(so->so_type == SOCK_DGRAM ||
       
   247 			    so->so_type == SOCK_STREAM);
       
   248 
       
   249 			/*
       
   250 			 * Abort direct call interface if the module directly
       
   251 			 * underneath the stream head is not defined with the
       
   252 			 * _D_DIRECT flag.  This could happen in the tcp or
       
   253 			 * udp case, when some other module is autopushed
       
   254 			 * above it, or for some reasons the expected module
       
   255 			 * isn't purely D_MP (which is the main requirement).
       
   256 			 */
       
   257 			if (!socktpi_direct || !(tq->q_flag & _QDIRECT) ||
       
   258 			    !(_OTHERQ(tq)->q_flag & _QDIRECT)) {
       
   259 				int rval;
       
   260 
       
   261 				/* Continue on without direct calls */
       
   262 				so->so_state &= ~SS_DIRECT;
       
   263 				if ((error = strioctl(vp, _SIOCSOCKFALLBACK,
       
   264 				    0, 0, K_TO_K, CRED(), &rval)) != 0) {
       
   265 					(void) socktpi_close(vp, flag, 1,
       
   266 					    (offset_t)0, cr);
       
   267 					return (error);
       
   268 				}
       
   269 			}
       
   270 		}
   208 	} else {
   271 	} else {
   209 		/*
   272 		/*
   210 		 * While the same socket can not be reopened (unlike specfs)
   273 		 * While the same socket can not be reopened (unlike specfs)
   211 		 * the stream head sets STREOPENFAIL when the autopush fails.
   274 		 * the stream head sets STREOPENFAIL when the autopush fails.
   212 		 */
   275 		 */
   433 	if (so_mode & SM_BYTESTREAM) {
   496 	if (so_mode & SM_BYTESTREAM) {
   434 		/* Send M_DATA messages */
   497 		/* Send M_DATA messages */
   435 		if (so->so_nl7c_flags & NL7C_ENABLED) {
   498 		if (so->so_nl7c_flags & NL7C_ENABLED) {
   436 			/* Give NL7C some data */
   499 			/* Give NL7C some data */
   437 			nl7c_data(so, uiop);
   500 			nl7c_data(so, uiop);
       
   501 		}
       
   502 
       
   503 		if ((so_state & SS_DIRECT) &&
       
   504 		    canputnext(vp->v_stream->sd_wrq)) {
       
   505 			return (sostream_direct(so, uiop, NULL, cr));
   438 		}
   506 		}
   439 		return (strwrite(vp, uiop, cr));
   507 		return (strwrite(vp, uiop, cr));
   440 	} else {
   508 	} else {
   441 		/* Send T_DATA_REQ messages without MORE_flag set */
   509 		/* Send T_DATA_REQ messages without MORE_flag set */
   442 		return (sosend_svc(so, uiop, T_DATA_REQ, 0, 0));
   510 		return (sosend_svc(so, uiop, T_DATA_REQ, 0, 0));
   629 
   697 
   630 	case I_FDINSERT:
   698 	case I_FDINSERT:
   631 	case I_SENDFD:
   699 	case I_SENDFD:
   632 	case I_RECVFD:
   700 	case I_RECVFD:
   633 	case I_ATMARK:
   701 	case I_ATMARK:
   634 	case SIOCPOPSOCKFS:
   702 	case _SIOCSOCKFALLBACK:
   635 		/*
   703 		/*
   636 		 * These ioctls do not apply to sockets. I_FDINSERT can be
   704 		 * These ioctls do not apply to sockets. I_FDINSERT can be
   637 		 * used to send M_PROTO messages without modifying the socket
   705 		 * used to send M_PROTO messages without modifying the socket
   638 		 * state. I_SENDFD/RECVFD should not be used for socket file
   706 		 * state. I_SENDFD/RECVFD should not be used for socket file
   639 		 * descriptor passing since they assume a twisted stream.
   707 		 * descriptor passing since they assume a twisted stream.
   640 		 * SIOCATMARK must be used instead of I_ATMARK.
   708 		 * SIOCATMARK must be used instead of I_ATMARK.
   641 		 *
   709 		 *
   642 		 * SIOCPOPSOCKFS from an application should never be
   710 		 * _SIOCSOCKFALLBACK from an application should never be
   643 		 * processed. It is always generated in response to I_POP.
   711 		 * processed.  It is only generated by socktpi_open() or
       
   712 		 * in response to I_POP or I_PUSH.
   644 		 */
   713 		 */
   645 #ifdef DEBUG
   714 #ifdef DEBUG
   646 		cmn_err(CE_WARN, "Unsupported STREAMS ioctl 0x%x on socket. "
   715 		cmn_err(CE_WARN, "Unsupported STREAMS ioctl 0x%x on socket. "
   647 		    "Pid = %d\n", cmd, curproc->p_pid);
   716 		    "Pid = %d\n", cmd, curproc->p_pid);
   648 #endif /* DEBUG */
   717 #endif /* DEBUG */
   722 		return (strioctl(vp, cmd, arg, mode, U_TO_K, cr, rvalp));
   791 		return (strioctl(vp, cmd, arg, mode, U_TO_K, cr, rvalp));
   723 	}
   792 	}
   724 
   793 
   725 	switch (cmd) {
   794 	switch (cmd) {
   726 	case I_PUSH:
   795 	case I_PUSH:
       
   796 		if (so->so_state & SS_DIRECT) {
       
   797 			mutex_enter(&so->so_lock);
       
   798 			so_lock_single(so);
       
   799 			mutex_exit(&so->so_lock);
       
   800 
       
   801 			error = strioctl(vp, _SIOCSOCKFALLBACK, 0, 0, K_TO_K,
       
   802 			    CRED(), rvalp);
       
   803 
       
   804 			mutex_enter(&so->so_lock);
       
   805 			if (error == 0)
       
   806 				so->so_state &= ~SS_DIRECT;
       
   807 			so_unlock_single(so, SOLOCKED);
       
   808 			mutex_exit(&so->so_lock);
       
   809 
       
   810 			if (error != 0)
       
   811 				return (error);
       
   812 		}
       
   813 
   727 		error = strioctl(vp, cmd, arg, mode, U_TO_K, cr, rvalp);
   814 		error = strioctl(vp, cmd, arg, mode, U_TO_K, cr, rvalp);
   728 		if (error == 0)
   815 		if (error == 0)
   729 			so->so_pushcnt++;
   816 			so->so_pushcnt++;
   730 		return (error);
   817 		return (error);
   731 
   818