usr/src/uts/common/fs/nfs/nfs4_srv_ns.c
author jpk
Fri, 24 Mar 2006 12:29:20 -0800
changeset 1676 37f4a3e2bd99
parent 1610 3436e82414c8
child 4871 617ab0770307
permissions -rw-r--r--
PSARC/2002/762 Layered Trusted Solaris PSARC/2005/060 TSNET: Trusted Networking with Security Labels PSARC/2005/259 Layered Trusted Solaris Label Interfaces PSARC/2005/573 Solaris Trusted Extensions for Printing PSARC/2005/691 Trusted Extensions for Device Allocation PSARC/2005/723 Solaris Trusted Extensions Filesystem Labeling PSARC/2006/009 Labeled Auditing PSARC/2006/155 Trusted Extensions RBAC Changes PSARC/2006/191 is_system_labeled 6293271 Zone processes should use zone_kcred instead of kcred 6394554 integrate Solaris Trusted Extensions
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
1610
3436e82414c8 6344186 NFSv3 needs to support .zfs (like NFSv4 already does)
thurlow
parents: 806
diff changeset
     5
 * Common Development and Distribution License (the "License").
3436e82414c8 6344186 NFSv3 needs to support .zfs (like NFSv4 already does)
thurlow
parents: 806
diff changeset
     6
 * You may not use this file except in compliance with the License.
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     7
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     8
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     9
 * or http://www.opensolaris.org/os/licensing.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    10
 * See the License for the specific language governing permissions
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    11
 * and limitations under the License.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    12
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    13
 * When distributing Covered Code, include this CDDL HEADER in each
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    14
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    15
 * If applicable, add the following below this CDDL HEADER, with the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    16
 * fields enclosed by brackets "[]" replaced with your own identifying
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    17
 * information: Portions Copyright [yyyy] [name of copyright owner]
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    18
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    19
 * CDDL HEADER END
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    20
 *
1610
3436e82414c8 6344186 NFSv3 needs to support .zfs (like NFSv4 already does)
thurlow
parents: 806
diff changeset
    21
 * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    22
 * Use is subject to license terms.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    23
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    24
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    25
#pragma ident	"%Z%%M%	%I%	%E% SMI"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    26
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    27
#include <sys/systm.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    28
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    29
#include <nfs/nfs.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    30
#include <nfs/export.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    31
#include <sys/cmn_err.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    32
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    33
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    34
 * A version of VOP_FID that deals with a remote VOP_FID for nfs.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    35
 * If vp is an nfs node, nfs4_fid() returns EREMOTE, nfs3_fid() and nfs_fid()
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    36
 * returns the filehandle of vp as its fid. When nfs uses fid to set the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    37
 * exportinfo filehandle template, a remote nfs filehandle would be too big for
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    38
 * the fid of the exported directory. This routine remaps the value of the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    39
 * attribute va_nodeid of vp to be the fid of vp, so that the fid can fit.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    40
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    41
 * We need this fid mainly for setting up NFSv4 server namespace where an
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    42
 * nfs filesystem is also part of it. Thus, need to be able to setup a pseudo
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    43
 * exportinfo for an nfs node.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    44
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    45
 * e.g. mount an ufs filesystem on an nfs filesystem, then share the ufs
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    46
 *      filesystem. (like exporting a local disk from a "diskless" client)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    47
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    48
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    49
vop_fid_pseudo(vnode_t *vp, fid_t *fidp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    50
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    51
	struct vattr va;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    52
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    53
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    54
	error = VOP_FID(vp, fidp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    55
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    56
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    57
	 * XXX nfs4_fid() does nothing and returns EREMOTE.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    58
	 * XXX nfs3_fid()/nfs_fid() returns nfs filehandle as its fid
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    59
	 * which has a bigger length than local fid.
1610
3436e82414c8 6344186 NFSv3 needs to support .zfs (like NFSv4 already does)
thurlow
parents: 806
diff changeset
    60
	 * NFS_FH4MAXDATA is the size of
3436e82414c8 6344186 NFSv3 needs to support .zfs (like NFSv4 already does)
thurlow
parents: 806
diff changeset
    61
	 * fhandle4_t.fh_xdata[NFS_FH4MAXDATA].
806
849fb015aa25 6337437 .zfs doesn't work over NFS
ek110237
parents: 0
diff changeset
    62
	 *
849fb015aa25 6337437 .zfs doesn't work over NFS
ek110237
parents: 0
diff changeset
    63
	 * Note: nfs[2,3,4]_fid() only gets called for diskless clients.
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    64
	 */
806
849fb015aa25 6337437 .zfs doesn't work over NFS
ek110237
parents: 0
diff changeset
    65
	if (error == EREMOTE ||
1610
3436e82414c8 6344186 NFSv3 needs to support .zfs (like NFSv4 already does)
thurlow
parents: 806
diff changeset
    66
	    (error == 0 && fidp->fid_len > NFS_FH4MAXDATA)) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    67
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    68
		va.va_mask = AT_NODEID;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    69
		error = VOP_GETATTR(vp, &va, 0, CRED());
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    70
		if (error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    71
			return (error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    72
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    73
		fidp->fid_len = sizeof (va.va_nodeid);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    74
		bcopy(&va.va_nodeid, fidp->fid_data, fidp->fid_len);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    75
		return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    76
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    77
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    78
	return (error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    79
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    80
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    81
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    82
 * Get an nfsv4 vnode of the given fid from the visible list of an
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    83
 * nfs filesystem or get the exi_vp if it is the root node.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    84
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    85
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    86
nfs4_vget_pseudo(struct exportinfo *exi, vnode_t **vpp, fid_t *fidp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    87
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    88
	fid_t exp_fid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    89
	struct exp_visible *visp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    90
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    91
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    92
	/* check if the given fid is in the visible list */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    93
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    94
	for (visp = exi->exi_visible; visp; visp = visp->vis_next) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    95
		if (EQFID(fidp, &visp->vis_fid)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    96
			VN_HOLD(visp->vis_vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    97
			*vpp = visp->vis_vp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    98
			return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    99
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   100
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   101
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   102
	/* check if the given fid is the same as the exported node */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   103
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   104
	bzero(&exp_fid, sizeof (exp_fid));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   105
	exp_fid.fid_len = MAXFIDSZ;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   106
	error = vop_fid_pseudo(exi->exi_vp, &exp_fid);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   107
	if (error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   108
		return (error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   109
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   110
	if (EQFID(fidp, &exp_fid)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   111
		VN_HOLD(exi->exi_vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   112
		*vpp = exi->exi_vp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   113
		return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   114
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   115
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   116
	return (ENOENT);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   117
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   118
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   119
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   120
 * Create a pseudo export entry
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   121
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   122
 * This is an export entry that's created as the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   123
 * side-effect of a "real" export.  As a part of
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   124
 * a real export, the pathname to the export is
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   125
 * checked to see if all the directory components
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   126
 * are accessible via an NFSv4 client, i.e. are
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   127
 * exported.  If tree_climb() finds an unexported
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   128
 * mountpoint along the path, then it calls this
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   129
 * function to export it.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   130
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   131
 * This pseudo export differs from a real export
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   132
 * in restriction on simple. read-only access,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   133
 * and the addition of a "visible" list of directories.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   134
 * A real export may have a visible list if it is a root of
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   135
 * a file system and at least one of its subtree resides in
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   136
 * a different file system is shared.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   137
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   138
 * A visible list is per file system. It resides in the exportinfo
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   139
 * for the pseudo node (VROOT) and it could reside in a real export
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   140
 * of a VROOT node.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   141
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   142
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   143
pseudo_exportfs(vnode_t *vp, struct exp_visible *vis_head,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   144
					struct exportdata *exdata)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   145
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   146
	struct exportinfo *exi;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   147
	struct exportdata *kex;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   148
	fid_t fid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   149
	fsid_t fsid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   150
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   151
	char *pseudo;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   152
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   153
	ASSERT(RW_WRITE_HELD(&exported_lock));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   154
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   155
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   156
	 * Get the vfs id
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   157
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   158
	bzero(&fid, sizeof (fid));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   159
	fid.fid_len = MAXFIDSZ;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   160
	error = vop_fid_pseudo(vp, &fid);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   161
	if (error) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   162
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   163
		 * If VOP_FID returns ENOSPC then the fid supplied
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   164
		 * is too small.  For now we simply return EREMOTE.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   165
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   166
		if (error == ENOSPC)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   167
			error = EREMOTE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   168
		return (error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   169
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   170
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   171
	fsid = vp->v_vfsp->vfs_fsid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   172
	exi = kmem_zalloc(sizeof (*exi), KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   173
	exi->exi_fsid = fsid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   174
	exi->exi_fid = fid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   175
	exi->exi_vp = vp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   176
	VN_HOLD(exi->exi_vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   177
	exi->exi_visible = vis_head;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   178
	exi->exi_count = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   179
	exi->exi_volatile_dev = (vfssw[vp->v_vfsp->vfs_fstype].vsw_flag &
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   180
				VSW_VOLATILEDEV) ? 1 : 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   181
	mutex_init(&exi->exi_lock, NULL, MUTEX_DEFAULT, NULL);
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
	 * Build up the template fhandle
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   185
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   186
	exi->exi_fh.fh_fsid = fsid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   187
	ASSERT(exi->exi_fid.fid_len <= sizeof (exi->exi_fh.fh_xdata));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   188
	exi->exi_fh.fh_xlen = exi->exi_fid.fid_len;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   189
	bcopy(exi->exi_fid.fid_data, exi->exi_fh.fh_xdata,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   190
	    exi->exi_fid.fid_len);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   191
	exi->exi_fh.fh_len = sizeof (exi->exi_fh.fh_data);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   192
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   193
	kex = &exi->exi_export;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   194
	kex->ex_flags = EX_PSEUDO;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   195
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   196
	/* Set up a generic pathname */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   197
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   198
	pseudo = "(pseudo)";
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   199
	kex->ex_pathlen = strlen(pseudo);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   200
	kex->ex_path = kmem_alloc(kex->ex_pathlen + 1, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   201
	(void) strcpy(kex->ex_path, pseudo);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   202
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   203
	/* Transfer the secinfo data from exdata to this new pseudo node */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   204
	if (exdata)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   205
		srv_secinfo_exp2pseu(&exi->exi_export, exdata);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   206
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   207
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   208
	 * Initialize auth cache lock
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   209
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   210
	rw_init(&exi->exi_cache_lock, NULL, RW_DEFAULT, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   211
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   212
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   213
	 * Insert the new entry at the front of the export list
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   214
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   215
	export_link(exi);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   216
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   217
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   218
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   219
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   220
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   221
 * Free a list of visible directories
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   222
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   223
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   224
free_visible(struct exp_visible *head)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   225
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   226
	struct exp_visible *visp, *next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   227
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   228
	for (visp = head; visp; visp = next) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   229
		if (visp->vis_vp != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   230
			VN_RELE(visp->vis_vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   231
		next = visp->vis_next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   232
		kmem_free(visp, sizeof (*visp));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   233
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   234
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   235
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   236
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   237
 * Add a list of visible directories to a pseudo exportfs.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   238
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   239
 * When we export a new directory we need to add a new
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   240
 * path segment through the pseudofs to reach the new
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   241
 * directory. This new path is reflected in a list of
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   242
 * directories added to the "visible" list.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   243
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   244
 * Here there are two lists of visible fids: one hanging off the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   245
 * pseudo exportinfo, and the one we want to add.  It's possible
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   246
 * that the two lists share a common path segment
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   247
 * and have some common directories.  We need to combine
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   248
 * the lists so there's no duplicate entries. Where a common
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   249
 * path component is found, the vis_count field is bumped.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   250
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   251
 * When the addition is complete, the supplied list is freed.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   252
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   253
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   254
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   255
more_visible(struct exportinfo *exi, struct exp_visible *vis_head)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   256
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   257
	struct exp_visible *vp1, *vp2;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   258
	struct exp_visible *tail, *new;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   259
	int found;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   260
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   261
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   262
	 * If exportinfo doesn't already have a visible
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   263
	 * list just assign the entire supplied list.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   264
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   265
	if (exi->exi_visible == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   266
		exi->exi_visible = vis_head;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   267
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   268
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   269
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   270
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   271
	 * The outer loop traverses the supplied list.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   272
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   273
	for (vp1 = vis_head; vp1; vp1 = vp1->vis_next) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   274
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   275
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   276
		 * Given an element from the list to be added,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   277
		 * search the exportinfo visible list looking for a match.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   278
		 * If a match is found, increment the reference count.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   279
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   280
		found = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   281
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   282
		for (vp2 = exi->exi_visible; vp2; vp2 = vp2->vis_next) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   283
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   284
			tail = vp2;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   285
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   286
			if (EQFID(&vp1->vis_fid, &vp2->vis_fid)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   287
				found = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   288
				vp2->vis_count++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   289
				VN_RELE(vp1->vis_vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   290
				vp1->vis_vp = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   291
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   292
				/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   293
				 * If the visible struct we want to add
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   294
				 * (vp1) has vis_exported set to 1, then
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   295
				 * the matching visible struct we just found
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   296
				 * must also have it's vis_exported field
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   297
				 * set to 1.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   298
				 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   299
				 * For example, if /export/home was shared
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   300
				 * (and a UFS mountpoint), then "export" and
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   301
				 * "home" would each have visible structs in
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   302
				 * the root pseudo exportinfo. The vis_exported
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   303
				 * for home would be 1, and vis_exported for
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   304
				 * export would be 0.  Now, if /export was
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   305
				 * also shared, more_visible would find the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   306
				 * existing visible struct for export, and
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   307
				 * see that vis_exported was 0.  The code
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   308
				 * below will set it to 1.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   309
				 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   310
				 * vp1 is from vis list passed in (vis_head)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   311
				 * vp2 is from vis list on pseudo exportinfo
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   312
				 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   313
				if (vp1->vis_exported && !vp2->vis_exported)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   314
					vp2->vis_exported = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   315
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   316
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   317
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   318
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   319
		/* If not found - add to the end of the list */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   320
		if (! found) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   321
			new = kmem_zalloc(sizeof (*new), KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   322
			*new = *vp1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   323
			tail->vis_next = new;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   324
			new->vis_next = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   325
			vp1->vis_vp = NULL;
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
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   329
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   330
	 * Throw away the path list. vis_vp pointers in vis_head list
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   331
	 * are either VN_RELEed or reassigned, and are set to NULL.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   332
	 * There is no need to VN_RELE in free_visible for this vis_head.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   333
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   334
	free_visible(vis_head);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   335
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   336
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   337
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   338
 * Remove a list of visible directories from the pseudo exportfs.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   339
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   340
 * When we unexport a directory, we have to remove path
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   341
 * components from the visible list in the pseudo exportfs
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   342
 * entry.  The supplied visible list contains the fids of the path
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   343
 * to the unexported directory.  The visible list of the export
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   344
 * is checked against this list any matching fids have their
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   345
 * reference count decremented.  If a reference count drops to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   346
 * zero, then it means no paths now use this directory, so its
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   347
 * fid can be removed from the visible list.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   348
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   349
 * When the last path is removed, the visible list will be null.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   350
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   351
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   352
less_visible(struct exportinfo *exi, struct exp_visible *vis_head)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   353
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   354
	struct exp_visible *vp1, *vp2;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   355
	struct exp_visible *prev, *next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   356
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   357
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   358
	 * The outer loop traverses the supplied list.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   359
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   360
	for (vp1 = vis_head; vp1; vp1 = vp1->vis_next) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   361
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   362
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   363
		 * Given an element from the list to be removed,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   364
		 * search the exportinfo list looking for a match.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   365
		 * If a match is found, decrement the reference
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   366
		 * count and drop the element if the count drops
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   367
		 * to zero.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   368
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   369
		for (vp2 = exi->exi_visible, prev = NULL; vp2; vp2 = next) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   370
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   371
			next = vp2->vis_next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   372
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   373
			if (EQFID(&vp1->vis_fid, &vp2->vis_fid)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   374
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   375
				/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   376
				 * Decrement the ref count.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   377
				 * Remove the entry if it's zero.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   378
				 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   379
				if (--vp2->vis_count <= 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   380
					if (prev == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   381
						exi->exi_visible = next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   382
					else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   383
						prev->vis_next = next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   384
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   385
					VN_RELE(vp2->vis_vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   386
					kmem_free(vp2, sizeof (*vp1));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   387
				} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   388
					/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   389
					 * If we're here, then the vp2 will
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   390
					 * remain in the vis list.  If the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   391
					 * vis entry corresponds to the object
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   392
					 * being unshared, then vis_exported
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   393
					 * needs to be set to 0.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   394
					 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   395
					 * vp1 is a node from caller's list
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   396
					 * vp2 is node from exportinfo's list
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   397
					 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   398
					 * Only 1 node in the caller's list
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   399
					 * will have vis_exported set to 1,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   400
					 * and it corresponds to the obj being
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   401
					 * unshared.  It should always be the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   402
					 * last element of the caller's list.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   403
					 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   404
					if (vp1->vis_exported &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   405
					    vp2->vis_exported) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   406
						vp2->vis_exported = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   407
					}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   408
				}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   409
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   410
				break;
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
			prev = vp2;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   414
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   415
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   416
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   417
	free_visible(vis_head);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   418
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   419
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   420
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   421
 * This function checks the path to a new export to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   422
 * check whether all the pathname components are
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   423
 * exported. It works by climbing the file tree one
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   424
 * component at a time via "..", crossing mountpoints
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   425
 * if necessary until an export entry is found, or the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   426
 * system root is reached.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   427
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   428
 * If an unexported mountpoint is found, then
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   429
 * a new pseudo export is added and the pathname from
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   430
 * the mountpoint down to the export is added to the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   431
 * visible list for the new pseudo export.  If an existing
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   432
 * pseudo export is found, then the pathname is added
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   433
 * to its visible list.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   434
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   435
 * Note that there's some tests for exportdir.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   436
 * The exportinfo entry that's passed as a parameter
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   437
 * is that of the real export and exportdir is set
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   438
 * for this case.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   439
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   440
 * Here is an example of a possible setup:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   441
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   442
 * () - a new fs; fs mount point
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   443
 * EXPORT - a real exported node
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   444
 * PSEUDO - a pseudo node
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   445
 * vis - visible list
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   446
 * f# - security flavor#
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   447
 * (f#) - security flavor# propagated from its decendents
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   448
 * "" - covered vnode
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   449
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   450
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   451
 *                 /
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   452
 *                 |
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   453
 *                 (a) PSEUDO (f1,f2)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   454
 *                 |   vis: b,b,"c","n"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   455
 *                 |
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   456
 *                 b
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   457
 *        ---------|------------------
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   458
 *        |                          |
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   459
 *        (c) EXPORT,f1(f2)          (n) PSEUDO (f1,f2)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   460
 *        |   vis: "e","d"           |   vis: m,m,,p,q,"o"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   461
 *        |                          |
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
 *  (d)      (e)      f         m EXPORT,f1(f2)    p
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   465
 *  EXPORT   EXPORT             |                  |
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   466
 *  f1       f2                 |                  |
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   467
 *           |                  |                  |
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   468
 *           j                 (o) EXPORT,f2       q EXPORT f2
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
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   472
treeclimb_export(struct exportinfo *exip)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   473
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   474
	vnode_t *dvp, *vp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   475
	fid_t fid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   476
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   477
	int exportdir;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   478
	struct exportinfo *exi = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   479
	struct exp_visible *visp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   480
	struct exp_visible *vis_head = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   481
	struct vattr va;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   482
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   483
	ASSERT(RW_WRITE_HELD(&exported_lock));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   484
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   485
	vp = exip->exi_vp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   486
	VN_HOLD(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   487
	exportdir = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   488
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   489
	for (;;) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   490
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   491
		bzero(&fid, sizeof (fid));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   492
		fid.fid_len = MAXFIDSZ;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   493
		error = vop_fid_pseudo(vp, &fid);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   494
		if (error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   495
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   496
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   497
		if (! exportdir) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   498
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   499
			 * Check if this exportroot is a VROOT dir.  If so,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   500
			 * then attach the pseudonodes.  If not, then
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   501
			 * continue .. traversal until we hit a VROOT
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   502
			 * export (pseudo or real).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   503
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   504
			exi = checkexport4(&vp->v_vfsp->vfs_fsid, &fid, vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   505
			if (exi != NULL && vp->v_flag & VROOT) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   506
				/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   507
				 * Found an export info
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   508
				 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   509
				 * Extend the list of visible
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   510
				 * directories whether it's a pseudo
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   511
				 * or a real export.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   512
				 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   513
				more_visible(exi, vis_head);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   514
				vis_head = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   515
				break;	/* and climb no further */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   516
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   517
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   518
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   519
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   520
		 * If at the root of the filesystem, need
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   521
		 * to traverse across the mountpoint
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   522
		 * and continue the climb on the mounted-on
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   523
		 * filesystem.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   524
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   525
		if (vp->v_flag & VROOT) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   526
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   527
			if (! exportdir) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   528
				/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   529
				 * Found the root directory of a filesystem
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   530
				 * that isn't exported.  Need to export
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   531
				 * this as a pseudo export so that an NFS v4
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   532
				 * client can do lookups in it.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   533
				 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   534
				error = pseudo_exportfs(vp, vis_head, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   535
				if (error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   536
					break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   537
				vis_head = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   538
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   539
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   540
			if (VN_CMP(vp, rootdir)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   541
				/* at system root */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   542
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   543
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   544
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   545
			vp = untraverse(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   546
			exportdir = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   547
			continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   548
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   549
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   550
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   551
		 * Do a getattr to obtain the nodeid (inode num)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   552
		 * for this vnode.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   553
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   554
		va.va_mask = AT_NODEID;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   555
		error = VOP_GETATTR(vp, &va, 0, CRED());
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   556
		if (error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   557
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   558
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   559
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   560
		 *  Add this directory fid to visible list
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   561
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   562
		visp = kmem_alloc(sizeof (*visp), KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   563
		VN_HOLD(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   564
		visp->vis_vp = vp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   565
		visp->vis_fid = fid;		/* structure copy */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   566
		visp->vis_ino = va.va_nodeid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   567
		visp->vis_count = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   568
		visp->vis_exported = exportdir;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   569
		visp->vis_next = vis_head;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   570
		vis_head = visp;
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
		 * Now, do a ".." to find parent dir of vp.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   574
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   575
		error = VOP_LOOKUP(vp, "..", &dvp, NULL, 0, NULL, CRED());
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   576
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   577
		if (error == ENOTDIR && exportdir) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   578
			dvp = exip->exi_dvp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   579
			ASSERT(dvp != NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   580
			VN_HOLD(dvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   581
			error = 0;
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
		if (error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   585
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   586
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   587
		exportdir = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   588
		VN_RELE(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   589
		vp = dvp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   590
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   591
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   592
	VN_RELE(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   593
	return (error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   594
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   595
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   596
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   597
 * Walk up the tree looking for pseudo export entries.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   598
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   599
 * If a pseudo export is found, remove the path we've
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   600
 * climbed from its visible list. If the visible list
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   601
 * still has entries after the removal, then we can stop.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   602
 * If it becomes null, then remove the pseudo export entry
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   603
 * and carry on up the tree to see if there's any more.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   604
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   605
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   606
treeclimb_unexport(struct exportinfo *exip)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   607
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   608
	vnode_t *dvp, *vp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   609
	fid_t fid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   610
	int error = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   611
	int exportdir;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   612
	struct exportinfo *exi = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   613
	struct exp_visible *vis_head = NULL, *visp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   614
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   615
	ASSERT(RW_WRITE_HELD(&exported_lock));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   616
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   617
	exportdir = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   618
	vp = exip->exi_vp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   619
	VN_HOLD(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   620
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   621
	for (;;) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   622
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   623
		bzero(&fid, sizeof (fid));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   624
		fid.fid_len = MAXFIDSZ;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   625
		error = vop_fid_pseudo(vp, &fid);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   626
		if (error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   627
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   628
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   629
		if (! exportdir) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   630
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   631
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   632
			 * We need to use checkexport4() here because it
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   633
			 * doesn't acquire exported_lock and it doesn't
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   634
			 * manipulate exi_count.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   635
			 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   636
			 * Remove directories from the visible
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   637
			 * list that are unique to the path
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   638
			 * for this export.  (Only VROOT exportinfos
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   639
			 * have can have visible entries).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   640
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   641
			exi = checkexport4(&vp->v_vfsp->vfs_fsid, &fid, vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   642
			if (exi != NULL && (vp->v_flag & VROOT)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   643
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   644
				less_visible(exi, vis_head);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   645
				vis_head = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   646
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   647
				/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   648
				 * If the visible list has entries
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   649
				 * or if it's a real export, then
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   650
				 * there's no need to keep climbing.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   651
				 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   652
				if (exi->exi_visible || ! PSEUDO(exi))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   653
					break;
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
				 * Otherwise, we have a pseudo export
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   657
				 * with an empty list (no exports below
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   658
				 * it) so we must remove and continue
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   659
				 * the climb to remove its name from
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   660
				 * the parent export.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   661
				 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   662
				error = export_unlink(&vp->v_vfsp->vfs_fsid,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   663
						&fid, vp, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   664
				if (error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   665
					break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   666
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   667
				exi_rele(exi);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   668
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   669
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   670
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   671
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   672
		 * If at the root of the filesystem, need
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   673
		 * to traverse across the mountpoint
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   674
		 * and continue the climb on the mounted-on
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   675
		 * filesystem.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   676
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   677
		if (vp->v_flag & VROOT) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   678
			if (VN_CMP(vp, rootdir)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   679
				/* at system root */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   680
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   681
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   682
			vp = untraverse(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   683
			exportdir = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   684
			continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   685
		}
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
		 *  Add this directory fid to path list
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   689
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   690
		visp = kmem_alloc(sizeof (*visp), KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   691
		VN_HOLD(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   692
		visp->vis_vp = vp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   693
		visp->vis_fid = fid;		/* structure copy */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   694
		visp->vis_ino = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   695
		visp->vis_count = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   696
		visp->vis_exported = exportdir;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   697
		visp->vis_next = vis_head;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   698
		vis_head = visp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   699
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   700
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   701
		 * Do a ".." to find parent dir of vp.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   702
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   703
		error = VOP_LOOKUP(vp, "..", &dvp, NULL, 0, NULL, CRED());
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   704
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   705
		if (error == ENOTDIR && exportdir) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   706
			dvp = exip->exi_dvp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   707
			ASSERT(dvp != NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   708
			VN_HOLD(dvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   709
			error = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   710
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   711
		if (error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   712
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   713
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   714
		exportdir = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   715
		VN_RELE(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   716
		vp = dvp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   717
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   718
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   719
	VN_RELE(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   720
	return (error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   721
}
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
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   725
 * Traverse backward across mountpoint from the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   726
 * root vnode of a filesystem to its mounted-on
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   727
 * vnode.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   728
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   729
vnode_t *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   730
untraverse(vnode_t *vp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   731
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   732
	vnode_t *tvp, *nextvp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   733
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   734
	tvp = vp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   735
	for (;;) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   736
		if (! (tvp->v_flag & VROOT))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   737
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   738
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   739
		/* lock vfs to prevent unmount of this vfs */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   740
		vfs_lock_wait(tvp->v_vfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   741
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   742
		if ((nextvp = tvp->v_vfsp->vfs_vnodecovered) == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   743
			vfs_unlock(tvp->v_vfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   744
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   745
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   746
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   747
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   748
		 * Hold nextvp to prevent unmount.  After unlock vfs and
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   749
		 * rele tvp, any number of overlays could be unmounted.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   750
		 * Putting a hold on vfs_vnodecovered will only allow
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   751
		 * tvp's vfs to be unmounted. Of course if caller placed
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   752
		 * extra hold on vp before calling untraverse, the following
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   753
		 * hold would not be needed.  Since prev actions of caller
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   754
		 * are unknown, we need to hold here just to be safe.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   755
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   756
		VN_HOLD(nextvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   757
		vfs_unlock(tvp->v_vfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   758
		VN_RELE(tvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   759
		tvp = nextvp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   760
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   761
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   762
	return (tvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   763
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   764
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   765
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   766
 * Given an exportinfo, climb up to find the exportinfo for the VROOT
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   767
 * of the filesystem.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   768
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   769
 * e.g.         /
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   770
 *              |
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   771
 *              a (VROOT) pseudo-exportinfo
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   772
 *		|
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   773
 *		b
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   774
 *		|
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   775
 *		c  #share /a/b/c
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   776
 *		|
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   777
 *		d
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   778
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   779
 * where c is in the same filesystem as a.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   780
 * So, get_root_export(*exportinfo_for_c) returns exportinfo_for_a
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   781
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   782
 * If d is shared, then c will be put into a's visible list.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   783
 * Note: visible list is per filesystem and is attached to the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   784
 * VROOT exportinfo.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   785
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   786
struct exportinfo *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   787
get_root_export(struct exportinfo *exip)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   788
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   789
	vnode_t *dvp, *vp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   790
	fid_t fid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   791
	struct exportinfo *exi = exip;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   792
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   793
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   794
	vp = exi->exi_vp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   795
	VN_HOLD(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   796
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   797
	for (;;) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   798
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   799
		if (vp->v_flag & VROOT) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   800
			ASSERT(exi != NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   801
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   802
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   803
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   804
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   805
		 * Now, do a ".." to find parent dir of vp.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   806
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   807
		error = VOP_LOOKUP(vp, "..", &dvp, NULL, 0, NULL, CRED());
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   808
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   809
		if (error) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   810
			exi = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   811
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   812
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   813
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   814
		VN_RELE(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   815
		vp = dvp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   816
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   817
		bzero(&fid, sizeof (fid));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   818
		fid.fid_len = MAXFIDSZ;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   819
		error = vop_fid_pseudo(vp, &fid);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   820
		if (error) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   821
			exi = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   822
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   823
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   824
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   825
		exi = checkexport4(&vp->v_vfsp->vfs_fsid, &fid, vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   826
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   827
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   828
	VN_RELE(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   829
	return (exi);
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
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   833
 * Return true if the supplied vnode has a sub-directory exported.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   834
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   835
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   836
has_visible(struct exportinfo *exi, vnode_t *vp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   837
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   838
	struct exp_visible *visp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   839
	fid_t fid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   840
	bool_t vp_is_exported;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   841
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   842
	vp_is_exported = VN_CMP(vp,  exi->exi_vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   843
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   844
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   845
	 * An exported root vnode has a sub-dir shared if it has a visible list.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   846
	 * i.e. if it does not have a visible list, then there is no node in
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   847
	 * this filesystem leads to any other shared node.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   848
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   849
	if (vp_is_exported && (vp->v_flag & VROOT))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   850
		return (exi->exi_visible ? 1 : 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   851
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   852
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   853
	 * Only the exportinfo of a fs root node may have a visible list.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   854
	 * Either it is a pseudo root node, or a real exported root node.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   855
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   856
	if ((exi = get_root_export(exi)) == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   857
		return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   858
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   859
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   860
	if (!exi->exi_visible)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   861
		return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   862
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   863
	/* Get the fid of the vnode */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   864
	bzero(&fid, sizeof (fid));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   865
	fid.fid_len = MAXFIDSZ;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   866
	if (vop_fid_pseudo(vp, &fid) != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   867
		return (0);
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
	 * See if vp is in the visible list of the root node exportinfo.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   872
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   873
	for (visp = exi->exi_visible; visp; visp = visp->vis_next) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   874
		if (EQFID(&fid, &visp->vis_fid)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   875
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   876
			 * If vp is an exported non-root node with only 1 path
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   877
			 * count (for itself), it indicates no sub-dir shared
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   878
			 * using this vp as a path.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   879
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   880
			if (vp_is_exported && visp->vis_count < 2)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   881
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   882
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   883
			return (1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   884
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   885
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   886
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   887
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   888
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   889
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   890
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   891
 * Returns true if the supplied vnode is visible
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   892
 * in this export.  If vnode is visible, return
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   893
 * vis_exported in expseudo.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   894
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   895
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   896
nfs_visible(struct exportinfo *exi, vnode_t *vp, int *expseudo)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   897
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   898
	struct exp_visible *visp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   899
	fid_t fid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   900
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   901
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   902
	 * First check to see if vp is export root.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   903
	 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   904
	 * A pseudo export root can never be exported
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   905
	 * (it would be a real export then); however,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   906
	 * it is always visible.  If a pseudo root object
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   907
	 * was exported by server admin, then the entire
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   908
	 * pseudo exportinfo (and all visible entries) would
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   909
	 * be destroyed.  A pseudo exportinfo only exists
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   910
	 * to provide access to real (descendant) export(s).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   911
	 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   912
	 * Previously, rootdir was special cased here; however,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   913
	 * the export root special case handles the rootdir
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   914
	 * case also.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   915
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   916
	if (VN_CMP(vp, exi->exi_vp)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   917
		*expseudo = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   918
		return (1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   919
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   920
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   921
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   922
	 * Only a PSEUDO node has a visible list or an exported VROOT
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   923
	 * node may have a visible list.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   924
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   925
	if (! PSEUDO(exi) && (exi = get_root_export(exi)) == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   926
		*expseudo = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   927
		return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   928
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   929
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   930
	/* Get the fid of the vnode */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   931
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   932
	bzero(&fid, sizeof (fid));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   933
	fid.fid_len = MAXFIDSZ;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   934
	if (vop_fid_pseudo(vp, &fid) != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   935
		*expseudo = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   936
		return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   937
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   938
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   939
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   940
	 * We can't trust VN_CMP() above because of LOFS.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   941
	 * Even though VOP_CMP will do the right thing for LOFS
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   942
	 * objects, VN_CMP will short circuit out early when the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   943
	 * vnode ops ptrs are different.  Just in case we're dealing
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   944
	 * with LOFS, compare exi_fid/fsid here.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   945
	 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   946
	 * expseudo is not set because this is not an export
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   947
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   948
	if (EQFID(&exi->exi_fid, &fid) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   949
	    EQFSID(&exi->exi_fsid, &vp->v_vfsp->vfs_fsid)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   950
		*expseudo = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   951
		return (1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   952
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   953
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   954
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   955
	/* See if it matches any fid in the visible list */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   956
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   957
	for (visp = exi->exi_visible; visp; visp = visp->vis_next) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   958
		if (EQFID(&fid, &visp->vis_fid)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   959
			*expseudo = visp->vis_exported;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   960
			return (1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   961
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   962
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   963
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   964
	*expseudo = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   965
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   966
	return (0);
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
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   970
 * Returns true if the supplied vnode is the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   971
 * directory of an export point.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   972
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   973
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   974
nfs_exported(struct exportinfo *exi, vnode_t *vp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   975
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   976
	struct exp_visible *visp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   977
	fid_t fid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   978
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   979
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   980
	 * First check to see if vp is the export root
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   981
	 * This check required for the case of lookup ..
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   982
	 * where .. is a V_ROOT vnode and a pseudo exportroot.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   983
	 * Pseudo export root objects do not have an entry
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   984
	 * in the visible list even though every V_ROOT
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   985
	 * pseudonode is visible.  It is safe to compare
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   986
	 * vp here because pseudo_exportfs put a hold on
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   987
	 * it when exi_vp was initialized.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   988
	 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   989
	 * Note: VN_CMP() won't match for LOFS shares, but they're
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   990
	 * handled below w/EQFID/EQFSID.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   991
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   992
	if (VN_CMP(vp, exi->exi_vp))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   993
		return (1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   994
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   995
	/* Get the fid of the vnode */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   996
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   997
	bzero(&fid, sizeof (fid));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   998
	fid.fid_len = MAXFIDSZ;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   999
	if (vop_fid_pseudo(vp, &fid) != 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1000
		return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1001
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1002
	if (EQFID(&fid, &exi->exi_fid) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1003
	    EQFSID(&vp->v_vfsp->vfs_fsid, &exi->exi_fsid)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1004
		return (1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1005
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1006
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1007
	/* See if it matches any fid in the visible list */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1008
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1009
	for (visp = exi->exi_visible; visp; visp = visp->vis_next) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1010
		if (EQFID(&fid, &visp->vis_fid))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1011
			return (visp->vis_exported);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1012
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1013
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1014
	return (0);
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
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1018
 * Returns true if the supplied inode is visible
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1019
 * in this export.  This function is used by
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1020
 * readdir which uses inode numbers from the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1021
 * directory.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1022
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1023
 * NOTE: this code does not match inode number for ".",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1024
 * but it isn't required because NFS4 server rddir
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1025
 * skips . and .. entries.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1026
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1027
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1028
nfs_visible_inode(struct exportinfo *exi, ino64_t ino, int *expseudo)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1029
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1030
	struct exp_visible *visp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1031
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1032
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1033
	 * Only a PSEUDO node has a visible list or an exported VROOT
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1034
	 * node may have a visible list.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1035
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1036
	if (! PSEUDO(exi) && (exi = get_root_export(exi)) == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1037
		*expseudo = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1038
		return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1039
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1040
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1041
	for (visp = exi->exi_visible; visp; visp = visp->vis_next)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1042
		if ((u_longlong_t)ino == visp->vis_ino) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1043
			*expseudo = visp->vis_exported;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1044
			return (1);
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
	*expseudo = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1048
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1049
}