0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning/*
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning * CDDL HEADER START
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning *
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning * The contents of this file are subject to the terms of the
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning * Common Development and Distribution License (the "License").
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning * You may not use this file except in compliance with the License.
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning *
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning * or http://www.opensolaris.org/os/licensing.
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning * See the License for the specific language governing permissions
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning * and limitations under the License.
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning *
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning * When distributing Covered Code, include this CDDL HEADER in each
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning * If applicable, add the following below this CDDL HEADER, with the
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning * fields enclosed by brackets "[]" replaced with your own identifying
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning * information: Portions Copyright [yyyy] [name of copyright owner]
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning *
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning * CDDL HEADER END
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning */
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning/*
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning * Use is subject to license terms.
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning */
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning#include <sys/types.h>
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning#include <sys/t_lock.h>
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning#include <sys/param.h>
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning#include <sys/systm.h>
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning#include <sys/bitmap.h>
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning#include <sys/debug.h>
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning#include <sys/errno.h>
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning#include <sys/strsubr.h>
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning#include <sys/cmn_err.h>
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning#include <sys/sysmacros.h>
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning#include <sys/filio.h>
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning#include <sys/flock.h>
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning#include <sys/stat.h>
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning#include <sys/share.h>
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning#include <sys/vfs.h>
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning#include <sys/vfs_opreg.h>
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning#include <sys/sockio.h>
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning#include <sys/socket.h>
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning#include <sys/socketvar.h>
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning#include <sys/strsun.h>
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning#include <fs/sockfs/sockcommon.h>
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning#include <fs/sockfs/socktpi.h>
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning/*
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning * Generic vnode ops
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning */
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangningstatic int socket_vop_open(struct vnode **, int, struct cred *,
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning caller_context_t *);
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangningstatic int socket_vop_close(struct vnode *, int, int, offset_t,
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning struct cred *, caller_context_t *);
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangningstatic int socket_vop_read(struct vnode *, struct uio *, int,
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning struct cred *, caller_context_t *);
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangningstatic int socket_vop_write(struct vnode *, struct uio *, int,
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning struct cred *, caller_context_t *);
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangningstatic int socket_vop_ioctl(struct vnode *, int, intptr_t, int,
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning struct cred *, int32_t *, caller_context_t *);
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangningstatic int socket_vop_setfl(struct vnode *, int, int, cred_t *,
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning caller_context_t *);
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangningstatic int socket_vop_getattr(struct vnode *, struct vattr *, int,
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning struct cred *, caller_context_t *);
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangningstatic int socket_vop_setattr(struct vnode *, struct vattr *, int,
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning struct cred *, caller_context_t *);
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangningstatic int socket_vop_access(struct vnode *, int, int, struct cred *,
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning caller_context_t *);
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangningstatic int socket_vop_fsync(struct vnode *, int, struct cred *,
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning caller_context_t *);
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangningstatic void socket_vop_inactive(struct vnode *, struct cred *,
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning caller_context_t *);
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangningstatic int socket_vop_fid(struct vnode *, struct fid *,
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning caller_context_t *);
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangningstatic int socket_vop_seek(struct vnode *, offset_t, offset_t *,
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning caller_context_t *);
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangningstatic int socket_vop_poll(struct vnode *, short, int, short *,
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning struct pollhead **, caller_context_t *);
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangningextern int socket_close_internal(struct sonode *, int, cred_t *);
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangningextern void socket_destroy_internal(struct sonode *, cred_t *);
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangningstruct vnodeops *socket_vnodeops;
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangningconst fs_operation_def_t socket_vnodeops_template[] = {
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning VOPNAME_OPEN, { .vop_open = socket_vop_open },
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning VOPNAME_CLOSE, { .vop_close = socket_vop_close },
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning VOPNAME_READ, { .vop_read = socket_vop_read },
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning VOPNAME_WRITE, { .vop_write = socket_vop_write },
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning VOPNAME_IOCTL, { .vop_ioctl = socket_vop_ioctl },
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning VOPNAME_SETFL, { .vop_setfl = socket_vop_setfl },
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning VOPNAME_GETATTR, { .vop_getattr = socket_vop_getattr },
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning VOPNAME_SETATTR, { .vop_setattr = socket_vop_setattr },
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning VOPNAME_ACCESS, { .vop_access = socket_vop_access },
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning VOPNAME_FSYNC, { .vop_fsync = socket_vop_fsync },
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning VOPNAME_INACTIVE, { .vop_inactive = socket_vop_inactive },
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning VOPNAME_FID, { .vop_fid = socket_vop_fid },
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning VOPNAME_SEEK, { .vop_seek = socket_vop_seek },
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning VOPNAME_POLL, { .vop_poll = socket_vop_poll },
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning VOPNAME_DISPOSE, { .error = fs_error },
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning NULL, NULL
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning};
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning/*
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning * generic vnode ops
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning */
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning/*ARGSUSED*/
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangningstatic int
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangningsocket_vop_open(struct vnode **vpp, int flag, struct cred *cr,
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning caller_context_t *ct)
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning{
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning struct vnode *vp = *vpp;
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning struct sonode *so = VTOSO(vp);
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning flag &= ~FCREAT; /* paranoia */
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning mutex_enter(&so->so_lock);
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning so->so_count++;
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning mutex_exit(&so->so_lock);
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning ASSERT(so->so_count != 0); /* wraparound */
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning ASSERT(vp->v_type == VSOCK);
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning return (0);
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning}
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning/*ARGSUSED*/
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangningstatic int
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangningsocket_vop_close(struct vnode *vp, int flag, int count, offset_t offset,
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning struct cred *cr, caller_context_t *ct)
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning{
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning struct sonode *so;
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning int error = 0;
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning so = VTOSO(vp);
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning ASSERT(vp->v_type == VSOCK);
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning cleanlocks(vp, ttoproc(curthread)->p_pid, 0);
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning cleanshares(vp, ttoproc(curthread)->p_pid);
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning if (vp->v_stream)
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning strclean(vp);
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning if (count > 1) {
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning dprint(2, ("socket_vop_close: count %d\n", count));
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning return (0);
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning }
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning mutex_enter(&so->so_lock);
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning if (--so->so_count == 0) {
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning /*
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning * Initiate connection shutdown.
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning */
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning mutex_exit(&so->so_lock);
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning error = socket_close_internal(so, flag, cr);
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning } else {
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning mutex_exit(&so->so_lock);
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning }
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning return (error);
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning}
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning/*ARGSUSED2*/
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangningstatic int
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangningsocket_vop_read(struct vnode *vp, struct uio *uiop, int ioflag, struct cred *cr,
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning caller_context_t *ct)
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning{
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning struct sonode *so = VTOSO(vp);
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning struct nmsghdr lmsg;
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning ASSERT(vp->v_type == VSOCK);
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning bzero((void *)&lmsg, sizeof (lmsg));
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning return (socket_recvmsg(so, &lmsg, uiop, cr));
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning}
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning/*ARGSUSED2*/
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangningstatic int
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangningsocket_vop_write(struct vnode *vp, struct uio *uiop, int ioflag,
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning struct cred *cr, caller_context_t *ct)
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning{
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning struct sonode *so = VTOSO(vp);
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning struct nmsghdr lmsg;
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning ASSERT(vp->v_type == VSOCK);
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning bzero((void *)&lmsg, sizeof (lmsg));
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning if (!(so->so_mode & SM_BYTESTREAM)) {
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning /*
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning * If the socket is not byte stream set MSG_EOR
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning */
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning lmsg.msg_flags = MSG_EOR;
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning }
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning return (socket_sendmsg(so, &lmsg, uiop, cr));
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning}
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning/*ARGSUSED4*/
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangningstatic int
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangningsocket_vop_ioctl(struct vnode *vp, int cmd, intptr_t arg, int mode,
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning struct cred *cr, int32_t *rvalp, caller_context_t *ct)
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning{
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning struct sonode *so = VTOSO(vp);
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning ASSERT(vp->v_type == VSOCK);
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning return (socket_ioctl(so, cmd, arg, mode, cr, rvalp));
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning}
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning/*
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning * Allow any flags. Record FNDELAY and FNONBLOCK so that they can be inherited
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning * from listener to acceptor.
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning */
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning/* ARGSUSED */
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangningstatic int
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangningsocket_vop_setfl(vnode_t *vp, int oflags, int nflags, cred_t *cr,
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning caller_context_t *ct)
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning{
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning struct sonode *so = VTOSO(vp);
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning int error = 0;
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning ASSERT(vp->v_type == VSOCK);
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning mutex_enter(&so->so_lock);
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning if (nflags & FNDELAY)
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning so->so_state |= SS_NDELAY;
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning else
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning so->so_state &= ~SS_NDELAY;
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning if (nflags & FNONBLOCK)
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning so->so_state |= SS_NONBLOCK;
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning else
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning so->so_state &= ~SS_NONBLOCK;
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning mutex_exit(&so->so_lock);
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning if (so->so_state & SS_ASYNC)
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning oflags |= FASYNC;
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning /*
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning * Sets/clears the SS_ASYNC flag based on the presence/absence
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning * of the FASYNC flag passed to fcntl(F_SETFL).
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning * This exists solely for BSD fcntl() FASYNC compatibility.
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning */
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning if ((oflags ^ nflags) & FASYNC && so->so_version != SOV_STREAM) {
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning int async = nflags & FASYNC;
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning int32_t rv;
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning /*
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning * For non-TPI sockets all we have to do is set/remove the
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning * SS_ASYNC bit, but for TPI it is more involved. For that
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning * reason we delegate the job to the protocol's ioctl handler.
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning */
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning error = socket_ioctl(so, FIOASYNC, (intptr_t)&async, FKIOCTL,
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning cr, &rv);
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning }
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning return (error);
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning}
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning/*
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning * Get the made up attributes for the vnode.
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning * 4.3BSD returns the current time for all the timestamps.
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning * 4.4BSD returns 0 for all the timestamps.
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning * Here we use the access and modified times recorded in the sonode.
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning *
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning * Just like in BSD there is not effect on the underlying file system node
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning * bound to an AF_UNIX pathname.
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning *
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning * When sockmod has been popped this will act just like a stream. Since
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning * a socket is always a clone there is no need to inspect the attributes
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning * of the "realvp".
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning */
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning/* ARGSUSED */
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangningint
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangningsocket_vop_getattr(struct vnode *vp, struct vattr *vap, int flags,
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning struct cred *cr, caller_context_t *ct)
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning{
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning dev_t fsid;
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning struct sonode *so;
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning static int sonode_shift = 0;
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning /*
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning * Calculate the amount of bitshift to a sonode pointer which will
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning * still keep it unique. See below.
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning */
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning if (sonode_shift == 0)
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning sonode_shift = highbit(sizeof (struct sonode));
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning ASSERT(sonode_shift > 0);
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning so = VTOSO(vp);
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning fsid = sockdev;
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning if (so->so_version == SOV_STREAM) {
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning /*
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning * The imaginary "sockmod" has been popped - act
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning * as a stream
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning */
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning vap->va_type = VCHR;
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning vap->va_mode = 0;
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning } else {
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning vap->va_type = vp->v_type;
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning vap->va_mode = S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning S_IROTH|S_IWOTH;
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning }
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning vap->va_uid = vap->va_gid = 0;
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning vap->va_fsid = fsid;
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning /*
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning * If the va_nodeid is > MAX_USHORT, then i386 stats might fail.
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning * So we shift down the sonode pointer to try and get the most
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning * uniqueness into 16-bits.
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning */
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning vap->va_nodeid = ((ino_t)so >> sonode_shift) & 0xFFFF;
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning vap->va_nlink = 0;
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning vap->va_size = 0;
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning /*
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning * We need to zero out the va_rdev to avoid some fstats getting
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning * EOVERFLOW. This also mimics SunOS 4.x and BSD behavior.
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning */
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning vap->va_rdev = (dev_t)0;
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning vap->va_blksize = MAXBSIZE;
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning vap->va_nblocks = btod(vap->va_size);
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning if (!SOCK_IS_NONSTR(so)) {
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning sotpi_info_t *sti = SOTOTPI(so);
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning mutex_enter(&so->so_lock);
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning vap->va_atime.tv_sec = sti->sti_atime;
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning vap->va_mtime.tv_sec = sti->sti_mtime;
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning vap->va_ctime.tv_sec = sti->sti_ctime;
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning mutex_exit(&so->so_lock);
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning } else {
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning vap->va_atime.tv_sec = 0;
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning vap->va_mtime.tv_sec = 0;
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning vap->va_ctime.tv_sec = 0;
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning }
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning vap->va_atime.tv_nsec = 0;
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning vap->va_mtime.tv_nsec = 0;
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning vap->va_ctime.tv_nsec = 0;
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning vap->va_seq = 0;
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning return (0);
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning}
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning/*
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning * Set attributes.
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning * Just like in BSD there is not effect on the underlying file system node
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning * bound to an AF_UNIX pathname.
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning *
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning * When sockmod has been popped this will act just like a stream. Since
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning * a socket is always a clone there is no need to modify the attributes
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning * of the "realvp".
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning */
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning/* ARGSUSED */
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangningint
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangningsocket_vop_setattr(struct vnode *vp, struct vattr *vap, int flags,
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning struct cred *cr, caller_context_t *ct)
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning{
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning struct sonode *so = VTOSO(vp);
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning /*
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning * If times were changed, and we have a STREAMS socket, then update
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning * the sonode.
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning */
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning if (!SOCK_IS_NONSTR(so)) {
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning sotpi_info_t *sti = SOTOTPI(so);
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning mutex_enter(&so->so_lock);
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning if (vap->va_mask & AT_ATIME)
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning sti->sti_atime = vap->va_atime.tv_sec;
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning if (vap->va_mask & AT_MTIME) {
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning sti->sti_mtime = vap->va_mtime.tv_sec;
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning sti->sti_ctime = gethrestime_sec();
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning }
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning mutex_exit(&so->so_lock);
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning }
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning return (0);
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning}
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning/*
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning * Check if user is allowed to access vp. For non-STREAMS based sockets,
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning * there might not be a device attached to the file system. So for those
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning * types of sockets there are no permissions to check.
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning *
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning * XXX Should there be some other mechanism to check access rights?
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning */
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning/*ARGSUSED*/
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangningint
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangningsocket_vop_access(struct vnode *vp, int mode, int flags, struct cred *cr,
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning caller_context_t *ct)
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning{
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning struct sonode *so = VTOSO(vp);
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning if (!SOCK_IS_NONSTR(so)) {
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning ASSERT(so->so_sockparams->sp_sdev_info.sd_vnode != NULL);
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning return (VOP_ACCESS(so->so_sockparams->sp_sdev_info.sd_vnode,
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning mode, flags, cr, NULL));
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning }
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning return (0);
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning}
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning/*
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning * 4.3BSD and 4.4BSD fail a fsync on a socket with EINVAL.
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning * This code does the same to be compatible and also to not give an
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning * application the impression that the data has actually been "synced"
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning * to the other end of the connection.
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning */
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning/* ARGSUSED */
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangningint
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangningsocket_vop_fsync(struct vnode *vp, int syncflag, struct cred *cr,
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning caller_context_t *ct)
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning{
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning return (EINVAL);
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning}
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning/*ARGSUSED*/
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangningstatic void
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangningsocket_vop_inactive(struct vnode *vp, struct cred *cr, caller_context_t *ct)
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning{
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning struct sonode *so = VTOSO(vp);
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning ASSERT(vp->v_type == VSOCK);
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning mutex_enter(&vp->v_lock);
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning /*
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning * If no one has reclaimed the vnode, remove from the
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning * cache now.
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning */
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning if (vp->v_count < 1)
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning cmn_err(CE_PANIC, "socket_inactive: Bad v_count");
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning /*
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning * Drop the temporary hold by vn_rele now
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning */
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning if (--vp->v_count != 0) {
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning mutex_exit(&vp->v_lock);
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning return;
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning }
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning mutex_exit(&vp->v_lock);
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning ASSERT(!vn_has_cached_data(vp));
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning /* socket specfic clean-up */
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning socket_destroy_internal(so, cr);
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning}
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning/* ARGSUSED */
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangningint
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangningsocket_vop_fid(struct vnode *vp, struct fid *fidp, caller_context_t *ct)
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning{
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning return (EINVAL);
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning}
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning/*
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning * Sockets are not seekable.
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning * (and there is a bug to fix STREAMS to make them fail this as well).
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning */
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning/*ARGSUSED*/
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangningint
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangningsocket_vop_seek(struct vnode *vp, offset_t ooff, offset_t *noffp,
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning caller_context_t *ct)
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning{
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning return (ESPIPE);
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning}
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning/*ARGSUSED*/
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangningstatic int
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangningsocket_vop_poll(struct vnode *vp, short events, int anyyet, short *reventsp,
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning struct pollhead **phpp, caller_context_t *ct)
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning{
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning struct sonode *so = VTOSO(vp);
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning ASSERT(vp->v_type == VSOCK);
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning return (socket_poll(so, events, anyyet, reventsp, phpp));
0f1702c5201310f0529cd5abb77652e5e9b241b6Yu Xiangning}