4bff34e37def8a90f9194d81bc345c52ba20086athurlow/*
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Copyright (c) 2000-2001 Boris Popov
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * All rights reserved.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow *
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Redistribution and use in source and binary forms, with or without
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * modification, are permitted provided that the following conditions
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * are met:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * 1. Redistributions of source code must retain the above copyright
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * notice, this list of conditions and the following disclaimer.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * 2. Redistributions in binary form must reproduce the above copyright
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * notice, this list of conditions and the following disclaimer in the
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * documentation and/or other materials provided with the distribution.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * 3. All advertising materials mentioning features or use of this software
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * must display the following acknowledgement:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * This product includes software developed by Boris Popov.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * 4. Neither the name of the author nor the names of any co-contributors
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * may be used to endorse or promote products derived from this software
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * without specific prior written permission.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow *
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * SUCH DAMAGE.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow *
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * $Id: smb_conn.c,v 1.27.166.1 2005/05/27 02:35:29 lindak Exp $
4bff34e37def8a90f9194d81bc345c52ba20086athurlow */
6723e17f4e092e7f275f0791f9fce3ea061339d7Gordon Ross/*
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
6723e17f4e092e7f275f0791f9fce3ea061339d7Gordon Ross * Use is subject to license terms.
6723e17f4e092e7f275f0791f9fce3ea061339d7Gordon Ross */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow/*
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Connection engine.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#include <sys/param.h>
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#include <sys/systm.h>
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#include <sys/kmem.h>
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#include <sys/proc.h>
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#include <sys/lock.h>
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#include <sys/vnode.h>
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#include <sys/stream.h>
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#include <sys/stropts.h>
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#include <sys/socketvar.h>
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#include <sys/cred.h>
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#include <netinet/in.h>
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#include <inet/ip.h>
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#include <inet/ip6.h>
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#include <sys/cmn_err.h>
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#include <sys/thread.h>
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#include <sys/atomic.h>
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross#include <sys/u8_textprep.h>
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#include <netsmb/smb_osdep.h>
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#include <netsmb/smb.h>
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#include <netsmb/smb_conn.h>
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#include <netsmb/smb_subr.h>
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#include <netsmb/smb_tran.h>
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#include <netsmb/smb_pass.h>
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlowstatic struct smb_connobj smb_vclist;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlowvoid smb_co_init(struct smb_connobj *cp, int level, char *objname);
4bff34e37def8a90f9194d81bc345c52ba20086athurlowvoid smb_co_done(struct smb_connobj *cp);
4bff34e37def8a90f9194d81bc345c52ba20086athurlowvoid smb_co_hold(struct smb_connobj *cp);
4bff34e37def8a90f9194d81bc345c52ba20086athurlowvoid smb_co_rele(struct smb_connobj *cp);
4bff34e37def8a90f9194d81bc345c52ba20086athurlowvoid smb_co_kill(struct smb_connobj *cp);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlowstatic void smb_vc_free(struct smb_connobj *cp);
4bff34e37def8a90f9194d81bc345c52ba20086athurlowstatic void smb_vc_gone(struct smb_connobj *cp);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlowstatic void smb_share_free(struct smb_connobj *cp);
4bff34e37def8a90f9194d81bc345c52ba20086athurlowstatic void smb_share_gone(struct smb_connobj *cp);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlowint
4bff34e37def8a90f9194d81bc345c52ba20086athurlowsmb_sm_init(void)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow{
4bff34e37def8a90f9194d81bc345c52ba20086athurlow smb_co_init(&smb_vclist, SMBL_SM, "smbsm");
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return (0);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow}
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlowint
4bff34e37def8a90f9194d81bc345c52ba20086athurlowsmb_sm_idle(void)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow{
4bff34e37def8a90f9194d81bc345c52ba20086athurlow int error = 0;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow SMB_CO_LOCK(&smb_vclist);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if (smb_vclist.co_usecount > 1) {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow SMBSDEBUG("%d connections still active\n",
4bff34e37def8a90f9194d81bc345c52ba20086athurlow smb_vclist.co_usecount - 1);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow error = EBUSY;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow SMB_CO_UNLOCK(&smb_vclist);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return (error);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow}
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlowvoid
4bff34e37def8a90f9194d81bc345c52ba20086athurlowsmb_sm_done(void)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow{
4bff34e37def8a90f9194d81bc345c52ba20086athurlow /*
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * XXX Q4BP why are we not iterating on smb_vclist here?
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Because the caller has just called smb_sm_idle() to
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * make sure we have no VCs before calling this.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow smb_co_done(&smb_vclist);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow}
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow/*
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Common code for connection object
4bff34e37def8a90f9194d81bc345c52ba20086athurlow */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow/*ARGSUSED*/
4bff34e37def8a90f9194d81bc345c52ba20086athurlowvoid
4bff34e37def8a90f9194d81bc345c52ba20086athurlowsmb_co_init(struct smb_connobj *cp, int level, char *objname)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow{
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow mutex_init(&cp->co_lock, objname, MUTEX_DRIVER, NULL);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow cp->co_level = level;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow cp->co_usecount = 1;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow SLIST_INIT(&cp->co_children);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow}
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow/*
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Called just before free of an object
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * of which smb_connobj is a part, i.e.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * _vc_free, _share_free, also sm_done.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow */
4bff34e37def8a90f9194d81bc345c52ba20086athurlowvoid
4bff34e37def8a90f9194d81bc345c52ba20086athurlowsmb_co_done(struct smb_connobj *cp)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow{
4bff34e37def8a90f9194d81bc345c52ba20086athurlow ASSERT(SLIST_EMPTY(&cp->co_children));
4bff34e37def8a90f9194d81bc345c52ba20086athurlow mutex_destroy(&cp->co_lock);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow}
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlowstatic void
4bff34e37def8a90f9194d81bc345c52ba20086athurlowsmb_co_addchild(
4bff34e37def8a90f9194d81bc345c52ba20086athurlow struct smb_connobj *parent,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow struct smb_connobj *child)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow{
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow /*
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Set the child's pointer to the parent.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * No references yet, so no need to lock.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow ASSERT(child->co_usecount == 1);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow child->co_parent = parent;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow /*
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Add the child to the parent's list of
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * children, and in-line smb_co_hold
4bff34e37def8a90f9194d81bc345c52ba20086athurlow */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow ASSERT(MUTEX_HELD(&parent->co_lock));
4bff34e37def8a90f9194d81bc345c52ba20086athurlow parent->co_usecount++;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow SLIST_INSERT_HEAD(&parent->co_children, child, co_next);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow}
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlowvoid
4bff34e37def8a90f9194d81bc345c52ba20086athurlowsmb_co_hold(struct smb_connobj *cp)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow{
4bff34e37def8a90f9194d81bc345c52ba20086athurlow SMB_CO_LOCK(cp);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow cp->co_usecount++;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow SMB_CO_UNLOCK(cp);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow}
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow/*
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Called via smb_vc_rele, smb_share_rele
4bff34e37def8a90f9194d81bc345c52ba20086athurlow */
4bff34e37def8a90f9194d81bc345c52ba20086athurlowvoid
4bff34e37def8a90f9194d81bc345c52ba20086athurlowsmb_co_rele(struct smb_connobj *co)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow{
4bff34e37def8a90f9194d81bc345c52ba20086athurlow struct smb_connobj *parent;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow int old_flags;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow SMB_CO_LOCK(co);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if (co->co_usecount > 1) {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow co->co_usecount--;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow SMB_CO_UNLOCK(co);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow ASSERT(co->co_usecount == 1);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow co->co_usecount = 0;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow /*
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * This list of children should be empty now.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Check this while we're still linked, so
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * we have a better chance of debugging.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow ASSERT(SLIST_EMPTY(&co->co_children));
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow /*
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * OK, this element is going away.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow *
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * We need to drop the lock on this CO so we can take the
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * parent CO lock. The _GONE flag prevents this CO from
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * getting new references before we can unlink it from the
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * parent list.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow *
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * The _GONE flag is also used to ensure that the co_gone
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * function is called only once. Note that smb_co_kill may
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * do this before we get here. If we find that the _GONE
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * flag was not already set, then call the co_gone hook
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * (smb_share_gone, smb_vc_gone) which will disconnect
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * the share or the VC, respectively.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow *
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Note the old: smb_co_gone(co, scred);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * is now in-line here.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow old_flags = co->co_flags;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow co->co_flags |= SMBO_GONE;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow SMB_CO_UNLOCK(co);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ((old_flags & SMBO_GONE) == 0 && co->co_gone)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow co->co_gone(co);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow /*
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * If we have a parent (only smb_vclist does not)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * then unlink from parent's list of children.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * We have the only reference to the child.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow parent = co->co_parent;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if (parent) {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow SMB_CO_LOCK(parent);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow ASSERT(SLIST_FIRST(&parent->co_children));
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if (SLIST_FIRST(&parent->co_children)) {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow SLIST_REMOVE(&parent->co_children, co,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow smb_connobj, co_next);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow SMB_CO_UNLOCK(parent);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow /*
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Now it's safe to free the CO
4bff34e37def8a90f9194d81bc345c52ba20086athurlow */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if (co->co_free) {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow co->co_free(co);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow /*
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Finally, if the CO had a parent, decrement
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * the parent's hold count for the lost child.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if (parent) {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow /*
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Recursive call here (easier for debugging).
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Can only go two levels.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow smb_co_rele(parent);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow}
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow/*
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Do just the first part of what co_gone does,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * i.e. tree disconnect, or disconnect a VC.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * This is used to forcibly close things.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow */
4bff34e37def8a90f9194d81bc345c52ba20086athurlowvoid
4bff34e37def8a90f9194d81bc345c52ba20086athurlowsmb_co_kill(struct smb_connobj *co)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow{
4bff34e37def8a90f9194d81bc345c52ba20086athurlow int old_flags;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow SMB_CO_LOCK(co);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow old_flags = co->co_flags;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow co->co_flags |= SMBO_GONE;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow SMB_CO_UNLOCK(co);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow /*
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Do the same "call only once" logic here as in
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * smb_co_rele, though it's probably not possible
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * for this to be called after smb_co_rele.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ((old_flags & SMBO_GONE) == 0 && co->co_gone)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow co->co_gone(co);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow /* XXX: Walk list of children and kill those too? */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow}
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow/*
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * Session objects, which are referred to as "VC" for
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * "virtual cirtuit". This has nothing to do with the
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * CIFS notion of a "virtual cirtuit". See smb_conn.h
4bff34e37def8a90f9194d81bc345c52ba20086athurlow */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Rossvoid
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Rosssmb_vc_hold(struct smb_vc *vcp)
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross{
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross smb_co_hold(VCTOCP(vcp));
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross}
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Rossvoid
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Rosssmb_vc_rele(struct smb_vc *vcp)
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross{
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross smb_co_rele(VCTOCP(vcp));
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross}
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Rossvoid
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Rosssmb_vc_kill(struct smb_vc *vcp)
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross{
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross smb_co_kill(VCTOCP(vcp));
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross}
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross
4bff34e37def8a90f9194d81bc345c52ba20086athurlow/*
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * Normally called via smb_vc_rele()
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * after co_usecount drops to zero.
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * Also called via: smb_vc_kill()
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross *
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * Shutdown the VC to this server,
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * invalidate shares linked with it.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow */
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross/*ARGSUSED*/
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Rossstatic void
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Rosssmb_vc_gone(struct smb_connobj *cp)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow{
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross struct smb_vc *vcp = CPTOVC(cp);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross /*
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * Was smb_vc_disconnect(vcp);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross */
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross smb_iod_disconnect(vcp);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross}
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross/*
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * The VC has no more references. Free it.
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * No locks needed here.
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross */
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Rossstatic void
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Rosssmb_vc_free(struct smb_connobj *cp)
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross{
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross struct smb_vc *vcp = CPTOVC(cp);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross /*
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * The _gone call should have emptied the request list,
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * but let's make sure, as requests may have references
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * to this VC without taking a hold. (The hold is the
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * responsibility of threads placing requests.)
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross */
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross ASSERT(vcp->iod_rqlist.tqh_first == NULL);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross if (vcp->vc_tdata)
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross SMB_TRAN_DONE(vcp);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross/*
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * We are not using the iconv routines here. So commenting them for now.
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * REVISIT.
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross */
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross#ifdef NOTYETDEFINED
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross if (vcp->vc_tolower)
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross iconv_close(vcp->vc_tolower);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross if (vcp->vc_toupper)
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross iconv_close(vcp->vc_toupper);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross if (vcp->vc_tolocal)
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross iconv_close(vcp->vc_tolocal);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross if (vcp->vc_toserver)
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross iconv_close(vcp->vc_toserver);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross#endif
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross if (vcp->vc_mackey != NULL)
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross kmem_free(vcp->vc_mackey, vcp->vc_mackeylen);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross cv_destroy(&vcp->iod_idle);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross rw_destroy(&vcp->iod_rqlock);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross sema_destroy(&vcp->vc_sendlock);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross cv_destroy(&vcp->vc_statechg);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross smb_co_done(VCTOCP(vcp));
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross kmem_free(vcp, sizeof (*vcp));
4bff34e37def8a90f9194d81bc345c52ba20086athurlow}
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow/*ARGSUSED*/
4bff34e37def8a90f9194d81bc345c52ba20086athurlowint
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Rosssmb_vc_create(smbioc_ossn_t *ossn, smb_cred_t *scred, smb_vc_t **vcpp)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow{
4bff34e37def8a90f9194d81bc345c52ba20086athurlow static char objtype[] = "smb_vc";
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross cred_t *cr = scred->scr_cred;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow struct smb_vc *vcp;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow int error = 0;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow ASSERT(MUTEX_HELD(&smb_vclist.co_lock));
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow vcp = kmem_zalloc(sizeof (struct smb_vc), KM_SLEEP);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow smb_co_init(VCTOCP(vcp), SMBL_VC, objtype);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow vcp->vc_co.co_free = smb_vc_free;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow vcp->vc_co.co_gone = smb_vc_gone;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow cv_init(&vcp->vc_statechg, objtype, CV_DRIVER, NULL);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow sema_init(&vcp->vc_sendlock, 1, objtype, SEMA_DRIVER, NULL);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow rw_init(&vcp->iod_rqlock, objtype, RW_DRIVER, NULL);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross cv_init(&vcp->iod_idle, objtype, CV_DRIVER, NULL);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross /* Expanded TAILQ_HEAD_INITIALIZER */
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross vcp->iod_rqlist.tqh_last = &vcp->iod_rqlist.tqh_first;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross vcp->vc_state = SMBIOD_ST_IDLE;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow /*
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * These identify the connection.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow vcp->vc_zoneid = getzoneid();
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross bcopy(ossn, &vcp->vc_ssn, sizeof (*ossn));
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow /* This fills in vcp->vc_tdata */
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross vcp->vc_tdesc = &smb_tran_nbtcp_desc;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross if ((error = SMB_TRAN_CREATE(vcp, cr)) != 0)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow goto errout;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow /* Success! */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow smb_co_addchild(&smb_vclist, VCTOCP(vcp));
4bff34e37def8a90f9194d81bc345c52ba20086athurlow *vcpp = vcp;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return (0);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlowerrout:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow /*
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * This will destroy the new vc.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * See: smb_vc_free
4bff34e37def8a90f9194d81bc345c52ba20086athurlow */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow smb_vc_rele(vcp);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return (error);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow}
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow/*
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * Find or create a VC identified by the info in ossn
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * and return it with a "hold", but not locked.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow/*ARGSUSED*/
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Rossint
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Rosssmb_vc_findcreate(smbioc_ossn_t *ossn, smb_cred_t *scred, smb_vc_t **vcpp)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow{
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross struct smb_connobj *co;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross struct smb_vc *vcp;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross smbioc_ssn_ident_t *vc_id;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross int error;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross zoneid_t zoneid = getzoneid();
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross *vcpp = vcp = NULL;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross SMB_CO_LOCK(&smb_vclist);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross /* var, head, next_field */
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross SLIST_FOREACH(co, &smb_vclist.co_children, co_next) {
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross vcp = CPTOVC(co);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross /*
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * Some things we can check without
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * holding the lock (those that are
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * set at creation and never change).
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross /* VCs in other zones are invisibile. */
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross if (vcp->vc_zoneid != zoneid)
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross continue;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross /* Also segregate by Unix owner. */
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross if (vcp->vc_owner != ossn->ssn_owner)
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross continue;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross /*
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * Compare identifying info:
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * server address, user, domain
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * names are case-insensitive
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross */
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross vc_id = &vcp->vc_ssn.ssn_id;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross if (bcmp(&vc_id->id_srvaddr,
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross &ossn->ssn_id.id_srvaddr,
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross sizeof (vc_id->id_srvaddr)))
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross continue;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross if (u8_strcmp(vc_id->id_user, ossn->ssn_id.id_user, 0,
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross U8_STRCMP_CI_LOWER, U8_UNICODE_LATEST, &error))
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross continue;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross if (u8_strcmp(vc_id->id_domain, ossn->ssn_id.id_domain, 0,
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross U8_STRCMP_CI_LOWER, U8_UNICODE_LATEST, &error))
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross continue;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross /*
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * We have a match, but still have to check
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * the _GONE flag, and do that with a lock.
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * No new references when _GONE is set.
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross *
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * Also clear SMBVOPT_CREATE which the caller
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * may check to find out if we did create.
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross */
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross SMB_VC_LOCK(vcp);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross if ((vcp->vc_flags & SMBV_GONE) == 0) {
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross ossn->ssn_vopt &= ~SMBVOPT_CREATE;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross /*
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * Return it held, unlocked.
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * In-line smb_vc_hold here.
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross */
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross co->co_usecount++;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross SMB_VC_UNLOCK(vcp);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross *vcpp = vcp;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross error = 0;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross goto out;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross }
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross SMB_VC_UNLOCK(vcp);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross /* keep looking. */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross vcp = NULL;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross /* Note: smb_vclist is still locked. */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross if (ossn->ssn_vopt & SMBVOPT_CREATE) {
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross /*
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * Create a new VC. It starts out with
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * hold count = 1, so don't incr. here.
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross */
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross error = smb_vc_create(ossn, scred, &vcp);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross if (error == 0)
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross *vcpp = vcp;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross } else
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross error = ENOENT;
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Rossout:
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross SMB_CO_UNLOCK(&smb_vclist);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross return (error);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow}
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow/*
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * Helper functions that operate on VCs
4bff34e37def8a90f9194d81bc345c52ba20086athurlow */
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross/*
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * Get a pointer to the IP address suitable for passing to Trusted
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * Extensions find_tpc() routine. Used by smbfs_mount_label_policy().
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * Compare this code to nfs_mount_label_policy() if problems arise.
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross */
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Rossvoid *
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Rosssmb_vc_getipaddr(struct smb_vc *vcp, int *ipvers)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow{
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross smbioc_ssn_ident_t *id = &vcp->vc_ssn.ssn_id;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross void *ret;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross switch (id->id_srvaddr.sa.sa_family) {
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross case AF_INET:
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross *ipvers = IPV4_VERSION;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross ret = &id->id_srvaddr.sin.sin_addr;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross break;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross case AF_INET6:
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross *ipvers = IPV6_VERSION;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross ret = &id->id_srvaddr.sin6.sin6_addr;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross break;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross default:
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross SMBSDEBUG("invalid address family %d\n",
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross id->id_srvaddr.sa.sa_family);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross *ipvers = 0;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross ret = NULL;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross break;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross }
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross return (ret);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross}
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Rossvoid
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Rosssmb_vc_walkshares(struct smb_vc *vcp,
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross walk_share_func_t func)
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross{
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross smb_connobj_t *co;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross smb_share_t *ssp;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross /*
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * Walk the share list calling func(ssp, arg)
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross */
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross SMB_VC_LOCK(vcp);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow SLIST_FOREACH(co, &(VCTOCP(vcp)->co_children), co_next) {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow ssp = CPTOSS(co);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross SMB_SS_LOCK(ssp);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross func(ssp);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross SMB_SS_UNLOCK(ssp);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross SMB_VC_UNLOCK(vcp);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow}
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross/*
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * Share implementation
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Rossvoid
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Rosssmb_share_hold(struct smb_share *ssp)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow{
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross smb_co_hold(SSTOCP(ssp));
4bff34e37def8a90f9194d81bc345c52ba20086athurlow}
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Rossvoid
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Rosssmb_share_rele(struct smb_share *ssp)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow{
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross smb_co_rele(SSTOCP(ssp));
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross}
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Rossvoid
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Rosssmb_share_kill(struct smb_share *ssp)
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross{
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross smb_co_kill(SSTOCP(ssp));
4bff34e37def8a90f9194d81bc345c52ba20086athurlow}
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow/*
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * Normally called via smb_share_rele()
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * after co_usecount drops to zero.
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * Also called via: smb_share_kill()
4bff34e37def8a90f9194d81bc345c52ba20086athurlow */
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Rossstatic void
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Rosssmb_share_gone(struct smb_connobj *cp)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow{
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross struct smb_cred scred;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross struct smb_share *ssp = CPTOSS(cp);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross smb_credinit(&scred, NULL);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross smb_iod_shutdown_share(ssp);
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross (void) smb_smb_treedisconnect(ssp, &scred);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross smb_credrele(&scred);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow}
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow/*
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * Normally called via smb_share_rele()
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * after co_usecount drops to zero.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow */
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Rossstatic void
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Rosssmb_share_free(struct smb_connobj *cp)
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross{
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross struct smb_share *ssp = CPTOSS(cp);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross cv_destroy(&ssp->ss_conn_done);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross smb_co_done(SSTOCP(ssp));
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross kmem_free(ssp, sizeof (*ssp));
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross}
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross
4bff34e37def8a90f9194d81bc345c52ba20086athurlow/*
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Allocate share structure and attach it to the given VC
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Connection expected to be locked on entry. Share will be returned
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * in locked state.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow/*ARGSUSED*/
4bff34e37def8a90f9194d81bc345c52ba20086athurlowint
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Rosssmb_share_create(smbioc_tcon_t *tcon, struct smb_vc *vcp,
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross struct smb_share **sspp, struct smb_cred *scred)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow{
4bff34e37def8a90f9194d81bc345c52ba20086athurlow static char objtype[] = "smb_ss";
4bff34e37def8a90f9194d81bc345c52ba20086athurlow struct smb_share *ssp;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow ASSERT(MUTEX_HELD(&vcp->vc_lock));
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow ssp = kmem_zalloc(sizeof (struct smb_share), KM_SLEEP);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow smb_co_init(SSTOCP(ssp), SMBL_SHARE, objtype);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow ssp->ss_co.co_free = smb_share_free;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow ssp->ss_co.co_gone = smb_share_gone;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross cv_init(&ssp->ss_conn_done, objtype, CV_DRIVER, NULL);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow ssp->ss_tid = SMB_TID_UNKNOWN;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross bcopy(&tcon->tc_sh, &ssp->ss_ioc,
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross sizeof (smbioc_oshare_t));
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross
4bff34e37def8a90f9194d81bc345c52ba20086athurlow smb_co_addchild(VCTOCP(vcp), SSTOCP(ssp));
4bff34e37def8a90f9194d81bc345c52ba20086athurlow *sspp = ssp;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return (0);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow}
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow/*
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * Find or create a share under the given VC
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * and return it with a "hold", but not locked.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow */
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Rossint
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Rosssmb_share_findcreate(smbioc_tcon_t *tcon, struct smb_vc *vcp,
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross struct smb_share **sspp, struct smb_cred *scred)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow{
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross struct smb_connobj *co;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross struct smb_share *ssp = NULL;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross int error = 0;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross *sspp = NULL;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross SMB_VC_LOCK(vcp);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross /* var, head, next_field */
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross SLIST_FOREACH(co, &(VCTOCP(vcp)->co_children), co_next) {
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross ssp = CPTOSS(co);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross /* Share name */
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross if (u8_strcmp(ssp->ss_name, tcon->tc_sh.sh_name, 0,
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross U8_STRCMP_CI_LOWER, U8_UNICODE_LATEST, &error))
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross continue;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross /*
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * We have a match, but still have to check
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * the _GONE flag, and do that with a lock.
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * No new references when _GONE is set.
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross *
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * Also clear SMBSOPT_CREATE which the caller
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * may check to find out if we did create.
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross */
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross SMB_SS_LOCK(ssp);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross if ((ssp->ss_flags & SMBS_GONE) == 0) {
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross tcon->tc_opt &= ~SMBSOPT_CREATE;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross /*
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * Return it held, unlocked.
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * In-line smb_share_hold here.
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross */
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross co->co_usecount++;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross SMB_SS_UNLOCK(ssp);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross *sspp = ssp;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross error = 0;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross goto out;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross }
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross SMB_SS_UNLOCK(ssp);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross /* keep looking. */
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross }
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross ssp = NULL;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross /* Note: vcp (list of shares) is still locked. */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross if (tcon->tc_opt & SMBSOPT_CREATE) {
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross /*
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * Create a new share. It starts out with
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * hold count = 1, so don't incr. here.
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross */
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross error = smb_share_create(tcon, vcp, &ssp, scred);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross if (error == 0)
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross *sspp = ssp;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross } else
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross error = ENOENT;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Rossout:
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross SMB_VC_UNLOCK(vcp);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross return (error);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow}
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross
4bff34e37def8a90f9194d81bc345c52ba20086athurlow/*
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * Helper functions that operate on shares
4bff34e37def8a90f9194d81bc345c52ba20086athurlow */
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross/*
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * Mark this share as invalid, so consumers will know
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * their file handles have become invalid.
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross *
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * Most share consumers store a copy of ss_vcgenid when
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * opening a file handle and compare that with what's in
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * the share before using a file handle. If the genid
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * doesn't match, the file handle has become "stale"
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * due to disconnect. Therefore, zap ss_vcgenid here.
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross */
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Rossvoid
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Rosssmb_share_invalidate(struct smb_share *ssp)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow{
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow ASSERT(MUTEX_HELD(&ssp->ss_lock));
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross ssp->ss_flags &= ~SMBS_CONNECTED;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross ssp->ss_tid = SMB_TID_UNKNOWN;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross ssp->ss_vcgenid = 0;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow}
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow/*
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Connect (or reconnect) a share object.
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross *
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * Called by smb_usr_get_tree() for new connections,
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * and called by smb_rq_enqueue() for reconnect.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow */
4bff34e37def8a90f9194d81bc345c52ba20086athurlowint
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Rosssmb_share_tcon(smb_share_t *ssp, smb_cred_t *scred)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow{
4bff34e37def8a90f9194d81bc345c52ba20086athurlow clock_t tmo;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow int error;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross SMB_SS_LOCK(ssp);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if (ssp->ss_flags & SMBS_CONNECTED) {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow SMBIODEBUG("alread connected?");
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross error = 0;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross goto out;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow /*
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Wait for completion of any state changes
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * that might be underway.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow while (ssp->ss_flags & SMBS_RECONNECTING) {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow ssp->ss_conn_waiters++;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow tmo = cv_wait_sig(&ssp->ss_conn_done, &ssp->ss_lock);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow ssp->ss_conn_waiters--;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if (tmo == 0) {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow /* Interrupt! */
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross error = EINTR;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross goto out;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow /* Did someone else do it for us? */
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross if (ssp->ss_flags & SMBS_CONNECTED) {
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross error = 0;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross goto out;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow /*
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * OK, we'll do the work.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow ssp->ss_flags |= SMBS_RECONNECTING;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross /*
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * Drop the lock while doing the TCON.
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * On success, sets ss_tid, ss_vcgenid,
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * and ss_flags |= SMBS_CONNECTED;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow SMB_SS_UNLOCK(ssp);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross error = smb_smb_treeconnect(ssp, scred);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow SMB_SS_LOCK(ssp);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow ssp->ss_flags &= ~SMBS_RECONNECTING;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow /* They can all go ahead! */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if (ssp->ss_conn_waiters)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow cv_broadcast(&ssp->ss_conn_done);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Rossout:
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross SMB_SS_UNLOCK(ssp);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross return (error);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow}
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow/*
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Solaris zones support
4bff34e37def8a90f9194d81bc345c52ba20086athurlow */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow/*ARGSUSED*/
4bff34e37def8a90f9194d81bc345c52ba20086athurlowvoid
4bff34e37def8a90f9194d81bc345c52ba20086athurlowlingering_vc(struct smb_vc *vc)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow{
4bff34e37def8a90f9194d81bc345c52ba20086athurlow /* good place for a breakpoint */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow DEBUG_ENTER("lingering VC");
4bff34e37def8a90f9194d81bc345c52ba20086athurlow}
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow/*
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * On zone shutdown, kill any IOD threads still running in this zone.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow/* ARGSUSED */
4bff34e37def8a90f9194d81bc345c52ba20086athurlowvoid
4bff34e37def8a90f9194d81bc345c52ba20086athurlownsmb_zone_shutdown(zoneid_t zoneid, void *data)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow{
4bff34e37def8a90f9194d81bc345c52ba20086athurlow struct smb_connobj *co;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow struct smb_vc *vcp;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow SMB_CO_LOCK(&smb_vclist);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow SLIST_FOREACH(co, &smb_vclist.co_children, co_next) {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow vcp = CPTOVC(co);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if (vcp->vc_zoneid != zoneid)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow continue;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow /*
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * This will close the connection, and
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * cause the IOD thread to terminate.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow smb_vc_kill(vcp);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow SMB_CO_UNLOCK(&smb_vclist);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow}
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow/*
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * On zone destroy, kill any IOD threads and free all resources they used.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow/* ARGSUSED */
4bff34e37def8a90f9194d81bc345c52ba20086athurlowvoid
4bff34e37def8a90f9194d81bc345c52ba20086athurlownsmb_zone_destroy(zoneid_t zoneid, void *data)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow{
4bff34e37def8a90f9194d81bc345c52ba20086athurlow struct smb_connobj *co;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow struct smb_vc *vcp;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow /*
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * We will repeat what should have already happened
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * in zone_shutdown to make things go away.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow *
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * There should have been an smb_vc_rele call
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * by now for all VCs in the zone. If not,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * there's probably more we needed to do in
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * the shutdown call.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow SMB_CO_LOCK(&smb_vclist);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if (smb_vclist.co_usecount > 1) {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow SMBERROR("%d connections still active\n",
4bff34e37def8a90f9194d81bc345c52ba20086athurlow smb_vclist.co_usecount - 1);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow /* var, head, next_field */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow SLIST_FOREACH(co, &smb_vclist.co_children, co_next) {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow vcp = CPTOVC(co);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if (vcp->vc_zoneid != zoneid)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow continue;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow /* Debugging */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow lingering_vc(vcp);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow SMB_CO_UNLOCK(&smb_vclist);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow}