usr/src/uts/common/fs/nfs/nfs_export.c
author ek110237
Mon, 31 Oct 2005 22:53:57 -0800
changeset 806 849fb015aa25
parent 0 68f95e015346
child 1610 3436e82414c8
permissions -rw-r--r--
6337437 .zfs doesn't work over NFS
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     1
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     2
 * CDDL HEADER START
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     3
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     4
 * The contents of this file are subject to the terms of the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     5
 * Common Development and Distribution License, Version 1.0 only
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     6
 * (the "License").  You may not use this file except in compliance
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     7
 * with the License.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     8
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     9
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    10
 * or http://www.opensolaris.org/os/licensing.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    11
 * See the License for the specific language governing permissions
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    12
 * and limitations under the License.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    13
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    14
 * When distributing Covered Code, include this CDDL HEADER in each
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    15
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    16
 * If applicable, add the following below this CDDL HEADER, with the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    17
 * fields enclosed by brackets "[]" replaced with your own identifying
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    18
 * information: Portions Copyright [yyyy] [name of copyright owner]
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    19
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    20
 * CDDL HEADER END
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    21
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    22
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    23
 * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    24
 * Use is subject to license terms.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    25
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    26
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    27
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    28
 *  	Copyright 1983, 1984, 1985, 1986, 1987, 1988, 1989  AT&T.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    29
 *		All rights reserved.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    30
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    31
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    32
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    33
#pragma ident	"%Z%%M%	%I%	%E% SMI"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    34
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    35
#include <sys/types.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    36
#include <sys/param.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    37
#include <sys/time.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    38
#include <sys/vfs.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    39
#include <sys/vnode.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    40
#include <sys/socket.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    41
#include <sys/errno.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    42
#include <sys/uio.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    43
#include <sys/proc.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    44
#include <sys/user.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    45
#include <sys/file.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    46
#include <sys/tiuser.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    47
#include <sys/kmem.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    48
#include <sys/pathname.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    49
#include <sys/debug.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    50
#include <sys/vtrace.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    51
#include <sys/cmn_err.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    52
#include <sys/acl.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    53
#include <sys/utsname.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    54
#include <netinet/in.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    55
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    56
#include <rpc/types.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    57
#include <rpc/auth.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    58
#include <rpc/svc.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    59
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    60
#include <nfs/nfs.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    61
#include <nfs/export.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    62
#include <nfs/nfssys.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    63
#include <nfs/nfs_clnt.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    64
#include <nfs/nfs_acl.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    65
#include <nfs/nfs_log.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    66
#include <nfs/lm.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    67
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    68
#define	EXPTABLESIZE 16
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    69
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    70
struct exportinfo *exptable[EXPTABLESIZE];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    71
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    72
static int	unexport(fsid_t *, fid_t *, vnode_t *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    73
static void	exportfree(struct exportinfo *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    74
static int	loadindex(struct exportdata *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    75
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    76
extern void	nfsauth_cache_free(struct exportinfo *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    77
extern int	sec_svc_loadrootnames(int, int, caddr_t **, model_t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    78
extern void	sec_svc_freerootnames(int, int, caddr_t *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    79
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    80
#ifdef VOLATILE_FH_TEST
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    81
static struct ex_vol_rename *find_volrnm_fh(struct exportinfo *, nfs_fh4 *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    82
static uint32_t find_volrnm_fh_id(struct exportinfo *, nfs_fh4 *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    83
static void free_volrnm_list(struct exportinfo *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    84
#endif /* VOLATILE_FH_TEST */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    85
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    86
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    87
 * exported_lock	Read/Write lock that protects the exportinfo list.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    88
 *			This lock must be held when searching or modifiying
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    89
 *			the exportinfo list.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    90
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    91
krwlock_t exported_lock;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    92
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    93
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    94
 * "public" and default (root) location for public filehandle
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    95
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    96
struct exportinfo *exi_public, *exi_root;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    97
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    98
fid_t exi_rootfid;	/* for checking the default public file handle */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    99
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   100
fhandle_t nullfh2;	/* for comparing V2 filehandles */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   101
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   102
#define	exptablehash(fsid, fid) (nfs_fhhash((fsid), (fid)) & (EXPTABLESIZE - 1))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   103
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   104
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   105
 * File handle hash function, good for producing hash values 16 bits wide.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   106
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   107
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   108
nfs_fhhash(fsid_t *fsid, fid_t *fid)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   109
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   110
	short *data;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   111
	int i, len;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   112
	short h;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   113
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   114
	ASSERT(fid != NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   115
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   116
	data = (short *)fid->fid_data;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   117
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   118
	/* fid_data must be aligned on a short */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   119
	ASSERT((((uintptr_t)data) & (sizeof (short) - 1)) == 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   120
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   121
	if (fid->fid_len == 10) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   122
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   123
		 * probably ufs: hash on bytes 4,5 and 8,9
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   124
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   125
		return (fsid->val[0] ^ data[2] ^ data[4]);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   126
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   127
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   128
	if (fid->fid_len == 6) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   129
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   130
		 * probably hsfs: hash on bytes 0,1 and 4,5
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   131
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   132
		return ((fsid->val[0] ^ data[0] ^ data[2]));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   133
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   134
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   135
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   136
	 * Some other file system. Assume that every byte is
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   137
	 * worth hashing.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   138
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   139
	h = (short)fsid->val[0];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   140
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   141
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   142
	 * Sanity check the length before using it
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   143
	 * blindly in case the client trashed it.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   144
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   145
	if (fid->fid_len > NFS_FHMAXDATA)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   146
		len = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   147
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   148
		len = fid->fid_len / sizeof (short);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   149
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   150
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   151
	 * This will ignore one byte if len is not a multiple of
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   152
	 * of sizeof (short). No big deal since we at least get some
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   153
	 * variation with fsid->val[0];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   154
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   155
	for (i = 0; i < len; i++)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   156
		h ^= data[i];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   157
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   158
	return ((int)h);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   159
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   160
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   161
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   162
 * Free the memory allocated within a secinfo entry.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   163
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   164
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   165
srv_secinfo_entry_free(struct secinfo *secp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   166
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   167
	if (secp->s_rootcnt > 0 && secp->s_rootnames != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   168
		sec_svc_freerootnames(secp->s_secinfo.sc_rpcnum,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   169
				secp->s_rootcnt, secp->s_rootnames);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   170
		secp->s_rootcnt = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   171
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   172
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   173
	if ((secp->s_secinfo.sc_rpcnum == RPCSEC_GSS) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   174
	    (secp->s_secinfo.sc_gss_mech_type)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   175
		kmem_free(secp->s_secinfo.sc_gss_mech_type->elements,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   176
			secp->s_secinfo.sc_gss_mech_type->length);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   177
		kmem_free(secp->s_secinfo.sc_gss_mech_type,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   178
			sizeof (rpc_gss_OID_desc));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   179
		secp->s_secinfo.sc_gss_mech_type = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   180
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   181
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   182
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   183
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   184
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   185
 * Free a list of secinfo allocated in the exportdata structure.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   186
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   187
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   188
srv_secinfo_list_free(struct secinfo *secinfo, int cnt)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   189
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   190
	int i;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   191
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   192
	if (cnt == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   193
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   194
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   195
	for (i = 0; i < cnt; i++)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   196
		srv_secinfo_entry_free(&secinfo[i]);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   197
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   198
	kmem_free(secinfo, cnt * sizeof (struct secinfo));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   199
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   200
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   201
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   202
 * Allocate and copy a secinfo data from "from" to "to".
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   203
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   204
 * This routine is used by srv_secinfo_add() to add a new flavor to an
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   205
 * ancestor's export node. The rootnames are not copied because the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   206
 * allowable rootname access only applies to the explicit exported node,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   207
 * not its ancestor's.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   208
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   209
 * "to" should have already been allocated and zeroed before calling
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   210
 * this routine.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   211
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   212
 * This routine is used under the protection of exported_lock (RW_WRITER).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   213
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   214
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   215
srv_secinfo_copy(struct secinfo *from, struct secinfo *to)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   216
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   217
	to->s_secinfo.sc_nfsnum = from->s_secinfo.sc_nfsnum;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   218
	to->s_secinfo.sc_rpcnum = from->s_secinfo.sc_rpcnum;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   219
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   220
	if (from->s_secinfo.sc_rpcnum == RPCSEC_GSS) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   221
		to->s_secinfo.sc_service = from->s_secinfo.sc_service;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   222
		bcopy(from->s_secinfo.sc_name, to->s_secinfo.sc_name,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   223
			strlen(from->s_secinfo.sc_name));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   224
		bcopy(from->s_secinfo.sc_gss_mech, to->s_secinfo.sc_gss_mech,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   225
			strlen(from->s_secinfo.sc_gss_mech));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   226
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   227
		/* copy mechanism oid */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   228
		to->s_secinfo.sc_gss_mech_type =
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   229
			kmem_alloc(sizeof (rpc_gss_OID_desc), KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   230
		to->s_secinfo.sc_gss_mech_type->length =
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   231
			from->s_secinfo.sc_gss_mech_type->length;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   232
		to->s_secinfo.sc_gss_mech_type->elements =
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   233
			kmem_alloc(from->s_secinfo.sc_gss_mech_type->length,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   234
					KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   235
		bcopy(from->s_secinfo.sc_gss_mech_type->elements,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   236
			to->s_secinfo.sc_gss_mech_type->elements,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   237
			from->s_secinfo.sc_gss_mech_type->length);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   238
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   239
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   240
	to->s_refcnt = from->s_refcnt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   241
	to->s_window = from->s_window;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   242
	/* no need to copy the mode bits - s_flags */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   243
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   244
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   245
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   246
 * Add the new security flavors from newdata to the current list, curdata.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   247
 * Upon return, curdata has the newly merged secinfo list.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   248
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   249
 * There should be at least 1 secinfo entry in newdata.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   250
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   251
 * This routine is used under the protection of exported_lock (RW_WRITER).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   252
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   253
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   254
srv_secinfo_add(struct exportdata *curdata, struct exportdata *newdata)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   255
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   256
	int ccnt, c;		/* sec count in current data - curdata */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   257
	int ncnt, n;		/* sec count in new data - newdata */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   258
	int tcnt, mcnt;		/* total sec count after merge */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   259
	struct secinfo *msec;	/* merged secinfo list */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   260
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   261
	ccnt = curdata->ex_seccnt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   262
	ncnt = newdata->ex_seccnt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   263
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   264
	ASSERT(ncnt > 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   265
	tcnt = ccnt + ncnt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   266
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   267
	for (n = 0; n < ncnt; n++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   268
		for (c = 0; c < ccnt; c++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   269
		    if (newdata->ex_secinfo[n].s_secinfo.sc_nfsnum ==
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   270
			curdata->ex_secinfo[c].s_secinfo.sc_nfsnum) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   271
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   272
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   273
			 * add the reference count of the newdata
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   274
			 * to the curdata for this nfs flavor.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   275
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   276
			curdata->ex_secinfo[c].s_refcnt +=
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   277
				newdata->ex_secinfo[n].s_refcnt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   278
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   279
			tcnt--;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   280
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   281
		    }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   282
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   283
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   284
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   285
	if (tcnt == ccnt)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   286
		return; /* no change; no new flavors */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   287
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   288
	msec = kmem_zalloc(tcnt * sizeof (struct secinfo), KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   289
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   290
	/* move current secinfo list data to the new list */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   291
	for (c = 0; c < ccnt; c++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   292
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   293
		bcopy(&curdata->ex_secinfo[c], &msec[c],
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   294
			sizeof (struct secinfo));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   295
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   296
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   297
	/* Add the flavor that's not in the current data */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   298
	mcnt = ccnt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   299
	for (n = 0; n < ncnt; n++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   300
		for (c = 0; c < ccnt; c++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   301
		    if (newdata->ex_secinfo[n].s_secinfo.sc_nfsnum ==
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   302
			curdata->ex_secinfo[c].s_secinfo.sc_nfsnum)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   303
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   304
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   305
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   306
		/* This is the one. Add it. */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   307
		if (c == ccnt) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   308
		    srv_secinfo_copy(&newdata->ex_secinfo[n], &msec[mcnt]);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   309
		    if (curdata->ex_flags & EX_PSEUDO)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   310
			msec[mcnt].s_flags = M_RO;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   311
		    mcnt++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   312
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   313
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   314
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   315
	ASSERT(mcnt == tcnt);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   316
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   317
	 * Done. Update curdata.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   318
	 * Free up the existing secinfo list in curdata and
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   319
	 * set the new value.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   320
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   321
	if (ccnt > 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   322
		kmem_free(curdata->ex_secinfo, ccnt * sizeof (struct secinfo));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   323
	curdata->ex_seccnt = tcnt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   324
	curdata->ex_secinfo = msec;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   325
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   326
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   327
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   328
 * For NFS V4.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   329
 * Remove the security data of the unexported node from its ancestors.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   330
 * Assume there is at least one flavor entry in the current data, curdata.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   331
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   332
 * This routine is used under the protection of exported_lock (RW_WRITER).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   333
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   334
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   335
srv_secinfo_remove(struct exportdata *curdata, struct exportdata *remdata)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   336
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   337
	int ccnt, c;		/* sec count in current data - curdata */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   338
	int rcnt, r;		/* sec count in removal data - remdata */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   339
	int tcnt, mcnt;		/* total sec count after removing */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   340
	struct secinfo *msec;	/* final secinfo list after removing */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   341
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   342
	ASSERT(curdata->ex_seccnt > 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   343
	ccnt = curdata->ex_seccnt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   344
	rcnt = remdata->ex_seccnt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   345
	tcnt = ccnt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   346
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   347
	for (r = 0; r < rcnt; r++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   348
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   349
	    if (SEC_REF_EXPORTED(&remdata->ex_secinfo[r])) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   350
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   351
		 * Remove a flavor only if the flavor was a shared flavor for
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   352
		 * the remdata exported node that's being unshared. Otherwise,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   353
		 * this flavor is for the children of remdata, need to keep it.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   354
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   355
		for (c = 0; c < ccnt; c++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   356
		    if (remdata->ex_secinfo[r].s_secinfo.sc_nfsnum ==
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   357
			curdata->ex_secinfo[c].s_secinfo.sc_nfsnum) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   358
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   359
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   360
			 * Decrement secinfo reference count by 1.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   361
			 * If this entry is invalid after decrementing
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   362
			 * the count (i.e. count < 1), this entry will
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   363
			 * be removed.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   364
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   365
			curdata->ex_secinfo[c].s_refcnt--;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   366
			if (SEC_REF_INVALID(&curdata->ex_secinfo[c]))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   367
				tcnt--;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   368
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   369
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   370
		    }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   371
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   372
	    }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   373
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   374
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   375
	ASSERT(tcnt >= 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   376
	if (tcnt == ccnt)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   377
		return; /* no change; no flavors to remove */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   378
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   379
	if (tcnt == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   380
		srv_secinfo_list_free(curdata->ex_secinfo, ccnt);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   381
		curdata->ex_seccnt = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   382
		curdata->ex_secinfo = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   383
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   384
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   385
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   386
	msec = kmem_zalloc(tcnt * sizeof (struct secinfo), KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   387
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   388
	/* walk thru the given secinfo list to remove the flavors */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   389
	mcnt = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   390
	for (c = 0; c < ccnt; c++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   391
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   392
		if (SEC_REF_INVALID(&curdata->ex_secinfo[c])) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   393
			srv_secinfo_entry_free(&curdata->ex_secinfo[c]);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   394
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   395
			bcopy(&curdata->ex_secinfo[c], &msec[mcnt],
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   396
				sizeof (struct secinfo));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   397
			mcnt++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   398
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   399
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   400
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   401
	ASSERT(mcnt == tcnt);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   402
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   403
	 * Done. Update curdata.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   404
	 * Free the existing secinfo list in curdata. All pointers
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   405
	 * within the list have either been moved to msec or freed
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   406
	 * if it's invalid.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   407
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   408
	kmem_free(curdata->ex_secinfo, ccnt * sizeof (struct secinfo));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   409
	curdata->ex_seccnt = tcnt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   410
	curdata->ex_secinfo = msec;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   411
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   412
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   413
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   414
 * Upon re-sharing an export node, if there is more than 1 export reference
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   415
 * to an old flavor (i.e. some of its children shared with this flavor), this
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   416
 * flavor information needs to be transfered to the new shared node.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   417
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   418
 * Expect at least 1 secinfo entry in the old shared node - olddata.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   419
 * Expect both curdata and olddata are not pseudo nodes.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   420
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   421
 * This routine is used under the protection of exported_lock (RW_WRITER).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   422
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   423
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   424
srv_secinfo_exp2exp(struct exportdata *curdata, struct exportdata *olddata)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   425
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   426
	int ccnt, c;		/* sec count in current data - curdata */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   427
	int ocnt, o;		/* sec count in old data - olddata */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   428
	int tcnt, mcnt;		/* total sec count after the transfer */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   429
	struct secinfo *msec;	/* merged secinfo list */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   430
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   431
	ccnt = curdata->ex_seccnt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   432
	ocnt = olddata->ex_seccnt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   433
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   434
	ASSERT(ocnt > 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   435
	ASSERT(!(olddata->ex_flags & EX_PSEUDO));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   436
	ASSERT(!(curdata->ex_flags & EX_PSEUDO));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   437
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   438
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   439
	 * If the olddata has flavors with more than 1 reference count,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   440
	 * transfer the information to the curdata.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   441
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   442
	tcnt = ccnt + ocnt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   443
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   444
	for (o = 0; o < ocnt; o++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   445
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   446
	    if (SEC_REF_SELF(&olddata->ex_secinfo[o])) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   447
		tcnt--;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   448
	    } else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   449
		for (c = 0; c < ccnt; c++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   450
		    if (olddata->ex_secinfo[o].s_secinfo.sc_nfsnum ==
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   451
			curdata->ex_secinfo[c].s_secinfo.sc_nfsnum) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   452
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   453
			/* add old reference to the current secinfo count */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   454
			curdata->ex_secinfo[c].s_refcnt +=
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   455
				olddata->ex_secinfo[o].s_refcnt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   456
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   457
			/* delete the old export flavor reference */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   458
			if (SEC_REF_EXPORTED(&olddata->ex_secinfo[o]))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   459
				curdata->ex_secinfo[c].s_refcnt--;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   460
			tcnt--;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   461
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   462
		    }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   463
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   464
	    }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   465
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   466
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   467
	if (tcnt == ccnt)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   468
		return; /* no more transfer to do */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   469
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   470
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   471
	 * olddata has flavors refered by its children that are not
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   472
	 * in the current (new) export flavor list. Add these flavors.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   473
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   474
	msec = kmem_zalloc(tcnt * sizeof (struct secinfo), KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   475
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   476
	/* move current secinfo list data to the new list */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   477
	for (c = 0; c < ccnt; c++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   478
		bcopy(&curdata->ex_secinfo[c], &msec[c],
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   479
			sizeof (struct secinfo));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   480
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   481
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   482
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   483
	 * Add the flavor that's not in the new export, but still
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   484
	 * referred by its children.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   485
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   486
	mcnt = ccnt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   487
	for (o = 0; o < ocnt; o++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   488
	    if (! SEC_REF_SELF(&olddata->ex_secinfo[o])) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   489
		for (c = 0; c < ccnt; c++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   490
		    if (olddata->ex_secinfo[o].s_secinfo.sc_nfsnum ==
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   491
			curdata->ex_secinfo[c].s_secinfo.sc_nfsnum)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   492
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   493
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   494
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   495
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   496
		 * This is the one. Add it. Decrement the reference count
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   497
		 * by 1 if the flavor is an explicitly shared flavor for
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   498
		 * the olddata export node.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   499
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   500
		if (c == ccnt) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   501
		    srv_secinfo_copy(&olddata->ex_secinfo[o], &msec[mcnt]);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   502
		    if (SEC_REF_EXPORTED(&olddata->ex_secinfo[o]))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   503
			msec[mcnt].s_refcnt--;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   504
		    mcnt++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   505
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   506
	    }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   507
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   508
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   509
	ASSERT(mcnt == tcnt);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   510
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   511
	 * Done. Update curdata.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   512
	 * Free up the existing secinfo list in curdata and
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   513
	 * set the new value.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   514
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   515
	if (ccnt > 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   516
		kmem_free(curdata->ex_secinfo, ccnt * sizeof (struct secinfo));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   517
	curdata->ex_seccnt = tcnt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   518
	curdata->ex_secinfo = msec;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   519
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   520
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   521
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   522
 * When unsharing an old export node and the old node becomes a pseudo node,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   523
 * if there is more than 1 export reference to an old flavor (i.e. some of
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   524
 * its children shared with this flavor), this flavor information needs to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   525
 * be transfered to the new shared node.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   526
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   527
 * This routine is used under the protection of exported_lock (RW_WRITER).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   528
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   529
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   530
srv_secinfo_exp2pseu(struct exportdata *curdata, struct exportdata *olddata)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   531
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   532
	int ocnt, o;		/* sec count in transfer data - trandata */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   533
	int tcnt, mcnt;		/* total sec count after transfer */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   534
	struct secinfo *msec;	/* merged secinfo list */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   535
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   536
	ASSERT(curdata->ex_flags & EX_PSEUDO);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   537
	ASSERT(curdata->ex_seccnt == 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   538
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   539
	ocnt = olddata->ex_seccnt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   540
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   541
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   542
	 * If the olddata has flavors with more than 1 reference count,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   543
	 * transfer the information to the curdata.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   544
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   545
	tcnt = ocnt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   546
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   547
	for (o = 0; o < ocnt; o++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   548
	    if (SEC_REF_SELF(&olddata->ex_secinfo[o]))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   549
		tcnt--;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   550
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   551
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   552
	if (tcnt == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   553
		return; /* no transfer to do */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   554
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   555
	msec = kmem_zalloc(tcnt * sizeof (struct secinfo), KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   556
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   557
	mcnt = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   558
	for (o = 0; o < ocnt; o++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   559
	    if (! SEC_REF_SELF(&olddata->ex_secinfo[o])) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   560
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   561
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   562
		 * Decrement the reference count by 1 if the flavor is
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   563
		 * an explicitly shared flavor for the olddata export node.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   564
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   565
		srv_secinfo_copy(&olddata->ex_secinfo[o], &msec[mcnt]);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   566
		msec[mcnt].s_flags = M_RO; /* for a pseudo node */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   567
		if (SEC_REF_EXPORTED(&olddata->ex_secinfo[o]))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   568
			msec[mcnt].s_refcnt--;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   569
		mcnt++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   570
	    }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   571
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   572
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   573
	ASSERT(mcnt == tcnt);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   574
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   575
	 * Done. Update curdata.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   576
	 * Free up the existing secinfo list in curdata and
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   577
	 * set the new value.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   578
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   579
	curdata->ex_seccnt = tcnt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   580
	curdata->ex_secinfo = msec;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   581
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   582
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   583
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   584
 * For NFS V4.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   585
 * Add or remove the newly exported or unexported security flavors of the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   586
 * given exportinfo from its ancestors upto the system root.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   587
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   588
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   589
srv_secinfo_treeclimb(struct exportinfo *exip, bool_t isadd)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   590
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   591
	vnode_t *dvp, *vp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   592
	fid_t fid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   593
	int error = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   594
	int exportdir;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   595
	struct exportinfo *exi;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   596
	struct exportdata *exdata;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   597
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   598
	ASSERT(RW_WRITE_HELD(&exported_lock));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   599
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   600
	exdata = &exip->exi_export;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   601
	if (exdata->ex_seccnt == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   602
		return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   603
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   604
	vp = exip->exi_vp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   605
	VN_HOLD(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   606
	exportdir = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   607
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   608
	for (;;) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   609
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   610
		bzero(&fid, sizeof (fid));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   611
		fid.fid_len = MAXFIDSZ;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   612
		error = vop_fid_pseudo(vp, &fid);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   613
		if (error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   614
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   615
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   616
		if (! exportdir) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   617
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   618
			exi = checkexport4(&vp->v_vfsp->vfs_fsid, &fid, vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   619
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   620
			if (exi != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   621
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   622
			    if (isadd) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   623
				/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   624
				 * Add the new security flavors to the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   625
				 * export entry of the current directory.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   626
				 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   627
				srv_secinfo_add(&exi->exi_export, exdata);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   628
			    } else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   629
				/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   630
				 * Remove the unexported secinfo entries.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   631
				 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   632
				srv_secinfo_remove(&exi->exi_export, exdata);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   633
			    }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   634
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   635
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   636
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   637
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   638
		 * If at the root of the filesystem, need
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   639
		 * to traverse across the mountpoint
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   640
		 * and continue the climb on the mounted-on
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   641
		 * filesystem.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   642
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   643
		if (vp->v_flag & VROOT) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   644
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   645
			if (VN_CMP(vp, rootdir)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   646
				/* at system root */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   647
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   648
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   649
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   650
			vp = untraverse(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   651
			exportdir = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   652
			continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   653
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   654
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   655
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   656
		 * Now, do a ".." to find parent dir of vp.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   657
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   658
		error = VOP_LOOKUP(vp, "..", &dvp, NULL, 0, NULL, CRED());
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   659
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   660
		if (error == ENOTDIR && exportdir) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   661
			dvp = exip->exi_dvp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   662
			ASSERT(dvp != NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   663
			VN_HOLD(dvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   664
			error = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   665
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   666
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   667
		if (error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   668
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   669
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   670
		exportdir = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   671
		VN_RELE(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   672
		vp = dvp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   673
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   674
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   675
	VN_RELE(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   676
	return (error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   677
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   678
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   679
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   680
export_link(struct exportinfo *exi) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   681
	int exporthash;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   682
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   683
	exporthash = exptablehash(&exi->exi_fsid, &exi->exi_fid);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   684
	exi->exi_hash = exptable[exporthash];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   685
	exptable[exporthash] = exi;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   686
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   687
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   688
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   689
 * Initialization routine for export routines. Should only be called once.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   690
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   691
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   692
nfs_exportinit(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   693
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   694
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   695
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   696
	rw_init(&exported_lock, NULL, RW_DEFAULT, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   697
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   698
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   699
	 * Allocate the place holder for the public file handle, which
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   700
	 * is all zeroes. It is initially set to the root filesystem.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   701
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   702
	exi_root = kmem_zalloc(sizeof (*exi_root), KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   703
	exi_public = exi_root;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   704
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   705
	exi_root->exi_export.ex_flags = EX_PUBLIC;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   706
	exi_root->exi_export.ex_pathlen = 2;	/* length of "/" */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   707
	exi_root->exi_export.ex_path =
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   708
		kmem_alloc(exi_root->exi_export.ex_pathlen, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   709
	exi_root->exi_export.ex_path[0] = '/';
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   710
	exi_root->exi_export.ex_path[1] = '\0';
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   711
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   712
	exi_root->exi_count = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   713
	mutex_init(&exi_root->exi_lock, NULL, MUTEX_DEFAULT, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   714
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   715
	exi_root->exi_vp = rootdir;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   716
	exi_rootfid.fid_len = MAXFIDSZ;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   717
	error = vop_fid_pseudo(exi_root->exi_vp, &exi_rootfid);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   718
	if (error) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   719
		mutex_destroy(&exi_root->exi_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   720
		kmem_free(exi_root, sizeof (*exi_root));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   721
		return (error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   722
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   723
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   724
	/* setup the fhandle template */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   725
	exi_root->exi_fh.fh_fsid = rootdir->v_vfsp->vfs_fsid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   726
	exi_root->exi_fh.fh_xlen = exi_rootfid.fid_len;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   727
	bcopy(exi_rootfid.fid_data, exi_root->exi_fh.fh_xdata,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   728
			exi_rootfid.fid_len);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   729
	exi_root->exi_fh.fh_len = sizeof (exi_root->exi_fh.fh_data);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   730
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   731
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   732
	 * Publish the exportinfo in the hash table
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   733
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   734
	export_link(exi_root);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   735
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   736
	nfslog_init();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   737
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   738
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   739
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   740
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   741
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   742
 * Finalization routine for export routines. Called to cleanup previoulsy
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   743
 * initializtion work when the NFS server module could not be loaded correctly.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   744
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   745
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   746
nfs_exportfini(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   747
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   748
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   749
	 * Deallocate the place holder for the public file handle.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   750
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   751
	srv_secinfo_list_free(exi_root->exi_export.ex_secinfo,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   752
				exi_root->exi_export.ex_seccnt);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   753
	mutex_destroy(&exi_root->exi_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   754
	kmem_free(exi_root, sizeof (*exi_root));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   755
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   756
	rw_destroy(&exported_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   757
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   758
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   759
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   760
 *  Check if 2 gss mechanism identifiers are the same.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   761
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   762
 *  return FALSE if not the same.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   763
 *  return TRUE if the same.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   764
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   765
static bool_t
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   766
nfs_mech_equal(rpc_gss_OID mech1, rpc_gss_OID mech2)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   767
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   768
	if ((mech1->length == 0) && (mech2->length == 0))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   769
		return (TRUE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   770
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   771
	if (mech1->length != mech2->length)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   772
		return (FALSE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   773
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   774
	return (bcmp(mech1->elements, mech2->elements, mech1->length) == 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   775
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   776
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   777
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   778
 *  This routine is used by rpc to map rpc security number
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   779
 *  to nfs specific security flavor number.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   780
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   781
 *  The gss callback prototype is
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   782
 *  callback(struct svc_req *, gss_cred_id_t *, gss_ctx_id_t *,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   783
 *				rpc_gss_lock_t *, void **),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   784
 *  since nfs does not use the gss_cred_id_t/gss_ctx_id_t arguments
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   785
 *  we cast them to void.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   786
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   787
/*ARGSUSED*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   788
bool_t
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   789
rfs_gsscallback(struct svc_req *req, gss_cred_id_t deleg, void *gss_context,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   790
    rpc_gss_lock_t *lock, void **cookie)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   791
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   792
	int i, j;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   793
	rpc_gss_rawcred_t *raw_cred;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   794
	struct exportinfo *exi;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   795
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   796
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   797
	 * We don't deal with delegated credentials.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   798
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   799
	if (deleg != GSS_C_NO_CREDENTIAL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   800
		return (FALSE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   801
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   802
	raw_cred = lock->raw_cred;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   803
	*cookie = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   804
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   805
	rw_enter(&exported_lock, RW_READER);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   806
	for (i = 0; i < EXPTABLESIZE; i++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   807
	    exi = exptable[i];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   808
	    while (exi) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   809
		if (exi->exi_export.ex_seccnt > 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   810
		    struct secinfo *secp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   811
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   812
		    secp = exi->exi_export.ex_secinfo;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   813
		    for (j = 0; j < exi->exi_export.ex_seccnt; j++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   814
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   815
			 *  If there is a map of the triplet
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   816
			 *  (mechanism, service, qop) between raw_cred and
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   817
			 *  the exported flavor, get the psudo flavor number.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   818
			 *  Also qop should not be NULL, it should be "default"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   819
			 *  or something else.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   820
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   821
			if ((secp[j].s_secinfo.sc_rpcnum == RPCSEC_GSS) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   822
			(nfs_mech_equal(secp[j].s_secinfo.sc_gss_mech_type,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   823
			raw_cred->mechanism)) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   824
			(secp[j].s_secinfo.sc_service == raw_cred->service) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   825
			(raw_cred->qop == secp[j].s_secinfo.sc_qop)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   826
				*cookie = (void *)(uintptr_t)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   827
				    secp[j].s_secinfo.sc_nfsnum;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   828
				goto done;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   829
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   830
		    }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   831
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   832
		exi = exi->exi_hash;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   833
	    }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   834
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   835
done:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   836
	rw_exit(&exported_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   837
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   838
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   839
	 * If no nfs pseudo number mapping can be found in the export
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   840
	 * table, assign the nfsflavor to NFS_FLAVOR_NOMAP. In V4, we may
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   841
	 * recover the flavor mismatch from NFS layer (NFS4ERR_WRONGSEC).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   842
	 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   843
	 * For example:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   844
	 *	server first shares with krb5i;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   845
	 *	client mounts with krb5i;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   846
	 *	server re-shares with krb5p;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   847
	 *	client tries with krb5i, but no mapping can be found;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   848
	 *	rpcsec_gss module calls this routine to do the mapping,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   849
	 *		if this routine fails, request is rejected from
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   850
	 *		the rpc layer.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   851
	 *	What we need is to let the nfs layer rejects the request.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   852
	 *	For V4, we can reject with NFS4ERR_WRONGSEC and the client
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   853
	 *	may recover from it by getting the new flavor via SECINFO.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   854
	 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   855
	 * nfs pseudo number for RPCSEC_GSS mapping (see nfssec.conf)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   856
	 * is owned by IANA (see RFC 2623).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   857
	 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   858
	 * XXX NFS_FLAVOR_NOMAP is defined in Solaris to work around
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   859
	 * the implementation issue. This number should not overlap with
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   860
	 * any new IANA defined pseudo flavor numbers.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   861
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   862
	if (*cookie == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   863
		*cookie = (void *)NFS_FLAVOR_NOMAP;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   864
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   865
	lock->locked = TRUE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   866
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   867
	return (TRUE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   868
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   869
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   870
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   871
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   872
 * Exportfs system call; credentials should be checked before
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   873
 * calling this function.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   874
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   875
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   876
exportfs(struct exportfs_args *args, model_t model, cred_t *cr)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   877
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   878
	vnode_t *vp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   879
	vnode_t *dvp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   880
	struct exportdata *kex;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   881
	struct exportinfo *exi;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   882
	struct exportinfo *ex, *prev;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   883
	fid_t fid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   884
	fsid_t fsid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   885
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   886
	size_t allocsize;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   887
	struct secinfo *sp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   888
	struct secinfo *exs;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   889
	rpc_gss_callback_t cb;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   890
	char *pathbuf;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   891
	char *log_buffer;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   892
	char *tagbuf;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   893
	int callback;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   894
	int allocd_seccnt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   895
	STRUCT_HANDLE(exportfs_args, uap);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   896
	STRUCT_DECL(exportdata, uexi);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   897
	int i;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   898
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   899
	STRUCT_SET_HANDLE(uap, model, args);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   900
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   901
	error = lookupname(STRUCT_FGETP(uap, dname), UIO_USERSPACE,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   902
	    FOLLOW, &dvp, &vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   903
	if (error == EINVAL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   904
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   905
		 * if fname resolves to / we get EINVAL error
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   906
		 * since we wanted the parent vnode. Try again
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   907
		 * with NULL dvp.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   908
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   909
		error = lookupname(STRUCT_FGETP(uap, dname), UIO_USERSPACE,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   910
		    FOLLOW, NULL, &vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   911
		dvp = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   912
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   913
	if (!error && vp == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   914
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   915
		 * Last component of fname not found
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   916
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   917
		if (dvp != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   918
			VN_RELE(dvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   919
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   920
		error = ENOENT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   921
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   922
	if (error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   923
		return (error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   924
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   925
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   926
	 * 'vp' may be an AUTOFS node, so we perform a
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   927
	 * VOP_ACCESS() to trigger the mount of the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   928
	 * intended filesystem, so we can share the intended
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   929
	 * filesystem instead of the AUTOFS filesystem.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   930
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   931
	(void) VOP_ACCESS(vp, 0, 0, cr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   932
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   933
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   934
	 * We're interested in the top most filesystem.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   935
	 * This is specially important when uap->dname is a trigger
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   936
	 * AUTOFS node, since we're really interested in sharing the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   937
	 * filesystem AUTOFS mounted as result of the VOP_ACCESS()
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   938
	 * call not the AUTOFS node itself.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   939
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   940
	if (vn_mountedvfs(vp) != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   941
		if (error = traverse(&vp)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   942
			VN_RELE(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   943
			if (dvp != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   944
				VN_RELE(dvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   945
			return (error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   946
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   947
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   948
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   949
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   950
	 * Get the vfs id
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   951
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   952
	bzero(&fid, sizeof (fid));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   953
	fid.fid_len = MAXFIDSZ;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   954
	error = VOP_FID(vp, &fid);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   955
	fsid = vp->v_vfsp->vfs_fsid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   956
	if (error) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   957
		VN_RELE(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   958
		if (dvp != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   959
			VN_RELE(dvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   960
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   961
		 * If VOP_FID returns ENOSPC then the fid supplied
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   962
		 * is too small.  For now we simply return EREMOTE.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   963
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   964
		if (error == ENOSPC)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   965
			error = EREMOTE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   966
		return (error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   967
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   968
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   969
	if (STRUCT_FGETP(uap, uex) == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   970
		error = unexport(&fsid, &fid, vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   971
		VN_RELE(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   972
		if (dvp != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   973
			VN_RELE(dvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   974
		return (error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   975
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   976
	exi = kmem_zalloc(sizeof (*exi), KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   977
	exi->exi_fsid = fsid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   978
	exi->exi_fid = fid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   979
	exi->exi_vp = vp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   980
	exi->exi_count = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   981
	exi->exi_volatile_dev = (vfssw[vp->v_vfsp->vfs_fstype].vsw_flag &
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   982
				VSW_VOLATILEDEV) ? 1 : 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   983
	mutex_init(&exi->exi_lock, NULL, MUTEX_DEFAULT, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   984
	exi->exi_dvp = dvp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   985
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   986
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   987
	 * Initialize auth cache lock
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   988
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   989
	rw_init(&exi->exi_cache_lock, NULL, RW_DEFAULT, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   990
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   991
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   992
	 * Build up the template fhandle
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   993
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   994
	exi->exi_fh.fh_fsid = fsid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   995
	if (exi->exi_fid.fid_len > sizeof (exi->exi_fh.fh_xdata)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   996
		error = EREMOTE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   997
		goto out1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   998
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   999
	exi->exi_fh.fh_xlen = exi->exi_fid.fid_len;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1000
	bcopy(exi->exi_fid.fid_data, exi->exi_fh.fh_xdata,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1001
	    exi->exi_fid.fid_len);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1002
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1003
	exi->exi_fh.fh_len = sizeof (exi->exi_fh.fh_data);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1004
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1005
	kex = &exi->exi_export;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1006
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1007
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1008
	 * Load in everything, and do sanity checking
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1009
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1010
	STRUCT_INIT(uexi, model);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1011
	if (copyin(STRUCT_FGETP(uap, uex), STRUCT_BUF(uexi),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1012
	    STRUCT_SIZE(uexi))) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1013
		error = EFAULT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1014
		goto out1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1015
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1016
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1017
	kex->ex_version = STRUCT_FGET(uexi, ex_version);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1018
	if (kex->ex_version != EX_CURRENT_VERSION) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1019
		error = EINVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1020
		cmn_err(CE_WARN,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1021
		"NFS: exportfs requires export struct version 2 - got %d\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1022
		kex->ex_version);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1023
		goto out1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1024
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1025
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1026
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1027
	 * Must have at least one security entry
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1028
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1029
	kex->ex_seccnt = STRUCT_FGET(uexi, ex_seccnt);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1030
	if (kex->ex_seccnt < 1) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1031
		error = EINVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1032
		goto out1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1033
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1034
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1035
	kex->ex_path = STRUCT_FGETP(uexi, ex_path);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1036
	kex->ex_pathlen = STRUCT_FGET(uexi, ex_pathlen);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1037
	kex->ex_flags = STRUCT_FGET(uexi, ex_flags);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1038
	kex->ex_anon = STRUCT_FGET(uexi, ex_anon);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1039
	kex->ex_secinfo = STRUCT_FGETP(uexi, ex_secinfo);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1040
	kex->ex_index = STRUCT_FGETP(uexi, ex_index);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1041
	kex->ex_log_buffer = STRUCT_FGETP(uexi, ex_log_buffer);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1042
	kex->ex_log_bufferlen = STRUCT_FGET(uexi, ex_log_bufferlen);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1043
	kex->ex_tag = STRUCT_FGETP(uexi, ex_tag);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1044
	kex->ex_taglen = STRUCT_FGET(uexi, ex_taglen);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1045
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1046
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1047
	 * Copy the exported pathname into
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1048
	 * an appropriately sized buffer.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1049
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1050
	pathbuf = kmem_alloc(MAXPATHLEN, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1051
	if (copyinstr(kex->ex_path, pathbuf, MAXPATHLEN, &kex->ex_pathlen)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1052
		kmem_free(pathbuf, MAXPATHLEN);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1053
		error = EFAULT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1054
		goto out1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1055
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1056
	kex->ex_path = kmem_alloc(kex->ex_pathlen + 1, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1057
	bcopy(pathbuf, kex->ex_path, kex->ex_pathlen);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1058
	kex->ex_path[kex->ex_pathlen] = '\0';
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1059
	kmem_free(pathbuf, MAXPATHLEN);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1060
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1061
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1062
	 * Get the path to the logging buffer and the tag
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1063
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1064
	if (kex->ex_flags & EX_LOG) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1065
		log_buffer = kmem_alloc(MAXPATHLEN, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1066
		if (copyinstr(kex->ex_log_buffer, log_buffer, MAXPATHLEN,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1067
		    &kex->ex_log_bufferlen)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1068
			kmem_free(log_buffer, MAXPATHLEN);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1069
			error = EFAULT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1070
			goto out2;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1071
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1072
		kex->ex_log_buffer =
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1073
			kmem_alloc(kex->ex_log_bufferlen + 1, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1074
		bcopy(log_buffer, kex->ex_log_buffer, kex->ex_log_bufferlen);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1075
		kex->ex_log_buffer[kex->ex_log_bufferlen] = '\0';
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1076
		kmem_free(log_buffer, MAXPATHLEN);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1077
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1078
		tagbuf = kmem_alloc(MAXPATHLEN, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1079
		if (copyinstr(kex->ex_tag, tagbuf, MAXPATHLEN,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1080
		    &kex->ex_taglen)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1081
			kmem_free(tagbuf, MAXPATHLEN);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1082
			error = EFAULT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1083
			goto out3;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1084
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1085
		kex->ex_tag = kmem_alloc(kex->ex_taglen + 1, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1086
		bcopy(tagbuf, kex->ex_tag, kex->ex_taglen);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1087
		kex->ex_tag[kex->ex_taglen] = '\0';
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1088
		kmem_free(tagbuf, MAXPATHLEN);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1089
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1090
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1091
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1092
	 * Load the security information for each flavor
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1093
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1094
	allocsize = kex->ex_seccnt * SIZEOF_STRUCT(secinfo, model);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1095
	sp = kmem_zalloc(allocsize, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1096
	if (copyin(kex->ex_secinfo, sp, allocsize)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1097
		kmem_free(sp, allocsize);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1098
		error = EFAULT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1099
		goto out4;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1100
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1101
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1102
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1103
	 * All of these nested structures need to be converted to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1104
	 * the kernel native format.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1105
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1106
	if (model != DATAMODEL_NATIVE) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1107
		size_t allocsize2;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1108
		struct secinfo *sp2;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1109
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1110
		allocsize2 = kex->ex_seccnt * sizeof (struct secinfo);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1111
		sp2 = kmem_zalloc(allocsize2, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1112
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1113
		for (i = 0; i < kex->ex_seccnt; i++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1114
			STRUCT_HANDLE(secinfo, usi);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1115
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1116
			STRUCT_SET_HANDLE(usi, model,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1117
			    (struct secinfo *)((caddr_t)sp +
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1118
			    (i * SIZEOF_STRUCT(secinfo, model))));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1119
			bcopy(STRUCT_FGET(usi, s_secinfo.sc_name),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1120
			    sp2[i].s_secinfo.sc_name, MAX_NAME_LEN);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1121
			sp2[i].s_secinfo.sc_nfsnum =
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1122
			    STRUCT_FGET(usi, s_secinfo.sc_nfsnum);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1123
			sp2[i].s_secinfo.sc_rpcnum =
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1124
			    STRUCT_FGET(usi, s_secinfo.sc_rpcnum);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1125
			bcopy(STRUCT_FGET(usi, s_secinfo.sc_gss_mech),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1126
			    sp2[i].s_secinfo.sc_gss_mech, MAX_NAME_LEN);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1127
			sp2[i].s_secinfo.sc_gss_mech_type =
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1128
			    STRUCT_FGETP(usi, s_secinfo.sc_gss_mech_type);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1129
			sp2[i].s_secinfo.sc_qop =
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1130
			    STRUCT_FGET(usi, s_secinfo.sc_qop);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1131
			sp2[i].s_secinfo.sc_service =
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1132
			    STRUCT_FGET(usi, s_secinfo.sc_service);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1133
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1134
			sp2[i].s_flags = STRUCT_FGET(usi, s_flags);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1135
			sp2[i].s_window = STRUCT_FGET(usi, s_window);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1136
			sp2[i].s_rootcnt = STRUCT_FGET(usi, s_rootcnt);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1137
			sp2[i].s_rootnames = STRUCT_FGETP(usi, s_rootnames);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1138
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1139
		kmem_free(sp, allocsize);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1140
		sp = sp2;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1141
		allocsize = allocsize2;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1142
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1143
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1144
	kex->ex_secinfo = sp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1145
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1146
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1147
	 * And now copy rootnames for each individual secinfo.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1148
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1149
	callback = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1150
	allocd_seccnt = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1151
	while (allocd_seccnt < kex->ex_seccnt) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1152
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1153
		exs = &sp[allocd_seccnt];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1154
		if (exs->s_rootcnt > 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1155
			if (!sec_svc_loadrootnames(exs->s_secinfo.sc_rpcnum,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1156
			    exs->s_rootcnt, &exs->s_rootnames, model)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1157
				error = EFAULT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1158
				goto out5;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1159
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1160
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1161
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1162
		if (exs->s_secinfo.sc_rpcnum == RPCSEC_GSS) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1163
			rpc_gss_OID mech_tmp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1164
			STRUCT_DECL(rpc_gss_OID_s, umech_tmp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1165
			caddr_t elements_tmp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1166
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1167
			/* Copyin mechanism type */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1168
			STRUCT_INIT(umech_tmp, model);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1169
			mech_tmp = kmem_alloc(sizeof (*mech_tmp), KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1170
			if (copyin(exs->s_secinfo.sc_gss_mech_type,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1171
			    STRUCT_BUF(umech_tmp), STRUCT_SIZE(umech_tmp))) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1172
				kmem_free(mech_tmp, sizeof (*mech_tmp));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1173
				error = EFAULT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1174
				goto out5;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1175
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1176
			mech_tmp->length = STRUCT_FGET(umech_tmp, length);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1177
			mech_tmp->elements = STRUCT_FGETP(umech_tmp, elements);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1178
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1179
			elements_tmp = kmem_alloc(mech_tmp->length, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1180
			if (copyin(mech_tmp->elements, elements_tmp,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1181
			    mech_tmp->length)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1182
				kmem_free(elements_tmp, mech_tmp->length);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1183
				kmem_free(mech_tmp, sizeof (*mech_tmp));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1184
				error = EFAULT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1185
				goto out5;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1186
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1187
			mech_tmp->elements = elements_tmp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1188
			exs->s_secinfo.sc_gss_mech_type = mech_tmp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1189
			allocd_seccnt++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1190
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1191
			callback = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1192
		} else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1193
			allocd_seccnt++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1194
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1195
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1196
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1197
	 * Init the secinfo reference count and mark these flavors
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1198
	 * explicitly exported flavors.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1199
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1200
	for (i = 0; i < kex->ex_seccnt; i++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1201
		kex->ex_secinfo[i].s_flags |= M_4SEC_EXPORTED;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1202
		kex->ex_secinfo[i].s_refcnt++;  /* 1 reference count */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1203
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1204
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1205
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1206
	 *  Set up rpcsec_gss callback routine entry if any.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1207
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1208
	if (callback) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1209
		cb.callback = rfs_gsscallback;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1210
		cb.program = NFS_ACL_PROGRAM;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1211
		for (cb.version = NFS_ACL_VERSMIN;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1212
		    cb.version <= NFS_ACL_VERSMAX; cb.version++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1213
			(void) sec_svc_control(RPC_SVC_SET_GSS_CALLBACK,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1214
			    (void *)&cb);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1215
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1216
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1217
		cb.program = NFS_PROGRAM;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1218
		for (cb.version = NFS_VERSMIN;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1219
		    cb.version <= NFS_VERSMAX; cb.version++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1220
			(void) sec_svc_control(RPC_SVC_SET_GSS_CALLBACK,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1221
			    (void *)&cb);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1222
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1223
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1224
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1225
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1226
	 * Check the index flag. Do this here to avoid holding the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1227
	 * lock while dealing with the index option (as we do with
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1228
	 * the public option).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1229
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1230
	if (kex->ex_flags & EX_INDEX) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1231
		if (!kex->ex_index) {	/* sanity check */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1232
			error = EINVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1233
			goto out5;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1234
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1235
		if (error = loadindex(kex))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1236
			goto out5;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1237
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1238
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1239
	if (kex->ex_flags & EX_LOG) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1240
		if (error = nfslog_setup(exi))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1241
			goto out6;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1242
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1243
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1244
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1245
	 * Insert the new entry at the front of the export list
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1246
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1247
	rw_enter(&exported_lock, RW_WRITER);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1248
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1249
	export_link(exi);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1250
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1251
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1252
	 * Check the rest of the list for an old entry for the fs.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1253
	 * If one is found then unlink it, wait until this is the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1254
	 * only reference and then free it.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1255
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1256
	prev = exi;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1257
	for (ex = prev->exi_hash; ex != NULL; prev = ex, ex = ex->exi_hash) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1258
		if (ex != exi_root && VN_CMP(ex->exi_vp, vp)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1259
			prev->exi_hash = ex->exi_hash;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1260
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1261
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1262
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1263
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1264
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1265
	 * If the public filehandle is pointing at the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1266
	 * old entry, then point it back at the root.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1267
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1268
	if (ex != NULL && ex == exi_public)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1269
		exi_public = exi_root;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1270
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1271
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1272
	 * If the public flag is on, make the global exi_public
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1273
	 * point to this entry and turn off the public bit so that
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1274
	 * we can distinguish it from the place holder export.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1275
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1276
	if (kex->ex_flags & EX_PUBLIC) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1277
		exi_public = exi;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1278
		kex->ex_flags &= ~EX_PUBLIC;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1279
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1280
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1281
#ifdef VOLATILE_FH_TEST
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1282
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1283
	 * Set up the volatile_id value if volatile on share.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1284
	 * The list of volatile renamed filehandles is always destroyed,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1285
	 * if the fs was reshared.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1286
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1287
	if (kex->ex_flags & EX_VOLFH)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1288
		exi->exi_volatile_id = gethrestime_sec();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1289
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1290
	mutex_init(&exi->exi_vol_rename_lock, NULL, MUTEX_DEFAULT, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1291
#endif /* VOLATILE_FH_TEST */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1292
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1293
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1294
	 * If this is a new export, then climb up
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1295
	 * the tree and check if any pseudo exports
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1296
	 * need to be created to provide a path for
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1297
	 * NFS v4 clients.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1298
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1299
	if (ex == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1300
		error = treeclimb_export(exi);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1301
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1302
	if (!error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1303
		error = srv_secinfo_treeclimb(exi, TRUE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1304
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1305
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1306
	 * If re-sharing an old export entry, update the secinfo data
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1307
	 * depending on if the old entry is a pseudo node or not.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1308
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1309
	if (!error && ex != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1310
		if (PSEUDO(ex)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1311
		    srv_secinfo_add(&exi->exi_export, &ex->exi_export);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1312
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1313
		    srv_secinfo_exp2exp(&exi->exi_export, &ex->exi_export);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1314
		    error = srv_secinfo_treeclimb(ex, FALSE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1315
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1316
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1317
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1318
	if (error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1319
		goto out7;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1320
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1321
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1322
	 * If it's a re-export and the old entry has a visible list,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1323
	 * then transfer its visible list to the new export.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1324
	 * Note: only VROOT node may have a visible list either
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1325
	 * it is a PSEUDO node or a real export node.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1326
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1327
	if (ex != NULL && (ex->exi_visible != NULL)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1328
		exi->exi_visible = ex->exi_visible;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1329
		ex->exi_visible = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1330
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1331
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1332
	rw_exit(&exported_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1333
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1334
	if (exi_public == exi || kex->ex_flags & EX_LOG) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1335
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1336
		 * Log share operation to this buffer only.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1337
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1338
		nfslog_share_record(exi, cr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1339
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1340
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1341
	if (ex != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1342
		exi_rele(ex);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1343
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1344
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1345
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1346
out7:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1347
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1348
	 * Cleaning up the tree. Assuming *treeclimb* routines
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1349
	 * will fail at the same place in the tree.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1350
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1351
	(void) treeclimb_unexport(exi);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1352
	(void) srv_secinfo_treeclimb(exi, FALSE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1353
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1354
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1355
	 * Unlink and re-link the new and old export in exptable.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1356
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1357
	(void) export_unlink(&exi->exi_fsid, &exi->exi_fid, exi->exi_vp, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1358
	if (ex != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1359
		export_link(ex);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1360
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1361
	rw_exit(&exported_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1362
out6:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1363
	if (kex->ex_flags & EX_INDEX)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1364
		kmem_free(kex->ex_index, strlen(kex->ex_index) + 1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1365
out5:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1366
	/* free partially completed allocation */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1367
	while (--allocd_seccnt >= 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1368
		exs = &kex->ex_secinfo[allocd_seccnt];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1369
		srv_secinfo_entry_free(exs);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1370
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1371
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1372
	if (kex->ex_secinfo) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1373
		kmem_free(kex->ex_secinfo,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1374
			kex->ex_seccnt * sizeof (struct secinfo));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1375
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1376
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1377
out4:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1378
	if ((kex->ex_flags & EX_LOG) && kex->ex_tag != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1379
		kmem_free(kex->ex_tag, kex->ex_taglen + 1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1380
out3:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1381
	if ((kex->ex_flags & EX_LOG) && kex->ex_log_buffer != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1382
		kmem_free(kex->ex_log_buffer, kex->ex_log_bufferlen + 1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1383
out2:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1384
	kmem_free(kex->ex_path, kex->ex_pathlen + 1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1385
out1:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1386
	VN_RELE(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1387
	if (dvp != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1388
		VN_RELE(dvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1389
	mutex_destroy(&exi->exi_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1390
	rw_destroy(&exi->exi_cache_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1391
	kmem_free(exi, sizeof (*exi));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1392
	return (error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1393
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1394
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1395
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1396
 * Remove the exportinfo from the export list
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1397
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1398
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1399
export_unlink(fsid_t *fsid, fid_t *fid, vnode_t *vp, struct exportinfo **exip)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1400
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1401
	struct exportinfo **tail;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1402
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1403
	ASSERT(RW_WRITE_HELD(&exported_lock));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1404
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1405
	tail = &exptable[exptablehash(fsid, fid)];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1406
	while (*tail != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1407
		if (exportmatch(*tail, fsid, fid)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1408
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1409
			 * If vp is given, check if vp is the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1410
			 * same vnode as the exported node.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1411
			 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1412
			 * Since VOP_FID of a lofs node returns the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1413
			 * fid of its real node (ufs), the exported
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1414
			 * node for lofs and (pseudo) ufs may have
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1415
			 * the same fsid and fid.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1416
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1417
			if (vp == NULL || vp == (*tail)->exi_vp) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1418
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1419
				if (exip != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1420
					*exip = *tail;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1421
				*tail = (*tail)->exi_hash;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1422
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1423
				return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1424
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1425
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1426
		tail = &(*tail)->exi_hash;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1427
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1428
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1429
	return (EINVAL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1430
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1431
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1432
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1433
 * Unexport an exported filesystem
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1434
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1435
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1436
unexport(fsid_t *fsid, fid_t *fid, vnode_t *vp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1437
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1438
	struct exportinfo *exi = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1439
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1440
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1441
	rw_enter(&exported_lock, RW_WRITER);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1442
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1443
	error = export_unlink(fsid, fid, vp, &exi);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1444
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1445
	if (error) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1446
		rw_exit(&exported_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1447
		return (error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1448
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1449
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1450
	/* pseudo node is not a real exported filesystem */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1451
	if (PSEUDO(exi)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1452
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1453
		 * Put the pseudo node back into the export table
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1454
		 * before erroring out.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1455
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1456
		export_link(exi);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1457
		rw_exit(&exported_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1458
		return (EINVAL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1459
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1460
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1461
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1462
	 * If there's a visible list, then need to leave
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1463
	 * a pseudo export here to retain the visible list
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1464
	 * for paths to exports below.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1465
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1466
	if (exi->exi_visible) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1467
		error = pseudo_exportfs(exi->exi_vp, exi->exi_visible,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1468
						&exi->exi_export);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1469
		if (error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1470
			goto done;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1471
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1472
		exi->exi_visible = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1473
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1474
		error = treeclimb_unexport(exi);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1475
		if (error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1476
			goto done;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1477
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1478
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1479
	error = srv_secinfo_treeclimb(exi, FALSE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1480
	if (error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1481
		goto done;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1482
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1483
	rw_exit(&exported_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1484
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1485
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1486
	 * Need to call into the NFSv4 server and release all data
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1487
	 * held on this particular export.  This is important since
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1488
	 * the v4 server may be holding file locks or vnodes under
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1489
	 * this export.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1490
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1491
	rfs4_clean_state_exi(exi);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1492
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1493
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1494
	 * Notify the lock manager that the filesystem is being
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1495
	 * unexported.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1496
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1497
	lm_unexport(exi);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1498
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1499
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1500
	 * If this was a public export, restore
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1501
	 * the public filehandle to the root.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1502
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1503
	if (exi == exi_public) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1504
		exi_public = exi_root;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1505
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1506
		nfslog_share_record(exi_public, CRED());
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1507
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1508
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1509
	if (exi->exi_export.ex_flags & EX_LOG) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1510
		nfslog_unshare_record(exi, CRED());
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1511
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1512
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1513
	exi_rele(exi);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1514
	return (error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1515
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1516
done:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1517
	rw_exit(&exported_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1518
	exi_rele(exi);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1519
	return (error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1520
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1521
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1522
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1523
 * Get file handle system call.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1524
 * Takes file name and returns a file handle for it.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1525
 * Credentials must be verified before calling.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1526
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1527
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1528
nfs_getfh(struct nfs_getfh_args *args, model_t model, cred_t *cr)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1529
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1530
	fhandle_t fh;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1531
	vnode_t *vp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1532
	vnode_t *dvp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1533
	struct exportinfo *exi;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1534
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1535
	STRUCT_HANDLE(nfs_getfh_args, uap);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1536
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1537
#ifdef lint
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1538
	model = model;		/* STRUCT macros don't always use it */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1539
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1540
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1541
	STRUCT_SET_HANDLE(uap, model, args);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1542
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1543
	error = lookupname(STRUCT_FGETP(uap, fname), UIO_USERSPACE,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1544
	    FOLLOW, &dvp, &vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1545
	if (error == EINVAL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1546
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1547
		 * if fname resolves to / we get EINVAL error
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1548
		 * since we wanted the parent vnode. Try again
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1549
		 * with NULL dvp.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1550
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1551
		error = lookupname(STRUCT_FGETP(uap, fname), UIO_USERSPACE,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1552
		    FOLLOW, NULL, &vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1553
		dvp = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1554
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1555
	if (!error && vp == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1556
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1557
		 * Last component of fname not found
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1558
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1559
		if (dvp != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1560
			VN_RELE(dvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1561
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1562
		error = ENOENT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1563
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1564
	if (error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1565
		return (error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1566
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1567
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1568
	 * 'vp' may be an AUTOFS node, so we perform a
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1569
	 * VOP_ACCESS() to trigger the mount of the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1570
	 * intended filesystem, so we can share the intended
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1571
	 * filesystem instead of the AUTOFS filesystem.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1572
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1573
	(void) VOP_ACCESS(vp, 0, 0, cr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1574
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1575
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1576
	 * We're interested in the top most filesystem.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1577
	 * This is specially important when uap->dname is a trigger
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1578
	 * AUTOFS node, since we're really interested in sharing the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1579
	 * filesystem AUTOFS mounted as result of the VOP_ACCESS()
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1580
	 * call not the AUTOFS node itself.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1581
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1582
	if (vn_mountedvfs(vp) != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1583
		if (error = traverse(&vp)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1584
			VN_RELE(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1585
			if (dvp != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1586
				VN_RELE(dvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1587
			return (error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1588
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1589
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1590
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1591
	exi = nfs_vptoexi(dvp, vp, cr, NULL, &error, FALSE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1592
	if (!error) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1593
		error = makefh(&fh, vp, exi);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1594
		if (!error && exi->exi_export.ex_flags & EX_LOG) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1595
			nfslog_getfh(exi, &fh, STRUCT_FGETP(uap, fname),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1596
				UIO_USERSPACE, cr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1597
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1598
		exi_rele(exi);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1599
		if (!error) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1600
			if (copyout(&fh, STRUCT_FGETP(uap, fhp), sizeof (fh)))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1601
				error = EFAULT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1602
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1603
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1604
	VN_RELE(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1605
	if (dvp != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1606
		VN_RELE(dvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1607
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1608
	return (error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1609
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1610
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1611
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1612
 * Strategy: if vp is in the export list, then
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1613
 * return the associated file handle. Otherwise, ".."
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1614
 * once up the vp and try again, until the root of the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1615
 * filesystem is reached.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1616
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1617
struct   exportinfo *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1618
nfs_vptoexi(vnode_t *dvp, vnode_t *vp, cred_t *cr, int *walk,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1619
	int *err,  bool_t v4srv)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1620
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1621
	fid_t fid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1622
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1623
	struct exportinfo *exi;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1624
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1625
	ASSERT(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1626
	VN_HOLD(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1627
	if (dvp != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1628
		VN_HOLD(dvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1629
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1630
	if (walk != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1631
		*walk = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1632
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1633
	for (;;) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1634
		bzero(&fid, sizeof (fid));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1635
		fid.fid_len = MAXFIDSZ;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1636
		error = vop_fid_pseudo(vp, &fid);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1637
		if (error) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1638
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1639
			 * If vop_fid_pseudo returns ENOSPC then the fid
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1640
			 * supplied is too small. For now we simply
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1641
			 * return EREMOTE.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1642
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1643
			if (error == ENOSPC)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1644
				error = EREMOTE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1645
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1646
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1647
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1648
		if (v4srv)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1649
			exi = checkexport4(&vp->v_vfsp->vfs_fsid, &fid, vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1650
		else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1651
			exi = checkexport(&vp->v_vfsp->vfs_fsid, &fid);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1652
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1653
		if (exi != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1654
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1655
			 * Found the export info
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1656
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1657
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1658
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1659
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1660
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1661
		 * We have just failed finding a matching export.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1662
		 * If we're at the root of this filesystem, then
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1663
		 * it's time to stop (with failure).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1664
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1665
		if (vp->v_flag & VROOT) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1666
			error = EINVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1667
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1668
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1669
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1670
		if (walk != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1671
			(*walk)++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1672
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1673
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1674
		 * Now, do a ".." up vp. If dvp is supplied, use it,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1675
		 * otherwise, look it up.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1676
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1677
		if (dvp == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1678
			error = VOP_LOOKUP(vp, "..", &dvp, NULL, 0, NULL, cr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1679
			if (error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1680
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1681
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1682
		VN_RELE(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1683
		vp = dvp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1684
		dvp = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1685
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1686
	VN_RELE(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1687
	if (dvp != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1688
		VN_RELE(dvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1689
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1690
	if (error != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1691
		if (err != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1692
			*err = error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1693
		return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1694
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1695
	return (exi);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1696
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1697
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1698
bool_t
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1699
chk_clnt_sec(struct exportinfo *exi, struct svc_req *req)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1700
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1701
	int i, nfsflavor;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1702
	struct secinfo *sp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1703
	bool_t sec_found = FALSE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1704
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1705
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1706
	 *  Get the nfs flavor number from xprt.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1707
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1708
	nfsflavor = (int)(uintptr_t)req->rq_xprt->xp_cookie;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1709
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1710
	sp = exi->exi_export.ex_secinfo;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1711
	for (i = 0; i < exi->exi_export.ex_seccnt; i++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1712
		if (nfsflavor == sp[i].s_secinfo.sc_nfsnum) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1713
			sec_found = TRUE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1714
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1715
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1716
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1717
	return (sec_found);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1718
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1719
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1720
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1721
 * Make an fhandle from a vnode
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1722
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1723
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1724
makefh(fhandle_t *fh, vnode_t *vp, struct exportinfo *exi)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1725
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1726
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1727
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1728
	*fh = exi->exi_fh;	/* struct copy */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1729
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1730
	error = VOP_FID(vp, (fid_t *)&fh->fh_len);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1731
	if (error) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1732
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1733
		 * Should be something other than EREMOTE
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1734
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1735
		return (EREMOTE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1736
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1737
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1738
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1739
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1740
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1741
 * This routine makes an overloaded V2 fhandle which contains
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1742
 * sec modes.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1743
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1744
 * Note that the first four octets contain the length octet,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1745
 * the status octet, and two padded octets to make them XDR
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1746
 * four-octet aligned.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1747
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1748
 *   1   2   3   4                                          32
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1749
 * +---+---+---+---+---+---+---+---+   +---+---+---+---+   +---+
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1750
 * | l | s |   |   |     sec_1     |...|     sec_n     |...|   |
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1751
 * +---+---+---+---+---+---+---+---+   +---+---+---+---+   +---+
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1752
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1753
 * where
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1754
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1755
 *   the status octet s indicates whether there are more security
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1756
 *   flavors (1 means yes, 0 means no) that require the client to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1757
 *   perform another 0x81 LOOKUP to get them,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1758
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1759
 *   the length octet l is the length describing the number of
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1760
 *   valid octets that follow.  (l = 4 * n, where n is the number
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1761
 *   of security flavors sent in the current overloaded filehandle.)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1762
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1763
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1764
makefh_ol(fhandle_t *fh, struct exportinfo *exi, uint_t sec_index)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1765
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1766
	static int max_cnt = (NFS_FHSIZE/sizeof (int)) - 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1767
	int totalcnt, i, *ipt, cnt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1768
	char *c;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1769
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1770
	if (fh == (fhandle_t *)NULL ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1771
		exi == (struct exportinfo *)NULL ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1772
		sec_index > exi->exi_export.ex_seccnt ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1773
		sec_index < 1)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1774
		return (EREMOTE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1775
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1776
	totalcnt = exi->exi_export.ex_seccnt-sec_index+1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1777
	cnt = totalcnt > max_cnt? max_cnt : totalcnt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1778
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1779
	c = (char *)fh;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1780
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1781
	 * Encode the length octet representing the number of
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1782
	 * security flavors (in bytes) in this overloaded fh.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1783
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1784
	*c = cnt * sizeof (int);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1785
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1786
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1787
	 * Encode the status octet that indicates whether there
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1788
	 * are more security flavors the client needs to get.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1789
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1790
	*(c+1) = totalcnt > max_cnt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1791
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1792
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1793
	 * put security flavors in the overloaded fh
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1794
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1795
	ipt = (int *)(c + sizeof (int32_t));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1796
	for (i = 0; i < cnt; i++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1797
		*ipt++ = htonl(exi->exi_export.ex_secinfo[i+sec_index-1].
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1798
				s_secinfo.sc_nfsnum);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1799
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1800
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1801
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1802
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1803
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1804
 * Make an nfs_fh3 from a vnode
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1805
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1806
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1807
makefh3(nfs_fh3 *fh, vnode_t *vp, struct exportinfo *exi)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1808
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1809
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1810
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1811
	fh->fh3_length = sizeof (fh->fh3_u.nfs_fh3_i);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1812
	fh->fh3_u.nfs_fh3_i.fh3_i = exi->exi_fh;	/* struct copy */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1813
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1814
	error = VOP_FID(vp, (fid_t *)&fh->fh3_len);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1815
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1816
	if (error) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1817
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1818
		 * Should be something other than EREMOTE
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1819
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1820
		return (EREMOTE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1821
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1822
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1823
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1824
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1825
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1826
 * This routine makes an overloaded V3 fhandle which contains
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1827
 * sec modes.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1828
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1829
 *  1        4
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1830
 * +--+--+--+--+
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1831
 * |    len    |
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1832
 * +--+--+--+--+
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1833
 *                                               up to 64
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1834
 * +--+--+--+--+--+--+--+--+--+--+--+--+     +--+--+--+--+
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1835
 * |s |  |  |  |   sec_1   |   sec_2   | ... |   sec_n   |
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1836
 * +--+--+--+--+--+--+--+--+--+--+--+--+     +--+--+--+--+
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1837
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1838
 * len = 4 * (n+1), where n is the number of security flavors
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1839
 * sent in the current overloaded filehandle.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1840
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1841
 * the status octet s indicates whether there are more security
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1842
 * mechanisms (1 means yes, 0 means no) that require the client
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1843
 * to perform another 0x81 LOOKUP to get them.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1844
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1845
 * Three octets are padded after the status octet.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1846
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1847
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1848
makefh3_ol(nfs_fh3 *fh, struct exportinfo *exi, uint_t sec_index)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1849
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1850
	static int max_cnt = NFS3_FHSIZE/sizeof (int) - 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1851
	int totalcnt, cnt, *ipt, i;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1852
	char *c;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1853
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1854
	if (fh == (nfs_fh3 *)NULL ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1855
		exi == (struct exportinfo *)NULL ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1856
		sec_index > exi->exi_export.ex_seccnt ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1857
		sec_index < 1) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1858
		return (EREMOTE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1859
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1860
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1861
	totalcnt = exi->exi_export.ex_seccnt-sec_index+1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1862
	cnt = totalcnt > max_cnt? max_cnt : totalcnt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1863
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1864
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1865
	 * Place the length in fh3_length representing the number
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1866
	 * of security flavors (in bytes) in this overloaded fh.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1867
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1868
	fh->fh3_length = (cnt+1) * sizeof (int32_t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1869
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1870
	c = (char *)&fh->fh3_u.nfs_fh3_i.fh3_i;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1871
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1872
	 * Encode the status octet that indicates whether there
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1873
	 * are more security flavors the client needs to get.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1874
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1875
	*c = totalcnt > max_cnt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1876
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1877
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1878
	 * put security flavors in the overloaded fh
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1879
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1880
	ipt = (int *)(c + sizeof (int32_t));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1881
	for (i = 0; i < cnt; i++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1882
		*(ipt+i) = htonl(
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1883
		exi->exi_export.ex_secinfo[i+sec_index-1].s_secinfo.sc_nfsnum);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1884
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1885
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1886
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1887
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1888
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1889
 * Make an nfs_fh4 from a vnode
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1890
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1891
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1892
makefh4(nfs_fh4 *fh, vnode_t *vp, struct exportinfo *exi)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1893
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1894
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1895
	nfs_fh4_fmt_t *fh_fmtp = (nfs_fh4_fmt_t *)fh->nfs_fh4_val;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1896
	fid_t fid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1897
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1898
	bzero(&fid, sizeof (fid));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1899
	fid.fid_len = MAXFIDSZ;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1900
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1901
	 * vop_fid_pseudo() is used to set up NFSv4 namespace, so
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1902
	 * use vop_fid_pseudo() here to get the fid instead of VOP_FID.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1903
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1904
	error = vop_fid_pseudo(vp, &fid);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1905
	if (error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1906
		return (error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1907
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1908
	fh->nfs_fh4_len = NFS_FH4_LEN;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1909
806
849fb015aa25 6337437 .zfs doesn't work over NFS
ek110237
parents: 0
diff changeset
  1910
	fh_fmtp->fh4_i.fhx_fsid = exi->exi_fh.fh_fsid;
849fb015aa25 6337437 .zfs doesn't work over NFS
ek110237
parents: 0
diff changeset
  1911
	fh_fmtp->fh4_i.fhx_xlen = exi->exi_fh.fh_xlen;
849fb015aa25 6337437 .zfs doesn't work over NFS
ek110237
parents: 0
diff changeset
  1912
849fb015aa25 6337437 .zfs doesn't work over NFS
ek110237
parents: 0
diff changeset
  1913
	bzero(fh_fmtp->fh4_i.fhx_data, sizeof (fh_fmtp->fh4_i.fhx_data));
849fb015aa25 6337437 .zfs doesn't work over NFS
ek110237
parents: 0
diff changeset
  1914
	bzero(fh_fmtp->fh4_i.fhx_xdata, sizeof (fh_fmtp->fh4_i.fhx_xdata));
849fb015aa25 6337437 .zfs doesn't work over NFS
ek110237
parents: 0
diff changeset
  1915
	bcopy(exi->exi_fh.fh_xdata, fh_fmtp->fh4_i.fhx_xdata,
849fb015aa25 6337437 .zfs doesn't work over NFS
ek110237
parents: 0
diff changeset
  1916
		exi->exi_fh.fh_xlen);
849fb015aa25 6337437 .zfs doesn't work over NFS
ek110237
parents: 0
diff changeset
  1917
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1918
	fh_fmtp->fh4_len = fid.fid_len;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1919
	ASSERT(fid.fid_len <= sizeof (fh_fmtp->fh4_data));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1920
	bcopy(fid.fid_data, fh_fmtp->fh4_data, fid.fid_len);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1921
	fh_fmtp->fh4_flag = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1922
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1923
#ifdef VOLATILE_FH_TEST
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1924
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1925
	 * XXX (temporary?)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1926
	 * Use the rnode volatile_id value to add volatility to the fh.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1927
	 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1928
	 * For testing purposes there are currently two scenarios, based
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1929
	 * on whether the filesystem was shared with "volatile_fh"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1930
	 * or "expire_on_rename". In the first case, use the value of
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1931
	 * export struct share_time as the volatile_id. In the second
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1932
	 * case use the vnode volatile_id value (which is set to the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1933
	 * time in which the file was renamed).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1934
	 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1935
	 * Note that the above are temporary constructs for testing only
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1936
	 * XXX
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1937
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1938
	if (exi->exi_export.ex_flags & EX_VOLRNM) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1939
		fh_fmtp->fh4_volatile_id = find_volrnm_fh_id(exi, fh);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1940
	} else if (exi->exi_export.ex_flags & EX_VOLFH) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1941
		fh_fmtp->fh4_volatile_id = exi->exi_volatile_id;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1942
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1943
		fh_fmtp->fh4_volatile_id = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1944
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1945
#endif /* VOLATILE_FH_TEST */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1946
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1947
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1948
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1949
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1950
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1951
 * Convert an fhandle into a vnode.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1952
 * Uses the file id (fh_len + fh_data) in the fhandle to get the vnode.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1953
 * WARNING: users of this routine must do a VN_RELE on the vnode when they
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1954
 * are done with it.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1955
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1956
vnode_t *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1957
nfs_fhtovp(fhandle_t *fh, struct exportinfo *exi)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1958
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1959
	vfs_t *vfsp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1960
	vnode_t *vp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1961
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1962
	fid_t *fidp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1963
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1964
	TRACE_0(TR_FAC_NFS, TR_FHTOVP_START,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1965
		"fhtovp_start");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1966
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1967
	if (exi == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1968
		TRACE_1(TR_FAC_NFS, TR_FHTOVP_END,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1969
			"fhtovp_end:(%S)", "exi NULL");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1970
		return (NULL);	/* not exported */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1971
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1972
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1973
	ASSERT(exi->exi_vp != NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1974
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1975
	if (PUBLIC_FH2(fh)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1976
		if (exi->exi_export.ex_flags & EX_PUBLIC) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1977
			TRACE_1(TR_FAC_NFS, TR_FHTOVP_END,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1978
				"fhtovp_end:(%S)", "root not exported");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1979
			return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1980
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1981
		vp = exi->exi_vp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1982
		VN_HOLD(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1983
		return (vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1984
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1985
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1986
	vfsp = exi->exi_vp->v_vfsp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1987
	ASSERT(vfsp != NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1988
	fidp = (fid_t *)&fh->fh_len;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1989
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1990
	error = VFS_VGET(vfsp, &vp, fidp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1991
	if (error || vp == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1992
		TRACE_1(TR_FAC_NFS, TR_FHTOVP_END,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1993
			"fhtovp_end:(%S)", "VFS_GET failed or vp NULL");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1994
		return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1995
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1996
	TRACE_1(TR_FAC_NFS, TR_FHTOVP_END,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1997
		"fhtovp_end:(%S)", "end");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1998
	return (vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1999
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2000
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2001
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2002
 * Convert an fhandle into a vnode.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2003
 * Uses the file id (fh_len + fh_data) in the fhandle to get the vnode.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2004
 * WARNING: users of this routine must do a VN_RELE on the vnode when they
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2005
 * are done with it.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2006
 * This is just like nfs_fhtovp() but without the exportinfo argument.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2007
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2008
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2009
vnode_t *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2010
lm_fhtovp(fhandle_t *fh)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2011
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2012
	register vfs_t *vfsp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2013
	vnode_t *vp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2014
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2015
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2016
	vfsp = getvfs(&fh->fh_fsid);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2017
	if (vfsp == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2018
		return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2019
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2020
	error = VFS_VGET(vfsp, &vp, (fid_t *)&(fh->fh_len));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2021
	VFS_RELE(vfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2022
	if (error || vp == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2023
		return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2024
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2025
	return (vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2026
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2027
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2028
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2029
 * Convert an nfs_fh3 into a vnode.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2030
 * Uses the file id (fh_len + fh_data) in the file handle to get the vnode.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2031
 * WARNING: users of this routine must do a VN_RELE on the vnode when they
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2032
 * are done with it.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2033
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2034
vnode_t *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2035
nfs3_fhtovp(nfs_fh3 *fh, struct exportinfo *exi)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2036
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2037
	vfs_t *vfsp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2038
	vnode_t *vp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2039
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2040
	fid_t *fidp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2041
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2042
	if (exi == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2043
		return (NULL);	/* not exported */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2044
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2045
	ASSERT(exi->exi_vp != NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2046
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2047
	if (PUBLIC_FH3(fh)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2048
		if (exi->exi_export.ex_flags & EX_PUBLIC)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2049
			return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2050
		vp = exi->exi_vp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2051
		VN_HOLD(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2052
		return (vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2053
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2054
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2055
	if (fh->fh3_length != NFS3_CURFHSIZE)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2056
		return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2057
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2058
	vfsp = exi->exi_vp->v_vfsp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2059
	ASSERT(vfsp != NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2060
	fidp = (fid_t *)&fh->fh3_len;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2061
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2062
	error = VFS_VGET(vfsp, &vp, fidp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2063
	if (error || vp == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2064
		return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2065
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2066
	return (vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2067
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2068
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2069
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2070
 * Convert an nfs_fh3 into a vnode.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2071
 * Uses the file id (fh_len + fh_data) in the file handle to get the vnode.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2072
 * WARNING: users of this routine must do a VN_RELE on the vnode when they
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2073
 * are done with it.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2074
 * BTW: This is just like nfs3_fhtovp() but without the exportinfo arg.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2075
 * Also, vfsp is accessed through getvfs() rather using exportinfo !!
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2076
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2077
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2078
vnode_t *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2079
lm_nfs3_fhtovp(nfs_fh3 *fh)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2080
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2081
	vfs_t *vfsp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2082
	vnode_t *vp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2083
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2084
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2085
	if (fh->fh3_length != NFS3_CURFHSIZE)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2086
		return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2087
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2088
	vfsp = getvfs(&fh->fh3_fsid);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2089
	if (vfsp == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2090
		return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2091
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2092
	error = VFS_VGET(vfsp, &vp, (fid_t *)&(fh->fh3_len));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2093
	VFS_RELE(vfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2094
	if (error || vp == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2095
		return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2096
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2097
	return (vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2098
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2099
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2100
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2101
 * Convert an nfs_fh4 into a vnode.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2102
 * Uses the file id (fh_len + fh_data) in the file handle to get the vnode.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2103
 * WARNING: users of this routine must do a VN_RELE on the vnode when they
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2104
 * are done with it.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2105
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2106
vnode_t *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2107
nfs4_fhtovp(nfs_fh4 *fh, struct exportinfo *exi, nfsstat4 *statp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2108
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2109
	vfs_t *vfsp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2110
	vnode_t *vp = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2111
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2112
	fid_t *fidp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2113
	nfs_fh4_fmt_t *fh_fmtp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2114
#ifdef VOLATILE_FH_TEST
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2115
	uint32_t volatile_id = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2116
#endif /* VOLATILE_FH_TEST */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2117
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2118
	if (exi == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2119
		*statp = NFS4ERR_STALE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2120
		return (NULL);	/* not exported */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2121
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2122
	ASSERT(exi->exi_vp != NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2123
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2124
	/* caller should have checked this */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2125
	ASSERT(fh->nfs_fh4_len >= NFS_FH4_LEN);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2126
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2127
	fh_fmtp = (nfs_fh4_fmt_t *)fh->nfs_fh4_val;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2128
	vfsp = exi->exi_vp->v_vfsp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2129
	ASSERT(vfsp != NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2130
	fidp = (fid_t *)&fh_fmtp->fh4_len;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2131
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2132
#ifdef VOLATILE_FH_TEST
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2133
	/* XXX check if volatile - should be changed later */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2134
	if (exi->exi_export.ex_flags & (EX_VOLRNM | EX_VOLFH)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2135
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2136
		 * Filesystem is shared with volatile filehandles
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2137
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2138
		if (exi->exi_export.ex_flags & EX_VOLRNM)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2139
			volatile_id = find_volrnm_fh_id(exi, fh);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2140
		else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2141
			volatile_id = exi->exi_volatile_id;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2142
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2143
		if (fh_fmtp->fh4_volatile_id != volatile_id) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2144
			*statp = NFS4ERR_FHEXPIRED;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2145
			return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2146
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2147
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2148
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2149
	 * XXX even if test_volatile_fh false, the fh may contain a
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2150
	 * volatile id if obtained when the test was set.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2151
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2152
	fh_fmtp->fh4_volatile_id = (uchar_t)0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2153
#endif /* VOLATILE_FH_TEST */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2154
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2155
	error = VFS_VGET(vfsp, &vp, fidp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2156
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2157
	 * If we can not get vp from VFS_VGET, perhaps this is
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2158
	 * an nfs v2/v3/v4 node in an nfsv4 pseudo filesystem.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2159
	 * Check it out.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2160
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2161
	if (error && PSEUDO(exi))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2162
		error = nfs4_vget_pseudo(exi, &vp, fidp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2163
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2164
	if (error || vp == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2165
		*statp = NFS4ERR_STALE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2166
		return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2167
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2168
	/* XXX - disgusting hack */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2169
	if (vp->v_type == VNON && vp->v_flag & V_XATTRDIR)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2170
		vp->v_type = VDIR;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2171
	*statp = NFS4_OK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2172
	return (vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2173
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2174
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2175
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2176
 * Find the export structure associated with the given filesystem.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2177
 * If found, then increment the ref count (exi_count).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2178
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2179
struct exportinfo *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2180
checkexport(fsid_t *fsid, fid_t *fid)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2181
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2182
	struct exportinfo *exi;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2183
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2184
	rw_enter(&exported_lock, RW_READER);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2185
	for (exi = exptable[exptablehash(fsid, fid)];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2186
	    exi != NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2187
	    exi = exi->exi_hash) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2188
		if (exportmatch(exi, fsid, fid)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2189
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2190
			 * If this is the place holder for the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2191
			 * public file handle, then return the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2192
			 * real export entry for the public file
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2193
			 * handle.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2194
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2195
			if (exi->exi_export.ex_flags & EX_PUBLIC) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2196
				exi = exi_public;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2197
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2198
			mutex_enter(&exi->exi_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2199
			exi->exi_count++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2200
			mutex_exit(&exi->exi_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2201
			rw_exit(&exported_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2202
			return (exi);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2203
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2204
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2205
	rw_exit(&exported_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2206
	return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2207
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2208
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2209
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2210
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2211
 * "old school" version of checkexport() for NFS4.  NFS4
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2212
 * rfs4_compound holds exported_lock for duration of compound
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2213
 * processing.  This version doesn't manipulate exi_count
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2214
 * since NFS4 breaks fundamental assumptions in the exi_count
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2215
 * design.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2216
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2217
struct exportinfo *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2218
checkexport4(fsid_t *fsid, fid_t *fid, vnode_t *vp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2219
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2220
	struct exportinfo *exi;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2221
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2222
	ASSERT(RW_LOCK_HELD(&exported_lock));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2223
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2224
	for (exi = exptable[exptablehash(fsid, fid)];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2225
	    exi != NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2226
	    exi = exi->exi_hash) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2227
		if (exportmatch(exi, fsid, fid)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2228
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2229
			 * If this is the place holder for the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2230
			 * public file handle, then return the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2231
			 * real export entry for the public file
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2232
			 * handle.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2233
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2234
			if (exi->exi_export.ex_flags & EX_PUBLIC) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2235
				exi = exi_public;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2236
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2237
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2238
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2239
			 * If vp is given, check if vp is the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2240
			 * same vnode as the exported node.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2241
			 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2242
			 * Since VOP_FID of a lofs node returns the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2243
			 * fid of its real node (ufs), the exported
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2244
			 * node for lofs and (pseudo) ufs may have
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2245
			 * the same fsid and fid.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2246
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2247
			if (vp == NULL || vp == exi->exi_vp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2248
				return (exi);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2249
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2250
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2251
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2252
	return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2253
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2254
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2255
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2256
 * Free an entire export list node
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2257
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2258
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2259
exportfree(struct exportinfo *exi)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2260
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2261
	struct exportdata *ex;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2262
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2263
	ex = &exi->exi_export;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2264
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2265
	ASSERT(exi->exi_vp != NULL && !(exi->exi_export.ex_flags & EX_PUBLIC));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2266
	VN_RELE(exi->exi_vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2267
	if (exi->exi_dvp != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2268
		VN_RELE(exi->exi_dvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2269
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2270
	if (ex->ex_flags & EX_INDEX)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2271
		kmem_free(ex->ex_index, strlen(ex->ex_index) + 1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2272
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2273
	kmem_free(ex->ex_path, ex->ex_pathlen + 1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2274
	nfsauth_cache_free(exi);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2275
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2276
	if (exi->exi_logbuffer != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2277
		nfslog_disable(exi);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2278
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2279
	if (ex->ex_flags & EX_LOG) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2280
		kmem_free(ex->ex_log_buffer, ex->ex_log_bufferlen + 1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2281
		kmem_free(ex->ex_tag, ex->ex_taglen + 1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2282
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2283
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2284
	if (exi->exi_visible)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2285
		free_visible(exi->exi_visible);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2286
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2287
	srv_secinfo_list_free(ex->ex_secinfo, ex->ex_seccnt);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2288
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2289
#ifdef VOLATILE_FH_TEST
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2290
	free_volrnm_list(exi);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2291
	mutex_destroy(&exi->exi_vol_rename_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2292
#endif /* VOLATILE_FH_TEST */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2293
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2294
	mutex_destroy(&exi->exi_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2295
	rw_destroy(&exi->exi_cache_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2296
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2297
	kmem_free(exi, sizeof (*exi));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2298
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2299
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2300
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2301
 * load the index file from user space into kernel space.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2302
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2303
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2304
loadindex(struct exportdata *kex)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2305
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2306
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2307
	char index[MAXNAMELEN+1];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2308
	size_t len;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2309
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2310
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2311
	 * copyinstr copies the complete string including the NULL and
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2312
	 * returns the len with the NULL byte included in the calculation
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2313
	 * as long as the max length is not exceeded.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2314
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2315
	if (error = copyinstr(kex->ex_index, index, sizeof (index), &len))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2316
		return (error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2317
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2318
	kex->ex_index = kmem_alloc(len, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2319
	bcopy(index, kex->ex_index, len);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2320
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2321
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2322
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2323
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2324
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2325
 * When a thread completes using exi, it should call exi_rele().
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2326
 * exi_rele() decrements exi_count. It releases exi if exi_count == 0, i.e.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2327
 * if this is the last user of exi and exi is not on exportinfo list anymore
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2328
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2329
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2330
exi_rele(struct exportinfo *exi)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2331
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2332
	mutex_enter(&exi->exi_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2333
	exi->exi_count--;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2334
	if (exi->exi_count == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2335
		mutex_exit(&exi->exi_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2336
		exportfree(exi);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2337
	} else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2338
		mutex_exit(&exi->exi_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2339
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2340
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2341
#ifdef VOLATILE_FH_TEST
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2342
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2343
 * Test for volatile fh's - add file handle to list and set its volatile id
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2344
 * to time it was renamed. If EX_VOLFH is also on and the fs is reshared,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2345
 * the vol_rename queue is purged.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2346
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2347
 * XXX This code is for unit testing purposes only... To correctly use it, it
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2348
 * needs to tie a rename list to the export struct and (more
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2349
 * important), protect access to the exi rename list using a write lock.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2350
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2351
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2352
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2353
 * get the fh vol record if it's in the volatile on rename list. Don't check
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2354
 * volatile_id in the file handle - compare only the file handles.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2355
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2356
static struct ex_vol_rename *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2357
find_volrnm_fh(struct exportinfo *exi, nfs_fh4 *fh4p)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2358
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2359
	struct ex_vol_rename *p = NULL;
806
849fb015aa25 6337437 .zfs doesn't work over NFS
ek110237
parents: 0
diff changeset
  2360
	fhandle_ext_t *fhp;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2361
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2362
	/* XXX shouldn't we assert &exported_lock held? */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2363
	ASSERT(MUTEX_HELD(&exi->exi_vol_rename_lock));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2364
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2365
	if (fh4p->nfs_fh4_len != NFS_FH4_LEN) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2366
		return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2367
	}
806
849fb015aa25 6337437 .zfs doesn't work over NFS
ek110237
parents: 0
diff changeset
  2368
	fhp = &((nfs_fh4_fmt_t *)fh4p->nfs_fh4_val)->fh4_i;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2369
	for (p = exi->exi_vol_rename; p != NULL; p = p->vrn_next) {
806
849fb015aa25 6337437 .zfs doesn't work over NFS
ek110237
parents: 0
diff changeset
  2370
		if (bcmp(fhp, &p->vrn_fh_fmt.fh4_i,
849fb015aa25 6337437 .zfs doesn't work over NFS
ek110237
parents: 0
diff changeset
  2371
		    sizeof (fhandle_ext_t)) == 0)
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2372
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2373
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2374
	return (p);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2375
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2376
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2377
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2378
 * get the volatile id for the fh (if there is - else return 0). Ignore the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2379
 * volatile_id in the file handle - compare only the file handles.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2380
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2381
static uint32_t
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2382
find_volrnm_fh_id(struct exportinfo *exi, nfs_fh4 *fh4p)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2383
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2384
	struct ex_vol_rename *p;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2385
	uint32_t volatile_id;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2386
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2387
	mutex_enter(&exi->exi_vol_rename_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2388
	p = find_volrnm_fh(exi, fh4p);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2389
	volatile_id = (p ? p->vrn_fh_fmt.fh4_volatile_id :
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2390
				exi->exi_volatile_id);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2391
	mutex_exit(&exi->exi_vol_rename_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2392
	return (volatile_id);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2393
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2394
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2395
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2396
 * Free the volatile on rename list - will be called if a filesystem is
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2397
 * unshared or reshared without EX_VOLRNM
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2398
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2399
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2400
free_volrnm_list(struct exportinfo *exi)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2401
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2402
	struct ex_vol_rename *p, *pnext;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2403
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2404
	/* no need to hold mutex lock - this one is called from exportfree */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2405
	for (p = exi->exi_vol_rename; p != NULL; p = pnext) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2406
		pnext = p->vrn_next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2407
		kmem_free(p, sizeof (*p));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2408
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2409
	exi->exi_vol_rename = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2410
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2411
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2412
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2413
 * Add a file handle to the volatile on rename list.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2414
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2415
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2416
add_volrnm_fh(struct exportinfo *exi, vnode_t *vp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2417
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2418
	struct ex_vol_rename *p;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2419
	char fhbuf[NFS4_FHSIZE];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2420
	nfs_fh4 fh4;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2421
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2422
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2423
	fh4.nfs_fh4_val = fhbuf;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2424
	error = makefh4(&fh4, vp, exi);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2425
	if ((error) || (fh4.nfs_fh4_len != sizeof (p->vrn_fh_fmt))) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2426
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2427
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2428
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2429
	mutex_enter(&exi->exi_vol_rename_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2430
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2431
	p = find_volrnm_fh(exi, &fh4);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2432
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2433
	if (p == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2434
		p = kmem_alloc(sizeof (*p), KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2435
		bcopy(fh4.nfs_fh4_val, &p->vrn_fh_fmt, sizeof (p->vrn_fh_fmt));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2436
		p->vrn_next = exi->exi_vol_rename;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2437
		exi->exi_vol_rename = p;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2438
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2439
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2440
	p->vrn_fh_fmt.fh4_volatile_id = gethrestime_sec();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2441
	mutex_exit(&exi->exi_vol_rename_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2442
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2443
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2444
#endif /* VOLATILE_FH_TEST */