usr/src/uts/common/fs/autofs/auto_vfsops.c
author Casper H.S. Dik <Casper.Dik@Sun.COM>
Wed, 28 Apr 2010 10:01:37 +0200
changeset 12273 63678502e95e
parent 11185 f0c31008e395
child 12633 9f2cda0ed938
permissions -rw-r--r--
PSARC 2009/377 In-kernel pfexec implementation. PSARC 2009/378 Basic File Privileges PSARC 2010/072 RBAC update: user attrs from profiles 4912090 pfzsh(1) should exist 4912093 pfbash(1) should exist 4912096 pftcsh(1) should exist 6440298 Expand the basic privilege set in order to restrict file access 6859862 Move pfexec into the kernel 6919171 cred_t sidesteps kmem_debug; we need to be able to detect bad hold/free when they occur 6923721 The new SYS_SMB privilege is not backward compatible 6937562 autofs doesn't remove its door when the zone shuts down 6937727 Zones stuck on deathrow; netstack_zone keeps a credential reference to the zone 6940159 Implement PSARC 2010/072
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
1488
196daa2cf3db PSARC/2006/034 fsstat
rsb
parents: 0
diff changeset
     5
 * Common Development and Distribution License (the "License").
196daa2cf3db PSARC/2006/034 fsstat
rsb
parents: 0
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
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    21
/*
12273
63678502e95e PSARC 2009/377 In-kernel pfexec implementation.
Casper H.S. Dik <Casper.Dik@Sun.COM>
parents: 11185
diff changeset
    22
 * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved.
0
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
#include <sys/param.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    26
#include <sys/errno.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    27
#include <sys/proc.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    28
#include <sys/disp.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    29
#include <sys/vfs.h>
3898
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 2516
diff changeset
    30
#include <sys/vfs_opreg.h>
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    31
#include <sys/vnode.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    32
#include <sys/uio.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    33
#include <sys/kmem.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    34
#include <sys/cred.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    35
#include <sys/statvfs.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    36
#include <sys/mount.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    37
#include <sys/tiuser.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    38
#include <sys/cmn_err.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    39
#include <sys/debug.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    40
#include <sys/systm.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    41
#include <sys/sysmacros.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    42
#include <sys/pathname.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    43
#include <rpc/types.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    44
#include <rpc/auth.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    45
#include <rpc/clnt.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    46
#include <fs/fs_subr.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    47
#include <sys/fs/autofs.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    48
#include <sys/modctl.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    49
#include <sys/mntent.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    50
#include <sys/policy.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    51
#include <sys/zone.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    52
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    53
static int autofs_init(int, char *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    54
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    55
static major_t autofs_major;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    56
static minor_t autofs_minor;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    57
4092
c859d126a342 6513455 automounter is not responding to interrupts correctly
evanl
parents: 3898
diff changeset
    58
kmutex_t autofs_minor_lock;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    59
zone_key_t autofs_key;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    60
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    61
static mntopts_t auto_mntopts;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    62
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    63
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    64
 * The AUTOFS system call.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    65
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    66
static struct sysent autofssysent = {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    67
	2,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    68
	SE_32RVAL1 | SE_ARGC | SE_NOUNLOAD,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    69
	autofssys
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    70
};
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    71
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    72
static struct modlsys modlsys = {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    73
	&mod_syscallops,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    74
	"AUTOFS syscall",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    75
	&autofssysent
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
#ifdef	_SYSCALL32_IMPL
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    79
static struct modlsys  modlsys32 = {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    80
	&mod_syscallops32,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    81
	"AUTOFS syscall (32-bit)",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    82
	&autofssysent
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    83
};
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    84
#endif	/* _SYSCALL32_IMPL */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    85
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    86
static vfsdef_t vfw = {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    87
	VFSDEF_VERSION,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    88
	"autofs",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    89
	autofs_init,
1488
196daa2cf3db PSARC/2006/034 fsstat
rsb
parents: 0
diff changeset
    90
	VSW_HASPROTO|VSW_CANRWRO|VSW_CANREMOUNT|VSW_STATS,
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    91
	&auto_mntopts
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    92
};
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    93
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    94
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    95
 * Module linkage information for the kernel.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    96
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    97
static struct modlfs modlfs = {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    98
	&mod_fsops, "filesystem for autofs", &vfw
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
static struct modlinkage modlinkage = {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   102
	MODREV_1,
2516
391407c3e041 6452979 Single panic "assertion failed: fngp->fng_fnnode_count == 1" on Sun-Blade-1000 BrandZ snv_43r2
evanl
parents: 2170
diff changeset
   103
	&modlfs,
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   104
	&modlsys,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   105
#ifdef	_SYSCALL32_IMPL
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   106
	&modlsys32,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   107
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   108
	NULL
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   109
};
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   110
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   111
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   112
 * There are not enough stubs for rpcmod so we must force load it
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   113
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   114
char _depends_on[] = "strmod/rpcmod misc/rpcsec fs/mntfs";
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   115
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   116
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   117
 * This is the module initialization routine.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   118
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   119
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   120
_init(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   121
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   122
	return (mod_install(&modlinkage));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   123
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   124
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   125
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   126
_fini(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   127
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   128
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   129
	 * Don't allow the autofs module to be unloaded for now.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   130
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   131
	return (EBUSY);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   132
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   133
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   134
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   135
_info(struct modinfo *modinfop)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   136
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   137
	return (mod_info(&modlinkage, modinfop));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   138
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   139
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   140
static int autofs_fstype;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   141
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   142
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   143
 * autofs VFS operations
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   144
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   145
static int auto_mount(vfs_t *, vnode_t *, struct mounta *, cred_t *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   146
static int auto_unmount(vfs_t *, int, cred_t *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   147
static int auto_root(vfs_t *, vnode_t **);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   148
static int auto_statvfs(vfs_t *, struct statvfs64 *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   149
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   150
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   151
 * Auto Mount options table
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   152
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   153
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   154
static char *direct_cancel[] = { MNTOPT_INDIRECT, NULL };
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   155
static char *indirect_cancel[] = { MNTOPT_DIRECT, NULL };
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   156
static char *browse_cancel[] = { MNTOPT_NOBROWSE, NULL };
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   157
static char *nobrowse_cancel[] = { MNTOPT_BROWSE, NULL };
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   158
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   159
static mntopt_t mntopts[] = {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   160
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   161
 *	option name		cancel options	default arg	flags
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   162
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   163
	{ MNTOPT_DIRECT,	direct_cancel,	NULL,		0,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   164
		NULL },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   165
	{ MNTOPT_INDIRECT,	indirect_cancel, NULL,		0,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   166
		NULL },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   167
	{ MNTOPT_IGNORE,	NULL,		NULL,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   168
		MO_DEFAULT|MO_TAG,	NULL },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   169
	{ "nest",		NULL,		NULL,		MO_TAG,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   170
		NULL },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   171
	{ MNTOPT_BROWSE,	browse_cancel,	NULL,		MO_TAG,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   172
		NULL },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   173
	{ MNTOPT_NOBROWSE,	nobrowse_cancel, NULL,		MO_TAG,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   174
		NULL },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   175
	{ MNTOPT_RESTRICT,	NULL,		NULL,		MO_TAG,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   176
		NULL },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   177
};
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   178
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   179
static mntopts_t auto_mntopts = {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   180
	sizeof (mntopts) / sizeof (mntopt_t),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   181
	mntopts
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
/*ARGSUSED*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   185
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   186
autofs_zone_destructor(zoneid_t zoneid, void *arg)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   187
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   188
	struct autofs_globals *fngp = arg;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   189
	vnode_t *vp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   190
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   191
	if (fngp == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   192
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   193
	ASSERT(fngp->fng_fnnode_count == 1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   194
	ASSERT(fngp->fng_unmount_threads == 0);
12273
63678502e95e PSARC 2009/377 In-kernel pfexec implementation.
Casper H.S. Dik <Casper.Dik@Sun.COM>
parents: 11185
diff changeset
   195
63678502e95e PSARC 2009/377 In-kernel pfexec implementation.
Casper H.S. Dik <Casper.Dik@Sun.COM>
parents: 11185
diff changeset
   196
	if (fngp->fng_autofs_daemon_dh != NULL)
63678502e95e PSARC 2009/377 In-kernel pfexec implementation.
Casper H.S. Dik <Casper.Dik@Sun.COM>
parents: 11185
diff changeset
   197
		door_ki_rele(fngp->fng_autofs_daemon_dh);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   198
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   199
	 * vn_alloc() initialized the rootnode with a count of 1; we need to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   200
	 * make this 0 to placate auto_freefnnode().
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   201
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   202
	vp = fntovn(fngp->fng_rootfnnodep);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   203
	ASSERT(vp->v_count == 1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   204
	vp->v_count--;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   205
	auto_freefnnode(fngp->fng_rootfnnodep);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   206
	mutex_destroy(&fngp->fng_unmount_threads_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   207
	kmem_free(fngp, sizeof (*fngp));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   208
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   209
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   210
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   211
 * rootfnnodep is allocated here.  Its sole purpose is to provide
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   212
 * read/write locking for top level fnnodes.  This object is
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   213
 * persistent and will not be deallocated until the zone is destroyed.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   214
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   215
 * The current zone is implied as the zone of interest, since we will be
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   216
 * calling zthread_create() which must be called from the correct zone.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   217
 */
2170
eb691d2a219e PSARC 2005/714 Automounter Scalability Enhancements
evanl
parents: 1676
diff changeset
   218
struct autofs_globals *
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   219
autofs_zone_init(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   220
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   221
	char rootname[sizeof ("root_fnnode_zone_") + ZONEID_WIDTH];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   222
	struct autofs_globals *fngp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   223
	zoneid_t zoneid = getzoneid();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   224
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   225
	fngp = kmem_zalloc(sizeof (*fngp), KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   226
	(void) snprintf(rootname, sizeof (rootname), "root_fnnode_zone_%d",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   227
	    zoneid);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   228
	fngp->fng_rootfnnodep = auto_makefnnode(VNON, NULL, rootname, CRED(),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   229
	    fngp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   230
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   231
	 * Don't need to hold fng_rootfnnodep as it's never really used for
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   232
	 * anything.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   233
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   234
	fngp->fng_fnnode_count = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   235
	fngp->fng_printed_not_running_msg = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   236
	fngp->fng_zoneid = zoneid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   237
	mutex_init(&fngp->fng_unmount_threads_lock, NULL, MUTEX_DEFAULT,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   238
	    NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   239
	fngp->fng_unmount_threads = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   240
2170
eb691d2a219e PSARC 2005/714 Automounter Scalability Enhancements
evanl
parents: 1676
diff changeset
   241
	mutex_init(&fngp->fng_autofs_daemon_lock, NULL, MUTEX_DEFAULT, NULL);
eb691d2a219e PSARC 2005/714 Automounter Scalability Enhancements
evanl
parents: 1676
diff changeset
   242
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   243
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   244
	 * Start the unmounter thread for this zone.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   245
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   246
	(void) zthread_create(NULL, 0, auto_do_unmount, fngp, 0, minclsyspri);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   247
	return (fngp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   248
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   249
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   250
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   251
autofs_init(int fstype, char *name)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   252
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   253
	static const fs_operation_def_t auto_vfsops_template[] = {
3898
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 2516
diff changeset
   254
		VFSNAME_MOUNT,		{ .vfs_mount = auto_mount },
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 2516
diff changeset
   255
		VFSNAME_UNMOUNT,	{ .vfs_unmount = auto_unmount },
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 2516
diff changeset
   256
		VFSNAME_ROOT,		{ .vfs_root = auto_root },
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 2516
diff changeset
   257
		VFSNAME_STATVFS,	{ .vfs_statvfs = auto_statvfs },
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 2516
diff changeset
   258
		NULL,			NULL
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   259
	};
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   260
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   261
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   262
	autofs_fstype = fstype;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   263
	ASSERT(autofs_fstype != 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   264
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   265
	 * Associate VFS ops vector with this fstype
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   266
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   267
	error = vfs_setfsops(fstype, auto_vfsops_template, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   268
	if (error != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   269
		cmn_err(CE_WARN, "autofs_init: bad vfs ops template");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   270
		return (error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   271
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   272
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   273
	error = vn_make_ops(name, auto_vnodeops_template, &auto_vnodeops);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   274
	if (error != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   275
		(void) vfs_freevfsops_by_type(fstype);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   276
		cmn_err(CE_WARN, "autofs_init: bad vnode ops template");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   277
		return (error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   278
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   279
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   280
	mutex_init(&autofs_minor_lock, NULL, MUTEX_DEFAULT, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   281
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   282
	 * Assign unique major number for all autofs mounts
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   283
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   284
	if ((autofs_major = getudev()) == (major_t)-1) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   285
		cmn_err(CE_WARN,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   286
		    "autofs: autofs_init: can't get unique device number");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   287
		mutex_destroy(&autofs_minor_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   288
		return (1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   289
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   290
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   291
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   292
	 * We'd like to be able to provide a constructor here, but we can't
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   293
	 * since it wants to zthread_create(), something it can't do in a ZSD
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   294
	 * constructor.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   295
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   296
	zone_key_create(&autofs_key, NULL, NULL, autofs_zone_destructor);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   297
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   298
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   299
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   300
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   301
static char *restropts[] = {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   302
	RESTRICTED_MNTOPTS
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   303
};
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   304
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   305
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   306
 * This routine adds those options to the option string `buf' which are
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   307
 * forced by secpolicy_fs_mount.  If the automatic "security" options
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   308
 * are set, the option string gets them added if they aren't already
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   309
 * there.  We search the string with "strstr" and make sure that
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   310
 * the string we find is bracketed with <start|",">MNTOPT<","|"\0">
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   311
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   312
 * This is one half of the option inheritence algorithm which
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   313
 * implements the "restrict" option.  The other half is implemented
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   314
 * in automountd; it takes its cue from the options we add here.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   315
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   316
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   317
autofs_restrict_opts(struct vfs *vfsp, char *buf, size_t maxlen, size_t *curlen)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   318
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   319
	int i;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   320
	char *p;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   321
	size_t len = *curlen - 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   322
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   323
	/* Unrestricted */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   324
	if (!vfs_optionisset(vfsp, restropts[0], NULL))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   325
		return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   326
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   327
	for (i = 0; i < sizeof (restropts)/sizeof (restropts[0]); i++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   328
		size_t olen = strlen(restropts[i]);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   329
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   330
		/* Add "restrict" always and the others insofar set */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   331
		if ((i == 0 || vfs_optionisset(vfsp, restropts[i], NULL)) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   332
		    ((p = strstr(buf, restropts[i])) == NULL ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   333
		    !((p == buf || p[-1] == ',') &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   334
		    (p[olen] == '\0' || p[olen] == ',')))) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   335
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   336
			if (len + olen + 1 > maxlen)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   337
				return (-1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   338
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   339
			if (*buf != '\0')
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   340
				buf[len++] = ',';
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   341
			(void) strcpy(&buf[len], restropts[i]);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   342
			len += olen;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   343
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   344
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   345
	*curlen = len + 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   346
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   347
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   348
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   349
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   350
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   351
auto_mount(vfs_t *vfsp, vnode_t *vp, struct mounta *uap, cred_t *cr)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   352
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   353
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   354
	size_t len = 0;
2170
eb691d2a219e PSARC 2005/714 Automounter Scalability Enhancements
evanl
parents: 1676
diff changeset
   355
	autofs_args args;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   356
	fninfo_t *fnip = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   357
	vnode_t *rootvp = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   358
	fnnode_t *rootfnp = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   359
	char *data = uap->dataptr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   360
	char datalen = uap->datalen;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   361
	dev_t autofs_dev;
2170
eb691d2a219e PSARC 2005/714 Automounter Scalability Enhancements
evanl
parents: 1676
diff changeset
   362
	char strbuff[MAXPATHLEN + 1];
11185
f0c31008e395 6887924 PP_ISKAS needs to be defined in terms of VN_ISKAS for vnodes
Sean McEnroe <Sean.McEnroe@Sun.COM>
parents: 4092
diff changeset
   363
	vnode_t *kkvp;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   364
	struct autofs_globals *fngp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   365
	zone_t *zone = curproc->p_zone;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   366
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   367
	AUTOFS_DPRINT((4, "auto_mount: vfs %p vp %p\n", (void *)vfsp,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   368
	    (void *)vp));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   369
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   370
	if ((error = secpolicy_fs_mount(cr, vp, vfsp)) != 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   371
		return (EPERM);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   372
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   373
	if (zone == global_zone) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   374
		zone_t *mntzone;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   375
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   376
		mntzone = zone_find_by_path(refstr_value(vfsp->vfs_mntpt));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   377
		ASSERT(mntzone != NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   378
		zone_rele(mntzone);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   379
		if (mntzone != zone) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   380
			return (EBUSY);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   381
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   382
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   383
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   384
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   385
	 * Stop the mount from going any further if the zone is going away.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   386
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   387
	if (zone_status_get(zone) >= ZONE_IS_SHUTTING_DOWN)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   388
		return (EBUSY);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   389
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   390
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   391
	 * We need a lock to serialize this; minor_lock is as good as any.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   392
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   393
	mutex_enter(&autofs_minor_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   394
	if ((fngp = zone_getspecific(autofs_key, zone)) == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   395
		fngp = autofs_zone_init();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   396
		(void) zone_setspecific(autofs_key, zone, fngp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   397
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   398
	mutex_exit(&autofs_minor_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   399
	ASSERT(fngp != NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   400
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   401
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   402
	 * Get arguments
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   403
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   404
	if (uap->flags & MS_SYSSPACE) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   405
		if (datalen != sizeof (args))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   406
			return (EINVAL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   407
		error = kcopy(data, &args, sizeof (args));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   408
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   409
		if (get_udatamodel() == DATAMODEL_NATIVE) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   410
			if (datalen != sizeof (args))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   411
				return (EINVAL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   412
			error = copyin(data, &args, sizeof (args));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   413
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   414
			struct autofs_args32 args32;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   415
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   416
			if (datalen != sizeof (args32))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   417
				return (EINVAL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   418
			error = copyin(data, &args32, sizeof (args32));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   419
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   420
			args.addr.maxlen = args32.addr.maxlen;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   421
			args.addr.len = args32.addr.len;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   422
			args.addr.buf = (char *)(uintptr_t)args32.addr.buf;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   423
			args.path = (char *)(uintptr_t)args32.path;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   424
			args.opts = (char *)(uintptr_t)args32.opts;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   425
			args.map = (char *)(uintptr_t)args32.map;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   426
			args.subdir = (char *)(uintptr_t)args32.subdir;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   427
			args.key = (char *)(uintptr_t)args32.key;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   428
			args.mount_to = args32.mount_to;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   429
			args.rpc_to = args32.rpc_to;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   430
			args.direct = args32.direct;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   431
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   432
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   433
	if (error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   434
		return (EFAULT);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   435
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   436
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   437
	 * For a remount, only update mount information
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   438
	 * i.e. default mount options, map name, etc.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   439
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   440
	if (uap->flags & MS_REMOUNT) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   441
		fnip = vfstofni(vfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   442
		if (fnip == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   443
			return (EINVAL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   444
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   445
		if (args.direct == 1)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   446
			fnip->fi_flags |= MF_DIRECT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   447
		else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   448
			fnip->fi_flags &= ~MF_DIRECT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   449
		fnip->fi_mount_to = args.mount_to;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   450
		fnip->fi_rpc_to = args.rpc_to;
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
		 * Get default options
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   454
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   455
		if (uap->flags & MS_SYSSPACE)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   456
			error = copystr(args.opts, strbuff, sizeof (strbuff),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   457
			    &len);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   458
		else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   459
			error = copyinstr(args.opts, strbuff, sizeof (strbuff),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   460
			    &len);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   461
		if (error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   462
			return (EFAULT);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   463
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   464
		if (autofs_restrict_opts(vfsp, strbuff, sizeof (strbuff), &len)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   465
		    != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   466
			return (EFAULT);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   467
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   468
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   469
		kmem_free(fnip->fi_opts, fnip->fi_optslen);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   470
		fnip->fi_opts = kmem_alloc(len, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   471
		fnip->fi_optslen = (int)len;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   472
		bcopy(strbuff, fnip->fi_opts, len);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   473
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   474
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   475
		 * Get context/map name
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   476
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   477
		if (uap->flags & MS_SYSSPACE)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   478
			error = copystr(args.map, strbuff, sizeof (strbuff),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   479
			    &len);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   480
		else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   481
			error = copyinstr(args.map, strbuff, sizeof (strbuff),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   482
			    &len);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   483
		if (error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   484
			return (EFAULT);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   485
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   486
		kmem_free(fnip->fi_map, fnip->fi_maplen);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   487
		fnip->fi_map = kmem_alloc(len, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   488
		fnip->fi_maplen = (int)len;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   489
		bcopy(strbuff, fnip->fi_map, len);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   490
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   491
		return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   492
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   493
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   494
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   495
	 * Allocate fninfo struct and attach it to vfs
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   496
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   497
	fnip = kmem_zalloc(sizeof (*fnip), KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   498
	fnip->fi_mountvfs = vfsp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   499
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   500
	fnip->fi_mount_to = args.mount_to;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   501
	fnip->fi_rpc_to = args.rpc_to;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   502
	fnip->fi_refcnt = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   503
	vfsp->vfs_bsize = AUTOFS_BLOCKSIZE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   504
	vfsp->vfs_fstype = autofs_fstype;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   505
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   506
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   507
	 * Assign a unique device id to the mount
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   508
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   509
	mutex_enter(&autofs_minor_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   510
	do {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   511
		autofs_minor = (autofs_minor + 1) & L_MAXMIN32;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   512
		autofs_dev = makedevice(autofs_major, autofs_minor);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   513
	} while (vfs_devismounted(autofs_dev));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   514
	mutex_exit(&autofs_minor_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   515
	vfsp->vfs_dev = autofs_dev;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   516
	vfs_make_fsid(&vfsp->vfs_fsid, autofs_dev, autofs_fstype);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   517
	vfsp->vfs_data = (void *)fnip;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   518
	vfsp->vfs_bcount = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   519
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   520
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   521
	 * Get daemon address
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   522
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   523
	fnip->fi_addr.len = args.addr.len;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   524
	fnip->fi_addr.maxlen = fnip->fi_addr.len;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   525
	fnip->fi_addr.buf = kmem_alloc(args.addr.len, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   526
	if (uap->flags & MS_SYSSPACE)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   527
		error = kcopy(args.addr.buf, fnip->fi_addr.buf, args.addr.len);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   528
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   529
		error = copyin(args.addr.buf, fnip->fi_addr.buf, args.addr.len);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   530
	if (error) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   531
		error = EFAULT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   532
		goto errout;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   533
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   534
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   535
	fnip->fi_zoneid = getzoneid();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   536
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   537
	 * Get path for mountpoint
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   538
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   539
	if (uap->flags & MS_SYSSPACE)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   540
		error = copystr(args.path, strbuff, sizeof (strbuff), &len);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   541
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   542
		error = copyinstr(args.path, strbuff, sizeof (strbuff), &len);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   543
	if (error) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   544
		error = EFAULT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   545
		goto errout;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   546
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   547
	fnip->fi_path = kmem_alloc(len, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   548
	fnip->fi_pathlen = (int)len;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   549
	bcopy(strbuff, fnip->fi_path, len);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   550
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   551
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   552
	 * Get default options
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   553
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   554
	if (uap->flags & MS_SYSSPACE)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   555
		error = copystr(args.opts, strbuff, sizeof (strbuff), &len);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   556
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   557
		error = copyinstr(args.opts, strbuff, sizeof (strbuff), &len);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   558
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   559
	if (error != 0 ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   560
	    autofs_restrict_opts(vfsp, strbuff, sizeof (strbuff), &len) != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   561
		error = EFAULT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   562
		goto errout;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   563
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   564
	fnip->fi_opts = kmem_alloc(len, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   565
	fnip->fi_optslen = (int)len;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   566
	bcopy(strbuff, fnip->fi_opts, len);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   567
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   568
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   569
	 * Get context/map name
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   570
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   571
	if (uap->flags & MS_SYSSPACE)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   572
		error = copystr(args.map, strbuff, sizeof (strbuff), &len);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   573
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   574
		error = copyinstr(args.map, strbuff, sizeof (strbuff), &len);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   575
	if (error) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   576
		error = EFAULT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   577
		goto errout;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   578
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   579
	fnip->fi_map = kmem_alloc(len, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   580
	fnip->fi_maplen = (int)len;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   581
	bcopy(strbuff, fnip->fi_map, len);
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
	 * Get subdirectory within map
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   585
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   586
	if (uap->flags & MS_SYSSPACE)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   587
		error = copystr(args.subdir, strbuff, sizeof (strbuff), &len);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   588
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   589
		error = copyinstr(args.subdir, strbuff, sizeof (strbuff), &len);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   590
	if (error) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   591
		error = EFAULT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   592
		goto errout;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   593
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   594
	fnip->fi_subdir = kmem_alloc(len, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   595
	fnip->fi_subdirlen = (int)len;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   596
	bcopy(strbuff, fnip->fi_subdir, len);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   597
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   598
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   599
	 * Get the key
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   600
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   601
	if (uap->flags & MS_SYSSPACE)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   602
		error = copystr(args.key, strbuff, sizeof (strbuff), &len);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   603
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   604
		error = copyinstr(args.key, strbuff, sizeof (strbuff), &len);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   605
	if (error) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   606
		error = EFAULT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   607
		goto errout;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   608
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   609
	fnip->fi_key = kmem_alloc(len, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   610
	fnip->fi_keylen = (int)len;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   611
	bcopy(strbuff, fnip->fi_key, len);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   612
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   613
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   614
	 * Is this a direct mount?
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   615
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   616
	if (args.direct == 1)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   617
		fnip->fi_flags |= MF_DIRECT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   618
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   619
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   620
	 * Setup netconfig.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   621
	 * Can I pass in knconf as mount argument? what
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   622
	 * happens when the daemon gets restarted?
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   623
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   624
	if ((error = lookupname("/dev/ticotsord", UIO_SYSSPACE, FOLLOW,
11185
f0c31008e395 6887924 PP_ISKAS needs to be defined in terms of VN_ISKAS for vnodes
Sean McEnroe <Sean.McEnroe@Sun.COM>
parents: 4092
diff changeset
   625
	    NULLVPP, &kkvp)) != 0) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   626
		cmn_err(CE_WARN, "autofs: lookupname: %d", error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   627
		goto errout;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   628
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   629
11185
f0c31008e395 6887924 PP_ISKAS needs to be defined in terms of VN_ISKAS for vnodes
Sean McEnroe <Sean.McEnroe@Sun.COM>
parents: 4092
diff changeset
   630
	fnip->fi_knconf.knc_rdev = kkvp->v_rdev;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   631
	fnip->fi_knconf.knc_protofmly = NC_LOOPBACK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   632
	fnip->fi_knconf.knc_semantics = NC_TPI_COTS_ORD;
11185
f0c31008e395 6887924 PP_ISKAS needs to be defined in terms of VN_ISKAS for vnodes
Sean McEnroe <Sean.McEnroe@Sun.COM>
parents: 4092
diff changeset
   633
	VN_RELE(kkvp);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   634
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   635
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   636
	 * Make the root vnode
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   637
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   638
	rootfnp = auto_makefnnode(VDIR, vfsp, fnip->fi_path, cr, fngp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   639
	if (rootfnp == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   640
		error = ENOMEM;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   641
		goto errout;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   642
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   643
	rootvp = fntovn(rootfnp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   644
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   645
	rootvp->v_flag |= VROOT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   646
	rootfnp->fn_mode = AUTOFS_MODE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   647
	rootfnp->fn_parent = rootfnp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   648
	/* account for ".." entry */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   649
	rootfnp->fn_linkcnt = rootfnp->fn_size = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   650
	fnip->fi_rootvp = rootvp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   651
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   652
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   653
	 * Add to list of top level AUTOFS' if it is being mounted by
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   654
	 * a user level process.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   655
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   656
	if (!(uap->flags & MS_SYSSPACE)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   657
		rw_enter(&fngp->fng_rootfnnodep->fn_rwlock, RW_WRITER);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   658
		rootfnp->fn_parent = fngp->fng_rootfnnodep;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   659
		rootfnp->fn_next = fngp->fng_rootfnnodep->fn_dirents;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   660
		fngp->fng_rootfnnodep->fn_dirents = rootfnp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   661
		rw_exit(&fngp->fng_rootfnnodep->fn_rwlock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   662
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   663
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   664
	AUTOFS_DPRINT((5, "auto_mount: vfs %p root %p fnip %p return %d\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   665
	    (void *)vfsp, (void *)rootvp, (void *)fnip, error));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   666
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   667
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   668
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   669
errout:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   670
	ASSERT(fnip != NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   671
	ASSERT((uap->flags & MS_REMOUNT) == 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   672
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   673
	if (fnip->fi_addr.buf != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   674
		kmem_free(fnip->fi_addr.buf, fnip->fi_addr.len);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   675
	if (fnip->fi_path != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   676
		kmem_free(fnip->fi_path, fnip->fi_pathlen);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   677
	if (fnip->fi_opts != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   678
		kmem_free(fnip->fi_opts, fnip->fi_optslen);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   679
	if (fnip->fi_map != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   680
		kmem_free(fnip->fi_map, fnip->fi_maplen);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   681
	if (fnip->fi_subdir != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   682
		kmem_free(fnip->fi_subdir, fnip->fi_subdirlen);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   683
	if (fnip->fi_key != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   684
		kmem_free(fnip->fi_key, fnip->fi_keylen);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   685
	kmem_free(fnip, sizeof (*fnip));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   686
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   687
	AUTOFS_DPRINT((5, "auto_mount: vfs %p root %p fnip %p return %d\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   688
	    (void *)vfsp, (void *)rootvp, (void *)fnip, error));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   689
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   690
	return (error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   691
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   692
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   693
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   694
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   695
auto_unmount(vfs_t *vfsp, int flag, cred_t *cr)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   696
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   697
	fninfo_t *fnip;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   698
	vnode_t *rvp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   699
	fnnode_t *rfnp, *fnp, *pfnp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   700
	fnnode_t *myrootfnnodep;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   701
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   702
	fnip = vfstofni(vfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   703
	AUTOFS_DPRINT((4, "auto_unmount vfsp %p fnip %p\n", (void *)vfsp,
11185
f0c31008e395 6887924 PP_ISKAS needs to be defined in terms of VN_ISKAS for vnodes
Sean McEnroe <Sean.McEnroe@Sun.COM>
parents: 4092
diff changeset
   704
	    (void *)fnip));
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   705
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   706
	if (secpolicy_fs_unmount(cr, vfsp) != 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   707
		return (EPERM);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   708
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   709
	 * forced unmount is not supported by this file system
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   710
	 * and thus, ENOTSUP, is being returned.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   711
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   712
	if (flag & MS_FORCE)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   713
		return (ENOTSUP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   714
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   715
	ASSERT(vn_vfswlock_held(vfsp->vfs_vnodecovered));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   716
	rvp = fnip->fi_rootvp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   717
	rfnp = vntofn(rvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   718
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   719
	if (rvp->v_count > 1 || rfnp->fn_dirents != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   720
		return (EBUSY);
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
	 * The root vnode is on the linked list of root fnnodes only if
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   724
	 * this was not a trigger node. Since we have no way of knowing,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   725
	 * if we don't find it, then we assume it was a trigger node.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   726
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   727
	myrootfnnodep = rfnp->fn_globals->fng_rootfnnodep;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   728
	pfnp = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   729
	rw_enter(&myrootfnnodep->fn_rwlock, RW_WRITER);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   730
	fnp = myrootfnnodep->fn_dirents;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   731
	while (fnp != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   732
		if (fnp == rfnp) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   733
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   734
			 * A check here is made to see if rvp is busy.  If
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   735
			 * so, return EBUSY.  Otherwise proceed with
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   736
			 * disconnecting it from the list.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   737
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   738
			if (rvp->v_count > 1 || rfnp->fn_dirents != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   739
				rw_exit(&myrootfnnodep->fn_rwlock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   740
				return (EBUSY);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   741
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   742
			if (pfnp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   743
				pfnp->fn_next = fnp->fn_next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   744
			else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   745
				myrootfnnodep->fn_dirents = fnp->fn_next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   746
			fnp->fn_next = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   747
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   748
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   749
		pfnp = fnp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   750
		fnp = fnp->fn_next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   751
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   752
	rw_exit(&myrootfnnodep->fn_rwlock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   753
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   754
	ASSERT(rvp->v_count == 1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   755
	ASSERT(rfnp->fn_size == 1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   756
	ASSERT(rfnp->fn_linkcnt == 1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   757
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   758
	 * The following drops linkcnt to 0, therefore the disconnect is
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   759
	 * not attempted when auto_inactive() is called by
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   760
	 * vn_rele(). This is necessary because we have nothing to get
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   761
	 * disconnected from since we're the root of the filesystem. As a
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   762
	 * side effect the node is not freed, therefore I should free the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   763
	 * node here.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   764
	 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   765
	 * XXX - I really need to think of a better way of doing this.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   766
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   767
	rfnp->fn_size--;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   768
	rfnp->fn_linkcnt--;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   769
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   770
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   771
	 * release of last reference causes node
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   772
	 * to be freed
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   773
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   774
	VN_RELE(rvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   775
	rfnp->fn_parent = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   776
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   777
	auto_freefnnode(rfnp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   778
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   779
	kmem_free(fnip->fi_addr.buf, fnip->fi_addr.len);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   780
	kmem_free(fnip->fi_path, fnip->fi_pathlen);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   781
	kmem_free(fnip->fi_map, fnip->fi_maplen);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   782
	kmem_free(fnip->fi_subdir, fnip->fi_subdirlen);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   783
	kmem_free(fnip->fi_key, fnip->fi_keylen);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   784
	kmem_free(fnip->fi_opts, fnip->fi_optslen);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   785
	kmem_free(fnip, sizeof (*fnip));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   786
	AUTOFS_DPRINT((5, "auto_unmount: return=0\n"));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   787
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   788
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   789
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   790
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   791
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   792
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   793
 * find root of autofs
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   794
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   795
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   796
auto_root(vfs_t *vfsp, vnode_t **vpp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   797
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   798
	*vpp = (vnode_t *)vfstofni(vfsp)->fi_rootvp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   799
	VN_HOLD(*vpp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   800
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   801
	AUTOFS_DPRINT((5, "auto_root: vfs %p, *vpp %p\n", (void *)vfsp,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   802
	    (void *)*vpp));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   803
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   804
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   805
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   806
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   807
 * Get file system statistics.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   808
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   809
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   810
auto_statvfs(vfs_t *vfsp, struct statvfs64 *sbp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   811
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   812
	dev32_t d32;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   813
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   814
	AUTOFS_DPRINT((4, "auto_statvfs %p\n", (void *)vfsp));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   815
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   816
	bzero(sbp, sizeof (*sbp));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   817
	sbp->f_bsize	= vfsp->vfs_bsize;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   818
	sbp->f_frsize	= sbp->f_bsize;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   819
	sbp->f_blocks	= (fsblkcnt64_t)0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   820
	sbp->f_bfree	= (fsblkcnt64_t)0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   821
	sbp->f_bavail	= (fsblkcnt64_t)0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   822
	sbp->f_files	= (fsfilcnt64_t)0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   823
	sbp->f_ffree	= (fsfilcnt64_t)0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   824
	sbp->f_favail	= (fsfilcnt64_t)0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   825
	(void) cmpldev(&d32, vfsp->vfs_dev);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   826
	sbp->f_fsid	= d32;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   827
	(void) strcpy(sbp->f_basetype, vfssw[vfsp->vfs_fstype].vsw_name);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   828
	sbp->f_flag = vf_to_stf(vfsp->vfs_flag);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   829
	sbp->f_namemax = MAXNAMELEN;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   830
	(void) strcpy(sbp->f_fstr, MNTTYPE_AUTOFS);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   831
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   832
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   833
}