usr/src/uts/common/fs/autofs/auto_vnops.c
author Casper H.S. Dik <Casper.Dik@Sun.COM>
Wed, 28 Apr 2010 10:01:37 +0200
changeset 12273 63678502e95e
parent 12184 0216e4439444
child 12904 c3fa1a3c3799
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
2170
eb691d2a219e PSARC 2005/714 Automounter Scalability Enhancements
evanl
parents: 1153
diff changeset
     5
 * Common Development and Distribution License (the "License").
eb691d2a219e PSARC 2005/714 Automounter Scalability Enhancements
evanl
parents: 1153
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
/*
12184
0216e4439444 6864918 S10 auto_direct takes 45 mins to remount after manually unmounted a directory vs. S8 instantly
Jan Kryl <Jan.Kryl@Sun.COM>
parents: 5331
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/systm.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    27
#include <sys/errno.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    28
#include <sys/proc.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    29
#include <sys/vnode.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    30
#include <sys/vfs.h>
3898
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 3391
diff changeset
    31
#include <sys/vfs_opreg.h>
0
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/cred.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    34
#include <sys/pathname.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    35
#include <sys/dirent.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    36
#include <sys/debug.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    37
#include <sys/sysmacros.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    38
#include <sys/tiuser.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    39
#include <sys/cmn_err.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    40
#include <sys/stat.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    41
#include <sys/mode.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    42
#include <sys/policy.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 <sys/fs/autofs.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    47
#include <rpcsvc/autofs_prot.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    48
#include <fs/fs_subr.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    49
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    50
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    51
 *  Vnode ops for autofs
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    52
 */
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
    53
static int auto_open(vnode_t **, int, cred_t *, caller_context_t *);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
    54
static int auto_close(vnode_t *, int, int, offset_t, cred_t *,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
    55
	caller_context_t *);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
    56
static int auto_getattr(vnode_t *, vattr_t *, int, cred_t *,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
    57
	caller_context_t *);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    58
static int auto_setattr(vnode_t *, vattr_t *, int, cred_t *,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    59
	caller_context_t *);
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
    60
static int auto_access(vnode_t *, int, int, cred_t *, caller_context_t *);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    61
static int auto_lookup(vnode_t *, char *, vnode_t **,
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
    62
	pathname_t *, int, vnode_t *, cred_t *, caller_context_t *, int *,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
    63
	pathname_t *);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    64
static int auto_create(vnode_t *, char *, vattr_t *, vcexcl_t,
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
    65
	int, vnode_t **, cred_t *, int, caller_context_t *,  vsecattr_t *);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
    66
static int auto_remove(vnode_t *, char *, cred_t *, caller_context_t *, int);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
    67
static int auto_link(vnode_t *, vnode_t *, char *, cred_t *,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
    68
	caller_context_t *, int);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
    69
static int auto_rename(vnode_t *, char *, vnode_t *, char *, cred_t *,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
    70
	caller_context_t *, int);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
    71
static int auto_mkdir(vnode_t *, char *, vattr_t *, vnode_t **, cred_t *,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
    72
	caller_context_t *, int, vsecattr_t *);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
    73
static int auto_rmdir(vnode_t *, char *, vnode_t *, cred_t *,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
    74
	caller_context_t *, int);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
    75
static int auto_readdir(vnode_t *, uio_t *, cred_t *, int *,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
    76
	caller_context_t *, int);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
    77
static int auto_symlink(vnode_t *, char *, vattr_t *, char *, cred_t *,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
    78
	caller_context_t *, int);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
    79
static int auto_readlink(vnode_t *, struct uio *, cred_t *,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
    80
	caller_context_t *);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
    81
static int auto_fsync(vnode_t *, int, cred_t *, caller_context_t *);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
    82
static void auto_inactive(vnode_t *, cred_t *, caller_context_t *);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    83
static int auto_rwlock(vnode_t *, int, caller_context_t *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    84
static void auto_rwunlock(vnode_t *vp, int, caller_context_t *);
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
    85
static int auto_seek(vnode_t *vp, offset_t, offset_t *, caller_context_t *);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    86
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    87
static int auto_trigger_mount(vnode_t *, cred_t *, vnode_t **);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    88
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    89
vnodeops_t *auto_vnodeops;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    90
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    91
const fs_operation_def_t auto_vnodeops_template[] = {
3898
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 3391
diff changeset
    92
	VOPNAME_OPEN,		{ .vop_open = auto_open },
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 3391
diff changeset
    93
	VOPNAME_CLOSE,		{ .vop_close = auto_close },
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 3391
diff changeset
    94
	VOPNAME_GETATTR,	{ .vop_getattr = auto_getattr },
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 3391
diff changeset
    95
	VOPNAME_SETATTR,	{ .vop_setattr = auto_setattr },
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 3391
diff changeset
    96
	VOPNAME_ACCESS,		{ .vop_access = auto_access },
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 3391
diff changeset
    97
	VOPNAME_LOOKUP,		{ .vop_lookup = auto_lookup },
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 3391
diff changeset
    98
	VOPNAME_CREATE,		{ .vop_create = auto_create },
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 3391
diff changeset
    99
	VOPNAME_REMOVE,		{ .vop_remove = auto_remove },
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 3391
diff changeset
   100
	VOPNAME_LINK,		{ .vop_link = auto_link },
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 3391
diff changeset
   101
	VOPNAME_RENAME,		{ .vop_rename = auto_rename },
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 3391
diff changeset
   102
	VOPNAME_MKDIR,		{ .vop_mkdir = auto_mkdir },
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 3391
diff changeset
   103
	VOPNAME_RMDIR,		{ .vop_rmdir = auto_rmdir },
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 3391
diff changeset
   104
	VOPNAME_READDIR,	{ .vop_readdir = auto_readdir },
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 3391
diff changeset
   105
	VOPNAME_SYMLINK,	{ .vop_symlink = auto_symlink },
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 3391
diff changeset
   106
	VOPNAME_READLINK,	{ .vop_readlink = auto_readlink },
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 3391
diff changeset
   107
	VOPNAME_FSYNC,		{ .vop_fsync = auto_fsync },
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 3391
diff changeset
   108
	VOPNAME_INACTIVE,	{ .vop_inactive = auto_inactive },
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 3391
diff changeset
   109
	VOPNAME_RWLOCK,		{ .vop_rwlock = auto_rwlock },
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 3391
diff changeset
   110
	VOPNAME_RWUNLOCK,	{ .vop_rwunlock = auto_rwunlock },
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 3391
diff changeset
   111
	VOPNAME_SEEK,		{ .vop_seek = auto_seek },
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 3391
diff changeset
   112
	VOPNAME_FRLOCK,		{ .error = fs_error },
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 3391
diff changeset
   113
	VOPNAME_DISPOSE,	{ .error = fs_error },
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 3391
diff changeset
   114
	VOPNAME_SHRLOCK,	{ .error = fs_error },
4863
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
   115
	VOPNAME_VNEVENT,	{ .vop_vnevent = fs_vnevent_support },
3898
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 3391
diff changeset
   116
	NULL,			NULL
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   117
};
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   118
2170
eb691d2a219e PSARC 2005/714 Automounter Scalability Enhancements
evanl
parents: 1153
diff changeset
   119
eb691d2a219e PSARC 2005/714 Automounter Scalability Enhancements
evanl
parents: 1153
diff changeset
   120
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   121
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   122
static int
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   123
auto_open(vnode_t **vpp, int flag, cred_t *cred, caller_context_t *ct)
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   124
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   125
	vnode_t *newvp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   126
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   127
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   128
	AUTOFS_DPRINT((4, "auto_open: *vpp=%p\n", (void *)*vpp));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   129
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   130
	error = auto_trigger_mount(*vpp, cred, &newvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   131
	if (error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   132
		goto done;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   133
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   134
	if (newvp != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   135
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   136
		 * Node is now mounted on.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   137
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   138
		VN_RELE(*vpp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   139
		*vpp = newvp;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   140
		error = VOP_ACCESS(*vpp, VREAD, 0, cred, ct);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   141
		if (!error)
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   142
			error = VOP_OPEN(vpp, flag, cred, ct);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   143
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   144
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   145
done:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   146
	AUTOFS_DPRINT((5, "auto_open: *vpp=%p error=%d\n", (void *)*vpp,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   147
	    error));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   148
	return (error);
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
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   152
static int
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   153
auto_close(
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   154
	vnode_t *vp,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   155
	int flag,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   156
	int count,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   157
	offset_t offset,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   158
	cred_t *cred,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   159
	caller_context_t *ct)
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   160
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   161
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   162
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   163
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   164
static int
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   165
auto_getattr(
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   166
	vnode_t *vp,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   167
	vattr_t *vap,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   168
	int flags,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   169
	cred_t *cred,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   170
	caller_context_t *ct)
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   171
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   172
	fnnode_t *fnp = vntofn(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   173
	vnode_t *newvp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   174
	vfs_t *vfsp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   175
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   176
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   177
	AUTOFS_DPRINT((4, "auto_getattr vp %p\n", (void *)vp));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   178
5302
eec6aeacde6e PSARC 2007/416 NFSv4 Mirror-mounts
th199096
parents: 4863
diff changeset
   179
	if (flags & ATTR_TRIGGER) {
eec6aeacde6e PSARC 2007/416 NFSv4 Mirror-mounts
th199096
parents: 4863
diff changeset
   180
		/*
eec6aeacde6e PSARC 2007/416 NFSv4 Mirror-mounts
th199096
parents: 4863
diff changeset
   181
		 * Pre-trigger the mount
eec6aeacde6e PSARC 2007/416 NFSv4 Mirror-mounts
th199096
parents: 4863
diff changeset
   182
		 */
eec6aeacde6e PSARC 2007/416 NFSv4 Mirror-mounts
th199096
parents: 4863
diff changeset
   183
		error = auto_trigger_mount(vp, cred, &newvp);
eec6aeacde6e PSARC 2007/416 NFSv4 Mirror-mounts
th199096
parents: 4863
diff changeset
   184
		if (error)
eec6aeacde6e PSARC 2007/416 NFSv4 Mirror-mounts
th199096
parents: 4863
diff changeset
   185
			return (error);
eec6aeacde6e PSARC 2007/416 NFSv4 Mirror-mounts
th199096
parents: 4863
diff changeset
   186
eec6aeacde6e PSARC 2007/416 NFSv4 Mirror-mounts
th199096
parents: 4863
diff changeset
   187
		if (newvp == NULL)
eec6aeacde6e PSARC 2007/416 NFSv4 Mirror-mounts
th199096
parents: 4863
diff changeset
   188
			goto defattr;
eec6aeacde6e PSARC 2007/416 NFSv4 Mirror-mounts
th199096
parents: 4863
diff changeset
   189
eec6aeacde6e PSARC 2007/416 NFSv4 Mirror-mounts
th199096
parents: 4863
diff changeset
   190
		if (error = vn_vfsrlock_wait(vp))
eec6aeacde6e PSARC 2007/416 NFSv4 Mirror-mounts
th199096
parents: 4863
diff changeset
   191
			return (error);
149
b1477e956aca 6268481 unprivileged user calling umount on a autofs mountpoint hangs
casper
parents: 0
diff changeset
   192
5302
eec6aeacde6e PSARC 2007/416 NFSv4 Mirror-mounts
th199096
parents: 4863
diff changeset
   193
		vfsp = newvp->v_vfsp;
eec6aeacde6e PSARC 2007/416 NFSv4 Mirror-mounts
th199096
parents: 4863
diff changeset
   194
	} else {
eec6aeacde6e PSARC 2007/416 NFSv4 Mirror-mounts
th199096
parents: 4863
diff changeset
   195
		/*
eec6aeacde6e PSARC 2007/416 NFSv4 Mirror-mounts
th199096
parents: 4863
diff changeset
   196
		 * Recursive auto_getattr/mount; go to the vfsp == NULL
eec6aeacde6e PSARC 2007/416 NFSv4 Mirror-mounts
th199096
parents: 4863
diff changeset
   197
		 * case.
eec6aeacde6e PSARC 2007/416 NFSv4 Mirror-mounts
th199096
parents: 4863
diff changeset
   198
		 */
eec6aeacde6e PSARC 2007/416 NFSv4 Mirror-mounts
th199096
parents: 4863
diff changeset
   199
		if (vn_vfswlock_held(vp))
eec6aeacde6e PSARC 2007/416 NFSv4 Mirror-mounts
th199096
parents: 4863
diff changeset
   200
			goto defattr;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   201
5302
eec6aeacde6e PSARC 2007/416 NFSv4 Mirror-mounts
th199096
parents: 4863
diff changeset
   202
		if (error = vn_vfsrlock_wait(vp))
eec6aeacde6e PSARC 2007/416 NFSv4 Mirror-mounts
th199096
parents: 4863
diff changeset
   203
			return (error);
eec6aeacde6e PSARC 2007/416 NFSv4 Mirror-mounts
th199096
parents: 4863
diff changeset
   204
eec6aeacde6e PSARC 2007/416 NFSv4 Mirror-mounts
th199096
parents: 4863
diff changeset
   205
		vfsp = vn_mountedvfs(vp);
eec6aeacde6e PSARC 2007/416 NFSv4 Mirror-mounts
th199096
parents: 4863
diff changeset
   206
	}
eec6aeacde6e PSARC 2007/416 NFSv4 Mirror-mounts
th199096
parents: 4863
diff changeset
   207
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   208
	if (vfsp != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   209
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   210
		 * Node is mounted on.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   211
		 */
1153
b0029fa0379d 4845430 heavy lookup on autofs mountpoints can introduce scalability issues.
nr123932
parents: 149
diff changeset
   212
		error = VFS_ROOT(vfsp, &newvp);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   213
		vn_vfsunlock(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   214
		if (error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   215
			return (error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   216
		mutex_enter(&fnp->fn_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   217
		if (fnp->fn_seen == newvp && fnp->fn_thread == curthread) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   218
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   219
			 * Recursive auto_getattr(); just release newvp and drop
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   220
			 * into the vfsp == NULL case.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   221
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   222
			mutex_exit(&fnp->fn_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   223
			VN_RELE(newvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   224
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   225
			while (fnp->fn_thread && fnp->fn_thread != curthread) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   226
				fnp->fn_flags |= MF_ATTR_WAIT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   227
				cv_wait(&fnp->fn_cv_mount, &fnp->fn_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   228
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   229
			fnp->fn_thread = curthread;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   230
			fnp->fn_seen = newvp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   231
			mutex_exit(&fnp->fn_lock);
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   232
			error = VOP_GETATTR(newvp, vap, flags, cred, ct);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   233
			VN_RELE(newvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   234
			mutex_enter(&fnp->fn_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   235
			fnp->fn_seen = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   236
			fnp->fn_thread = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   237
			if (fnp->fn_flags & MF_ATTR_WAIT) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   238
				fnp->fn_flags &= ~MF_ATTR_WAIT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   239
				cv_broadcast(&fnp->fn_cv_mount);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   240
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   241
			mutex_exit(&fnp->fn_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   242
			return (error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   243
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   244
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   245
		vn_vfsunlock(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   246
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   247
149
b1477e956aca 6268481 unprivileged user calling umount on a autofs mountpoint hangs
casper
parents: 0
diff changeset
   248
defattr:
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   249
	ASSERT(vp->v_type == VDIR || vp->v_type == VLNK);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   250
	vap->va_uid	= 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   251
	vap->va_gid	= 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   252
	vap->va_nlink	= fnp->fn_linkcnt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   253
	vap->va_nodeid	= (u_longlong_t)fnp->fn_nodeid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   254
	vap->va_size	= fnp->fn_size;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   255
	vap->va_atime	= fnp->fn_atime;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   256
	vap->va_mtime	= fnp->fn_mtime;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   257
	vap->va_ctime	= fnp->fn_ctime;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   258
	vap->va_type	= vp->v_type;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   259
	vap->va_mode	= fnp->fn_mode;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   260
	vap->va_fsid	= vp->v_vfsp->vfs_dev;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   261
	vap->va_rdev	= 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   262
	vap->va_blksize	= MAXBSIZE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   263
	vap->va_nblocks	= (fsblkcnt64_t)btod(vap->va_size);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   264
	vap->va_seq	= 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   265
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   266
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   267
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   268
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   269
/*ARGSUSED4*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   270
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   271
auto_setattr(
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   272
	vnode_t *vp,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   273
	struct vattr *vap,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   274
	int flags,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   275
	cred_t *cred,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   276
	caller_context_t *ct)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   277
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   278
	vnode_t *newvp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   279
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   280
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   281
	AUTOFS_DPRINT((4, "auto_setattr vp %p\n", (void *)vp));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   282
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   283
	if (error = auto_trigger_mount(vp, cred, &newvp))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   284
		goto done;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   285
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   286
	if (newvp != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   287
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   288
		 * Node is mounted on.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   289
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   290
		if (vn_is_readonly(newvp))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   291
			error = EROFS;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   292
		else
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   293
			error = VOP_SETATTR(newvp, vap, flags, cred, ct);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   294
		VN_RELE(newvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   295
	} else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   296
		error = ENOSYS;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   297
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   298
done:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   299
	AUTOFS_DPRINT((5, "auto_setattr: error=%d\n", error));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   300
	return (error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   301
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   302
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   303
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   304
static int
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   305
auto_access(
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   306
	vnode_t *vp,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   307
	int mode,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   308
	int flags,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   309
	cred_t *cred,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   310
	caller_context_t *ct)
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   311
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   312
	fnnode_t *fnp = vntofn(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   313
	vnode_t *newvp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   314
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   315
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   316
	AUTOFS_DPRINT((4, "auto_access: vp=%p\n", (void *)vp));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   317
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   318
	if (error = auto_trigger_mount(vp, cred, &newvp))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   319
		goto done;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   320
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   321
	if (newvp != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   322
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   323
		 * Node is mounted on.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   324
		 */
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   325
		error = VOP_ACCESS(newvp, mode, 0, cred, ct);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   326
		VN_RELE(newvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   327
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   328
		int shift = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   329
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   330
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   331
		 * really interested in the autofs node, check the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   332
		 * access on it
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   333
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   334
		ASSERT(error == 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   335
		if (crgetuid(cred) != fnp->fn_uid) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   336
			shift += 3;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   337
			if (groupmember(fnp->fn_gid, cred) == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   338
				shift += 3;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   339
		}
12273
63678502e95e PSARC 2009/377 In-kernel pfexec implementation.
Casper H.S. Dik <Casper.Dik@Sun.COM>
parents: 12184
diff changeset
   340
		error = secpolicy_vnode_access2(cred, vp, fnp->fn_uid,
63678502e95e PSARC 2009/377 In-kernel pfexec implementation.
Casper H.S. Dik <Casper.Dik@Sun.COM>
parents: 12184
diff changeset
   341
		    fnp->fn_mode << shift, mode);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   342
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   343
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   344
done:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   345
	AUTOFS_DPRINT((5, "auto_access: error=%d\n", error));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   346
	return (error);
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
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   350
auto_lookup(
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   351
	vnode_t *dvp,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   352
	char *nm,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   353
	vnode_t **vpp,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   354
	pathname_t *pnp,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   355
	int flags,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   356
	vnode_t *rdir,
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   357
	cred_t *cred,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   358
	caller_context_t *ct,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   359
	int *direntflags,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   360
	pathname_t *realpnp)
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   361
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   362
	int error = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   363
	vnode_t *newvp = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   364
	vfs_t *vfsp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   365
	fninfo_t *dfnip;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   366
	fnnode_t *dfnp = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   367
	fnnode_t *fnp = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   368
	char *searchnm;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   369
	int operation;		/* either AUTOFS_LOOKUP or AUTOFS_MOUNT */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   370
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   371
	dfnip = vfstofni(dvp->v_vfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   372
	AUTOFS_DPRINT((3, "auto_lookup: dvp=%p (%s) name=%s\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   373
	    (void *)dvp, dfnip->fi_map, nm));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   374
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   375
	if (nm[0] == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   376
		VN_HOLD(dvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   377
		*vpp = dvp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   378
		return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   379
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   380
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   381
	if (error = VOP_ACCESS(dvp, VEXEC, 0, cred, ct))
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   382
		return (error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   383
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   384
	if (nm[0] == '.' && nm[1] == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   385
		VN_HOLD(dvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   386
		*vpp = dvp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   387
		return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   388
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   389
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   390
	if (nm[0] == '.' && nm[1] == '.' && nm[2] == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   391
		fnnode_t *pdfnp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   392
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   393
		pdfnp = (vntofn(dvp))->fn_parent;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   394
		ASSERT(pdfnp != NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   395
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   396
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   397
		 * Since it is legitimate to have the VROOT flag set for the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   398
		 * subdirectories of the indirect map in autofs filesystem,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   399
		 * rootfnnodep is checked against fnnode of dvp instead of
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   400
		 * just checking whether VROOT flag is set in dvp
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   401
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   402
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   403
		if (pdfnp == pdfnp->fn_globals->fng_rootfnnodep) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   404
			vnode_t *vp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   405
1153
b0029fa0379d 4845430 heavy lookup on autofs mountpoints can introduce scalability issues.
nr123932
parents: 149
diff changeset
   406
			vfs_rlock_wait(dvp->v_vfsp);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   407
			if (dvp->v_vfsp->vfs_flag & VFS_UNMOUNTED) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   408
				vfs_unlock(dvp->v_vfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   409
				return (EIO);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   410
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   411
			vp = dvp->v_vfsp->vfs_vnodecovered;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   412
			VN_HOLD(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   413
			vfs_unlock(dvp->v_vfsp);
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   414
			error = VOP_LOOKUP(vp, nm, vpp, pnp, flags, rdir, cred,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   415
			    ct, direntflags, realpnp);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   416
			VN_RELE(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   417
			return (error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   418
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   419
			*vpp = fntovn(pdfnp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   420
			VN_HOLD(*vpp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   421
			return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   422
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   423
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   424
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   425
top:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   426
	dfnp = vntofn(dvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   427
	searchnm = nm;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   428
	operation = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   429
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   430
	ASSERT(vn_matchops(dvp, auto_vnodeops));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   431
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   432
	AUTOFS_DPRINT((3, "auto_lookup: dvp=%p dfnp=%p\n", (void *)dvp,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   433
	    (void *)dfnp));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   434
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   435
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   436
	 * If a lookup or mount of this node is in progress, wait for it
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   437
	 * to finish, and return whatever result it got.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   438
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   439
	mutex_enter(&dfnp->fn_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   440
	if (dfnp->fn_flags & (MF_LOOKUP | MF_INPROG)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   441
		mutex_exit(&dfnp->fn_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   442
		error = auto_wait4mount(dfnp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   443
		if (error == AUTOFS_SHUTDOWN)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   444
			error = ENOENT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   445
		if (error == EAGAIN)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   446
			goto top;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   447
		if (error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   448
			return (error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   449
	} else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   450
		mutex_exit(&dfnp->fn_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   451
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   452
1153
b0029fa0379d 4845430 heavy lookup on autofs mountpoints can introduce scalability issues.
nr123932
parents: 149
diff changeset
   453
	error = vn_vfsrlock_wait(dvp);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   454
	if (error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   455
		return (error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   456
	vfsp = vn_mountedvfs(dvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   457
	if (vfsp != NULL) {
1153
b0029fa0379d 4845430 heavy lookup on autofs mountpoints can introduce scalability issues.
nr123932
parents: 149
diff changeset
   458
		error = VFS_ROOT(vfsp, &newvp);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   459
		vn_vfsunlock(dvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   460
		if (!error) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   461
			error = VOP_LOOKUP(newvp, nm, vpp, pnp,
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   462
			    flags, rdir, cred, ct, direntflags, realpnp);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   463
			VN_RELE(newvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   464
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   465
		return (error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   466
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   467
	vn_vfsunlock(dvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   468
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   469
	rw_enter(&dfnp->fn_rwlock, RW_READER);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   470
	error = auto_search(dfnp, nm, &fnp, cred);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   471
	if (error) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   472
		if (dfnip->fi_flags & MF_DIRECT) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   473
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   474
			 * direct map.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   475
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   476
			if (dfnp->fn_dirents) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   477
				/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   478
				 * Mount previously triggered.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   479
				 * 'nm' not found
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   480
				 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   481
				error = ENOENT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   482
			} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   483
				/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   484
				 * I need to contact the daemon to trigger
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   485
				 * the mount. 'dfnp' will be the mountpoint.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   486
				 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   487
				operation = AUTOFS_MOUNT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   488
				VN_HOLD(fntovn(dfnp));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   489
				fnp = dfnp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   490
				error = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   491
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   492
		} else if (dvp == dfnip->fi_rootvp) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   493
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   494
			 * 'dfnp' is the root of the indirect AUTOFS.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   495
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   496
			if (rw_tryupgrade(&dfnp->fn_rwlock) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   497
				/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   498
				 * Could not acquire writer lock, release
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   499
				 * reader, and wait until available. We
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   500
				 * need to search for 'nm' again, since we
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   501
				 * had to release the lock before reacquiring
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   502
				 * it.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   503
				 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   504
				rw_exit(&dfnp->fn_rwlock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   505
				rw_enter(&dfnp->fn_rwlock, RW_WRITER);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   506
				error = auto_search(dfnp, nm, &fnp, cred);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   507
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   508
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   509
			ASSERT(RW_WRITE_HELD(&dfnp->fn_rwlock));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   510
			if (error) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   511
				/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   512
				 * create node being looked-up and request
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   513
				 * mount on it.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   514
				 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   515
				error = auto_enter(dfnp, nm, &fnp, kcred);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   516
				if (!error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   517
					operation = AUTOFS_LOOKUP;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   518
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   519
		} else if ((dfnp->fn_dirents == NULL) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   520
		    ((dvp->v_flag & VROOT) == 0) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   521
		    ((fntovn(dfnp->fn_parent))->v_flag & VROOT)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   522
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   523
			 * dfnp is the actual 'mountpoint' of indirect map,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   524
			 * it is the equivalent of a direct mount,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   525
			 * ie, /home/'user1'
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   526
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   527
			operation = AUTOFS_MOUNT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   528
			VN_HOLD(fntovn(dfnp));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   529
			fnp = dfnp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   530
			error = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   531
			searchnm = dfnp->fn_name;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   532
		}
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
	if (error == EAGAIN) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   536
		rw_exit(&dfnp->fn_rwlock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   537
		goto top;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   538
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   539
	if (error) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   540
		rw_exit(&dfnp->fn_rwlock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   541
		return (error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   542
	}
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
	 * We now have the actual fnnode we're interested in.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   546
	 * The 'MF_LOOKUP' indicates another thread is currently
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   547
	 * performing a daemon lookup of this node, therefore we
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   548
	 * wait for its completion.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   549
	 * The 'MF_INPROG' indicates another thread is currently
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   550
	 * performing a daemon mount of this node, we wait for it
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   551
	 * to be done if we are performing a MOUNT. We don't
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   552
	 * wait for it if we are performing a LOOKUP.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   553
	 * We can release the reader/writer lock as soon as we acquire
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   554
	 * the mutex, since the state of the lock can only change by
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   555
	 * first acquiring the mutex.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   556
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   557
	mutex_enter(&fnp->fn_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   558
	rw_exit(&dfnp->fn_rwlock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   559
	if ((fnp->fn_flags & MF_LOOKUP) ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   560
	    ((operation == AUTOFS_MOUNT) && (fnp->fn_flags & MF_INPROG))) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   561
		mutex_exit(&fnp->fn_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   562
		error = auto_wait4mount(fnp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   563
		VN_RELE(fntovn(fnp));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   564
		if (error == AUTOFS_SHUTDOWN)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   565
			error = ENOENT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   566
		if (error && error != EAGAIN)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   567
			return (error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   568
		goto top;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   569
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   570
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   571
	if (operation == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   572
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   573
		 * got the fnnode, check for any errors
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   574
		 * on the previous operation on that node.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   575
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   576
		error = fnp->fn_error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   577
		if ((error == EINTR) || (error == EAGAIN)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   578
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   579
			 * previous operation on this node was
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   580
			 * not completed, do a lookup now.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   581
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   582
			operation = AUTOFS_LOOKUP;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   583
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   584
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   585
			 * previous operation completed. Return
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   586
			 * a pointer to the node only if there was
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   587
			 * no error.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   588
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   589
			mutex_exit(&fnp->fn_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   590
			if (!error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   591
				*vpp = fntovn(fnp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   592
			else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   593
				VN_RELE(fntovn(fnp));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   594
			return (error);
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
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   598
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   599
	 * Since I got to this point, it means I'm the one
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   600
	 * responsible for triggering the mount/look-up of this node.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   601
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   602
	switch (operation) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   603
	case AUTOFS_LOOKUP:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   604
		AUTOFS_BLOCK_OTHERS(fnp, MF_LOOKUP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   605
		fnp->fn_error = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   606
		mutex_exit(&fnp->fn_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   607
		error = auto_lookup_aux(fnp, searchnm, cred);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   608
		if (!error) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   609
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   610
			 * Return this vnode
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   611
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   612
			*vpp = fntovn(fnp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   613
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   614
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   615
			 * release our reference to this vnode
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   616
			 * and return error
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   617
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   618
			VN_RELE(fntovn(fnp));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   619
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   620
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   621
	case AUTOFS_MOUNT:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   622
		AUTOFS_BLOCK_OTHERS(fnp, MF_INPROG);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   623
		fnp->fn_error = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   624
		mutex_exit(&fnp->fn_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   625
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   626
		 * auto_new_mount_thread fires up a new thread which
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   627
		 * calls automountd finishing up the work
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   628
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   629
		auto_new_mount_thread(fnp, searchnm, cred);
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
		 * At this point, we are simply another thread
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   633
		 * waiting for the mount to complete
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   634
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   635
		error = auto_wait4mount(fnp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   636
		if (error == AUTOFS_SHUTDOWN)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   637
			error = ENOENT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   638
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   639
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   640
		 * now release our reference to this vnode
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   641
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   642
		VN_RELE(fntovn(fnp));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   643
		if (!error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   644
			goto top;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   645
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   646
	default:
2170
eb691d2a219e PSARC 2005/714 Automounter Scalability Enhancements
evanl
parents: 1153
diff changeset
   647
		auto_log(dfnp->fn_globals->fng_verbose,
5302
eec6aeacde6e PSARC 2007/416 NFSv4 Mirror-mounts
th199096
parents: 4863
diff changeset
   648
		    dfnp->fn_globals->fng_zoneid, CE_WARN,
eec6aeacde6e PSARC 2007/416 NFSv4 Mirror-mounts
th199096
parents: 4863
diff changeset
   649
		    "auto_lookup: unknown operation %d",
eec6aeacde6e PSARC 2007/416 NFSv4 Mirror-mounts
th199096
parents: 4863
diff changeset
   650
		    operation);
0
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
	AUTOFS_DPRINT((5, "auto_lookup: name=%s *vpp=%p return=%d\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   654
	    nm, (void *)*vpp, error));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   655
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   656
	return (error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   657
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   658
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   659
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   660
auto_create(
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   661
	vnode_t *dvp,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   662
	char *nm,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   663
	vattr_t *va,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   664
	vcexcl_t excl,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   665
	int mode,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   666
	vnode_t **vpp,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   667
	cred_t *cred,
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   668
	int flag,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   669
	caller_context_t *ct,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   670
	vsecattr_t *vsecp)
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   671
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   672
	vnode_t *newvp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   673
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   674
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   675
	AUTOFS_DPRINT((4, "auto_create dvp %p nm %s\n", (void *)dvp, nm));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   676
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   677
	if (error = auto_trigger_mount(dvp, cred, &newvp))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   678
		goto done;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   679
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   680
	if (newvp != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   681
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   682
		 * Node is now mounted on.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   683
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   684
		if (vn_is_readonly(newvp))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   685
			error = EROFS;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   686
		else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   687
			error = VOP_CREATE(newvp, nm, va, excl,
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   688
			    mode, vpp, cred, flag, ct, vsecp);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   689
		VN_RELE(newvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   690
	} else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   691
		error = ENOSYS;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   692
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   693
done:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   694
	AUTOFS_DPRINT((5, "auto_create: error=%d\n", error));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   695
	return (error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   696
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   697
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   698
static int
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   699
auto_remove(
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   700
	vnode_t *dvp,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   701
	char *nm,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   702
	cred_t *cred,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   703
	caller_context_t *ct,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   704
	int flags)
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   705
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   706
	vnode_t *newvp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   707
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   708
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   709
	AUTOFS_DPRINT((4, "auto_remove dvp %p nm %s\n", (void *)dvp, nm));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   710
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   711
	if (error = auto_trigger_mount(dvp, cred, &newvp))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   712
		goto done;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   713
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   714
	if (newvp != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   715
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   716
		 * Node is now mounted on.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   717
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   718
		if (vn_is_readonly(newvp))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   719
			error = EROFS;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   720
		else
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   721
			error = VOP_REMOVE(newvp, nm, cred, ct, flags);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   722
		VN_RELE(newvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   723
	} else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   724
		error = ENOSYS;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   725
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   726
done:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   727
	AUTOFS_DPRINT((5, "auto_remove: error=%d\n", error));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   728
	return (error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   729
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   730
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   731
static int
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   732
auto_link(
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   733
	vnode_t *tdvp,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   734
	vnode_t *svp,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   735
	char *nm,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   736
	cred_t *cred,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   737
	caller_context_t *ct,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   738
	int flags)
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   739
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   740
	vnode_t *newvp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   741
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   742
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   743
	AUTOFS_DPRINT((4, "auto_link tdvp %p svp %p nm %s\n", (void *)tdvp,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   744
	    (void *)svp, nm));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   745
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   746
	if (error = auto_trigger_mount(tdvp, cred, &newvp))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   747
		goto done;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   748
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   749
	if (newvp == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   750
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   751
		 * an autonode can not be a link to another node
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   752
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   753
		error = ENOSYS;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   754
		goto done;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   755
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   756
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   757
	if (vn_is_readonly(newvp)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   758
		error = EROFS;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   759
		VN_RELE(newvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   760
		goto done;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   761
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   762
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   763
	if (vn_matchops(svp, auto_vnodeops)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   764
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   765
		 * source vp can't be an autonode
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   766
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   767
		error = ENOSYS;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   768
		VN_RELE(newvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   769
		goto done;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   770
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   771
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   772
	error = VOP_LINK(newvp, svp, nm, cred, ct, flags);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   773
	VN_RELE(newvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   774
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   775
done:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   776
	AUTOFS_DPRINT((5, "auto_link error=%d\n", error));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   777
	return (error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   778
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   779
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   780
static int
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   781
auto_rename(
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   782
	vnode_t *odvp,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   783
	char *onm,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   784
	vnode_t *ndvp,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   785
	char *nnm,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   786
	cred_t *cr,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   787
	caller_context_t *ct,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   788
	int flags)
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   789
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   790
	vnode_t *o_newvp, *n_newvp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   791
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   792
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   793
	AUTOFS_DPRINT((4, "auto_rename odvp %p onm %s to ndvp %p nnm %s\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   794
	    (void *)odvp, onm, (void *)ndvp, nnm));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   795
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   796
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   797
	 * we know odvp is an autonode, otherwise this function
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   798
	 * could not have ever been called.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   799
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   800
	ASSERT(vn_matchops(odvp, auto_vnodeops));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   801
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   802
	if (error = auto_trigger_mount(odvp, cr, &o_newvp))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   803
		goto done;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   804
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   805
	if (o_newvp == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   806
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   807
		 * can't rename an autonode
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   808
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   809
		error = ENOSYS;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   810
		goto done;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   811
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   812
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   813
	if (vn_matchops(ndvp, auto_vnodeops)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   814
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   815
		 * directory is AUTOFS, need to trigger the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   816
		 * mount of the real filesystem.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   817
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   818
		if (error = auto_trigger_mount(ndvp, cr, &n_newvp)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   819
			VN_RELE(o_newvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   820
			goto done;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   821
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   822
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   823
		if (n_newvp == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   824
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   825
			 * target can't be an autonode
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   826
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   827
			error = ENOSYS;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   828
			VN_RELE(o_newvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   829
			goto done;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   830
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   831
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   832
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   833
		 * destination directory mount had been
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   834
		 * triggered prior to the call to this function.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   835
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   836
		n_newvp = ndvp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   837
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   838
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   839
	ASSERT(!vn_matchops(n_newvp, auto_vnodeops));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   840
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   841
	if (vn_is_readonly(n_newvp)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   842
		error = EROFS;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   843
		VN_RELE(o_newvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   844
		if (n_newvp != ndvp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   845
			VN_RELE(n_newvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   846
		goto done;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   847
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   848
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   849
	error = VOP_RENAME(o_newvp, onm, n_newvp, nnm, cr, ct, flags);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   850
	VN_RELE(o_newvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   851
	if (n_newvp != ndvp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   852
		VN_RELE(n_newvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   853
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   854
done:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   855
	AUTOFS_DPRINT((5, "auto_rename error=%d\n", error));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   856
	return (error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   857
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   858
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   859
static int
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   860
auto_mkdir(
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   861
	vnode_t *dvp,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   862
	char *nm,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   863
	vattr_t *va,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   864
	vnode_t **vpp,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   865
	cred_t *cred,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   866
	caller_context_t *ct,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   867
	int flags,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   868
	vsecattr_t *vsecp)
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   869
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   870
	vnode_t *newvp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   871
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   872
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   873
	AUTOFS_DPRINT((4, "auto_mkdir dvp %p nm %s\n", (void *)dvp, nm));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   874
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   875
	if (error = auto_trigger_mount(dvp, cred, &newvp))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   876
		goto done;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   877
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   878
	if (newvp != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   879
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   880
		 * Node is now mounted on.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   881
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   882
		if (vn_is_readonly(newvp))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   883
			error = EROFS;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   884
		else
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   885
			error = VOP_MKDIR(newvp, nm, va, vpp, cred, ct,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   886
			    flags, vsecp);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   887
		VN_RELE(newvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   888
	} else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   889
		error = ENOSYS;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   890
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   891
done:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   892
	AUTOFS_DPRINT((5, "auto_mkdir: error=%d\n", error));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   893
	return (error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   894
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   895
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   896
static int
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   897
auto_rmdir(
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   898
	vnode_t *dvp,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   899
	char *nm,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   900
	vnode_t *cdir,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   901
	cred_t *cred,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   902
	caller_context_t *ct,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   903
	int flags)
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   904
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   905
	vnode_t *newvp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   906
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   907
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   908
	AUTOFS_DPRINT((4, "auto_rmdir: vp=%p nm=%s\n", (void *)dvp, nm));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   909
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   910
	if (error = auto_trigger_mount(dvp, cred, &newvp))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   911
		goto done;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   912
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   913
	if (newvp != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   914
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   915
		 * Node is now mounted on.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   916
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   917
		if (vn_is_readonly(newvp))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   918
			error = EROFS;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   919
		else
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   920
			error = VOP_RMDIR(newvp, nm, cdir, cred, ct, flags);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   921
		VN_RELE(newvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   922
	} else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   923
		error = ENOSYS;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   924
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   925
done:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   926
	AUTOFS_DPRINT((5, "auto_rmdir: error=%d\n", error));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   927
	return (error);
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
static int autofs_nobrowse = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   931
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   932
#ifdef nextdp
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   933
#undef nextdp
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   934
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   935
#define	nextdp(dp)	((struct dirent64 *)((char *)(dp) + (dp)->d_reclen))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   936
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   937
/* ARGSUSED */
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   938
static int
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   939
auto_readdir(
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   940
	vnode_t *vp,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   941
	uio_t *uiop,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   942
	cred_t *cred,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   943
	int *eofp,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   944
	caller_context_t *ct,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   945
	int flags)
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   946
{
2170
eb691d2a219e PSARC 2005/714 Automounter Scalability Enhancements
evanl
parents: 1153
diff changeset
   947
	struct autofs_rddirargs	rda;
eb691d2a219e PSARC 2005/714 Automounter Scalability Enhancements
evanl
parents: 1153
diff changeset
   948
	autofs_rddirres rd;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   949
	fnnode_t *fnp = vntofn(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   950
	fnnode_t *cfnp, *nfnp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   951
	dirent64_t *dp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   952
	ulong_t offset;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   953
	ulong_t outcount = 0, count = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   954
	size_t namelen;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   955
	ulong_t alloc_count;
2170
eb691d2a219e PSARC 2005/714 Automounter Scalability Enhancements
evanl
parents: 1153
diff changeset
   956
	void *outbuf = NULL;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   957
	fninfo_t *fnip = vfstofni(vp->v_vfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   958
	struct iovec *iovp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   959
	int error = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   960
	int reached_max = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   961
	int myeof = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   962
	int this_reclen;
2170
eb691d2a219e PSARC 2005/714 Automounter Scalability Enhancements
evanl
parents: 1153
diff changeset
   963
	struct autofs_globals *fngp = vntofn(fnip->fi_rootvp)->fn_globals;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   964
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   965
	AUTOFS_DPRINT((4, "auto_readdir vp=%p offset=%lld\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   966
	    (void *)vp, uiop->uio_loffset));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   967
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   968
	if (eofp != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   969
		*eofp = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   970
2170
eb691d2a219e PSARC 2005/714 Automounter Scalability Enhancements
evanl
parents: 1153
diff changeset
   971
	if (uiop->uio_iovcnt != 1)
eb691d2a219e PSARC 2005/714 Automounter Scalability Enhancements
evanl
parents: 1153
diff changeset
   972
		return (EINVAL);
eb691d2a219e PSARC 2005/714 Automounter Scalability Enhancements
evanl
parents: 1153
diff changeset
   973
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   974
	iovp = uiop->uio_iov;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   975
	alloc_count = iovp->iov_len;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   976
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   977
	gethrestime(&fnp->fn_atime);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   978
	fnp->fn_ref_time = fnp->fn_atime.tv_sec;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   979
2170
eb691d2a219e PSARC 2005/714 Automounter Scalability Enhancements
evanl
parents: 1153
diff changeset
   980
	dp = outbuf = kmem_zalloc(alloc_count, KM_SLEEP);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   981
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   982
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   983
	 * Held when getdents calls VOP_RWLOCK....
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   984
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   985
	ASSERT(RW_READ_HELD(&fnp->fn_rwlock));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   986
	if (uiop->uio_offset >= AUTOFS_DAEMONCOOKIE) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   987
again:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   988
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   989
		 * Do readdir of daemon contents only
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   990
		 * Drop readers lock and reacquire after reply.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   991
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   992
		rw_exit(&fnp->fn_rwlock);
2170
eb691d2a219e PSARC 2005/714 Automounter Scalability Enhancements
evanl
parents: 1153
diff changeset
   993
		bzero(&rd, sizeof (struct autofs_rddirres));
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   994
		count = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   995
		rda.rda_map = fnip->fi_map;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   996
		rda.rda_offset = (uint_t)uiop->uio_offset;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   997
		rd.rd_rddir.rddir_entries = dp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   998
		rda.rda_count = rd.rd_rddir.rddir_size = (uint_t)alloc_count;
3391
2e4fef544e31 6266812 pam_krb5 and pam_krb5_migrate localize their syslog messages
semery
parents: 2170
diff changeset
   999
		rda.uid = crgetuid(cred);
2170
eb691d2a219e PSARC 2005/714 Automounter Scalability Enhancements
evanl
parents: 1153
diff changeset
  1000
eb691d2a219e PSARC 2005/714 Automounter Scalability Enhancements
evanl
parents: 1153
diff changeset
  1001
		error = auto_calldaemon(fngp->fng_zoneid,
5302
eec6aeacde6e PSARC 2007/416 NFSv4 Mirror-mounts
th199096
parents: 4863
diff changeset
  1002
		    AUTOFS_READDIR,
eec6aeacde6e PSARC 2007/416 NFSv4 Mirror-mounts
th199096
parents: 4863
diff changeset
  1003
		    xdr_autofs_rddirargs,
eec6aeacde6e PSARC 2007/416 NFSv4 Mirror-mounts
th199096
parents: 4863
diff changeset
  1004
		    &rda,
eec6aeacde6e PSARC 2007/416 NFSv4 Mirror-mounts
th199096
parents: 4863
diff changeset
  1005
		    xdr_autofs_rddirres,
eec6aeacde6e PSARC 2007/416 NFSv4 Mirror-mounts
th199096
parents: 4863
diff changeset
  1006
		    (void *)&rd,
eec6aeacde6e PSARC 2007/416 NFSv4 Mirror-mounts
th199096
parents: 4863
diff changeset
  1007
		    sizeof (autofs_rddirres),
eec6aeacde6e PSARC 2007/416 NFSv4 Mirror-mounts
th199096
parents: 4863
diff changeset
  1008
		    TRUE);
2170
eb691d2a219e PSARC 2005/714 Automounter Scalability Enhancements
evanl
parents: 1153
diff changeset
  1009
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1010
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1011
		 * reacquire previously dropped lock
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1012
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1013
		rw_enter(&fnp->fn_rwlock, RW_READER);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1014
2170
eb691d2a219e PSARC 2005/714 Automounter Scalability Enhancements
evanl
parents: 1153
diff changeset
  1015
		if (!error) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1016
			error = rd.rd_status;
2170
eb691d2a219e PSARC 2005/714 Automounter Scalability Enhancements
evanl
parents: 1153
diff changeset
  1017
			dp = rd.rd_rddir.rddir_entries;
eb691d2a219e PSARC 2005/714 Automounter Scalability Enhancements
evanl
parents: 1153
diff changeset
  1018
		}
eb691d2a219e PSARC 2005/714 Automounter Scalability Enhancements
evanl
parents: 1153
diff changeset
  1019
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1020
		if (error) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1021
			if (error == AUTOFS_SHUTDOWN) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1022
				/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1023
				 * treat as empty directory
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1024
				 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1025
				error = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1026
				myeof = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1027
				if (eofp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1028
					*eofp = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1029
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1030
			goto done;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1031
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1032
		if (rd.rd_rddir.rddir_size) {
2170
eb691d2a219e PSARC 2005/714 Automounter Scalability Enhancements
evanl
parents: 1153
diff changeset
  1033
			dirent64_t *odp = dp;   /* next in output buffer */
eb691d2a219e PSARC 2005/714 Automounter Scalability Enhancements
evanl
parents: 1153
diff changeset
  1034
			dirent64_t *cdp = dp;   /* current examined entry */
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1035
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1036
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1037
			 * Check for duplicates here
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1038
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1039
			do {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1040
				this_reclen = cdp->d_reclen;
2170
eb691d2a219e PSARC 2005/714 Automounter Scalability Enhancements
evanl
parents: 1153
diff changeset
  1041
				if (auto_search(fnp, cdp->d_name,
5302
eec6aeacde6e PSARC 2007/416 NFSv4 Mirror-mounts
th199096
parents: 4863
diff changeset
  1042
				    NULL, cred)) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1043
					/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1044
					 * entry not found in kernel list,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1045
					 * include it in readdir output.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1046
					 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1047
					 * If we are skipping entries. then
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1048
					 * we need to copy this entry to the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1049
					 * correct position in the buffer
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1050
					 * to be copied out.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1051
					 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1052
					if (cdp != odp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1053
						bcopy(cdp, odp,
5302
eec6aeacde6e PSARC 2007/416 NFSv4 Mirror-mounts
th199096
parents: 4863
diff changeset
  1054
						    (size_t)this_reclen);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1055
					odp = nextdp(odp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1056
					outcount += this_reclen;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1057
				} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1058
					/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1059
					 * Entry was found in the kernel
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1060
					 * list. If it is the first entry
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1061
					 * in this buffer, then just skip it
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1062
					 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1063
					if (odp == dp) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1064
						dp = nextdp(dp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1065
						odp = dp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1066
					}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1067
				}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1068
				count += this_reclen;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1069
				cdp = (struct dirent64 *)
5302
eec6aeacde6e PSARC 2007/416 NFSv4 Mirror-mounts
th199096
parents: 4863
diff changeset
  1070
				    ((char *)cdp + this_reclen);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1071
			} while (count < rd.rd_rddir.rddir_size);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1072
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1073
			if (outcount)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1074
				error = uiomove(dp, outcount, UIO_READ, uiop);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1075
			uiop->uio_offset = rd.rd_rddir.rddir_offset;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1076
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1077
			if (rd.rd_rddir.rddir_eof == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1078
				/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1079
				 * alloc_count not large enough for one
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1080
				 * directory entry
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1081
				 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1082
				error = EINVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1083
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1084
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1085
		if (rd.rd_rddir.rddir_eof && !error) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1086
			myeof = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1087
			if (eofp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1088
				*eofp = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1089
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1090
		if (!error && !myeof && outcount == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1091
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1092
			 * call daemon with new cookie, all previous
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1093
			 * elements happened to be duplicates
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1094
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1095
			dp = outbuf;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1096
			goto again;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1097
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1098
		goto done;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1099
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1100
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1101
	if (uiop->uio_offset == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1102
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1103
		 * first time: so fudge the . and ..
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1104
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1105
		this_reclen = DIRENT64_RECLEN(1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1106
		if (alloc_count < this_reclen) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1107
			error = EINVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1108
			goto done;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1109
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1110
		dp->d_ino = (ino64_t)fnp->fn_nodeid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1111
		dp->d_off = (off64_t)1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1112
		dp->d_reclen = (ushort_t)this_reclen;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1113
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1114
		/* use strncpy(9f) to zero out uninitialized bytes */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1115
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1116
		(void) strncpy(dp->d_name, ".",
5302
eec6aeacde6e PSARC 2007/416 NFSv4 Mirror-mounts
th199096
parents: 4863
diff changeset
  1117
		    DIRENT64_NAMELEN(this_reclen));
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1118
		outcount += dp->d_reclen;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1119
		dp = nextdp(dp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1120
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1121
		this_reclen = DIRENT64_RECLEN(2);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1122
		if (alloc_count < outcount + this_reclen) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1123
			error = EINVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1124
			goto done;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1125
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1126
		dp->d_reclen = (ushort_t)this_reclen;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1127
		dp->d_ino = (ino64_t)fnp->fn_parent->fn_nodeid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1128
		dp->d_off = (off64_t)2;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1129
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1130
		/* use strncpy(9f) to zero out uninitialized bytes */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1131
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1132
		(void) strncpy(dp->d_name, "..",
5302
eec6aeacde6e PSARC 2007/416 NFSv4 Mirror-mounts
th199096
parents: 4863
diff changeset
  1133
		    DIRENT64_NAMELEN(this_reclen));
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1134
		outcount += dp->d_reclen;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1135
		dp = nextdp(dp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1136
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1137
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1138
	offset = 2;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1139
	cfnp = fnp->fn_dirents;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1140
	while (cfnp != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1141
		nfnp = cfnp->fn_next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1142
		offset = cfnp->fn_offset;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1143
		if ((offset >= uiop->uio_offset) &&
5302
eec6aeacde6e PSARC 2007/416 NFSv4 Mirror-mounts
th199096
parents: 4863
diff changeset
  1144
		    (!(cfnp->fn_flags & MF_LOOKUP))) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1145
			int reclen;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1146
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1147
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1148
			 * include node only if its offset is greater or
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1149
			 * equal to the one required and it is not in
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1150
			 * transient state (not being looked-up)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1151
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1152
			namelen = strlen(cfnp->fn_name);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1153
			reclen = (int)DIRENT64_RECLEN(namelen);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1154
			if (outcount + reclen > alloc_count) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1155
				reached_max = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1156
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1157
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1158
			dp->d_reclen = (ushort_t)reclen;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1159
			dp->d_ino = (ino64_t)cfnp->fn_nodeid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1160
			if (nfnp != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1161
				/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1162
				 * get the offset of the next element
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1163
				 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1164
				dp->d_off = (off64_t)nfnp->fn_offset;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1165
			} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1166
				/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1167
				 * This is the last element, make
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1168
				 * offset one plus the current
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1169
				 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1170
				dp->d_off = (off64_t)cfnp->fn_offset + 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1171
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1172
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1173
			/* use strncpy(9f) to zero out uninitialized bytes */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1174
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1175
			(void) strncpy(dp->d_name, cfnp->fn_name,
5302
eec6aeacde6e PSARC 2007/416 NFSv4 Mirror-mounts
th199096
parents: 4863
diff changeset
  1176
			    DIRENT64_NAMELEN(reclen));
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1177
			outcount += dp->d_reclen;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1178
			dp = nextdp(dp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1179
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1180
		cfnp = nfnp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1181
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1182
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1183
	if (outcount)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1184
		error = uiomove(outbuf, outcount, UIO_READ, uiop);
5302
eec6aeacde6e PSARC 2007/416 NFSv4 Mirror-mounts
th199096
parents: 4863
diff changeset
  1185
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1186
	if (!error) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1187
		if (reached_max) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1188
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1189
			 * This entry did not get added to the buffer on this,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1190
			 * call. We need to add it on the next call therefore
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1191
			 * set uio_offset to this entry's offset.  If there
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1192
			 * wasn't enough space for one dirent, return EINVAL.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1193
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1194
			uiop->uio_offset = offset;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1195
			if (outcount == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1196
				error = EINVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1197
		} else if (autofs_nobrowse ||
5302
eec6aeacde6e PSARC 2007/416 NFSv4 Mirror-mounts
th199096
parents: 4863
diff changeset
  1198
		    auto_nobrowse_option(fnip->fi_opts) ||
eec6aeacde6e PSARC 2007/416 NFSv4 Mirror-mounts
th199096
parents: 4863
diff changeset
  1199
		    (fnip->fi_flags & MF_DIRECT) ||
eec6aeacde6e PSARC 2007/416 NFSv4 Mirror-mounts
th199096
parents: 4863
diff changeset
  1200
		    (fnp->fn_trigger != NULL) ||
eec6aeacde6e PSARC 2007/416 NFSv4 Mirror-mounts
th199096
parents: 4863
diff changeset
  1201
		    (((vp->v_flag & VROOT) == 0) &&
eec6aeacde6e PSARC 2007/416 NFSv4 Mirror-mounts
th199096
parents: 4863
diff changeset
  1202
		    ((fntovn(fnp->fn_parent))->v_flag & VROOT) &&
eec6aeacde6e PSARC 2007/416 NFSv4 Mirror-mounts
th199096
parents: 4863
diff changeset
  1203
		    (fnp->fn_dirents == NULL))) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1204
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1205
			 * done reading directory entries
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1206
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1207
			uiop->uio_offset = offset + 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1208
			if (eofp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1209
				*eofp = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1210
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1211
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1212
			 * Need to get the rest of the entries from the daemon.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1213
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1214
			uiop->uio_offset = AUTOFS_DAEMONCOOKIE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1215
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1216
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1217
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1218
done:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1219
	kmem_free(outbuf, alloc_count);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1220
	AUTOFS_DPRINT((5, "auto_readdir vp=%p offset=%lld eof=%d\n",
5302
eec6aeacde6e PSARC 2007/416 NFSv4 Mirror-mounts
th199096
parents: 4863
diff changeset
  1221
	    (void *)vp, uiop->uio_loffset, myeof));
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1222
	return (error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1223
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1224
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1225
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1226
auto_symlink(
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1227
	vnode_t *dvp,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1228
	char *lnknm,		/* new entry */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1229
	vattr_t *tva,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1230
	char *tnm,		/* existing entry */
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  1231
	cred_t *cred,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  1232
	caller_context_t *ct,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  1233
	int flags)
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1234
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1235
	vnode_t *newvp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1236
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1237
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1238
	AUTOFS_DPRINT((4, "auto_symlink: dvp=%p lnknm=%s tnm=%s\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1239
	    (void *)dvp, lnknm, tnm));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1240
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1241
	if (error = auto_trigger_mount(dvp, cred, &newvp))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1242
		goto done;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1243
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1244
	if (newvp != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1245
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1246
		 * Node is mounted on.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1247
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1248
		if (vn_is_readonly(newvp))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1249
			error = EROFS;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1250
		else
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  1251
			error = VOP_SYMLINK(newvp, lnknm, tva, tnm, cred,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  1252
			    ct, flags);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1253
		VN_RELE(newvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1254
	} else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1255
		error = ENOSYS;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1256
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1257
done:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1258
	AUTOFS_DPRINT((5, "auto_symlink: error=%d\n", error));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1259
	return (error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1260
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1261
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1262
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1263
static int
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  1264
auto_readlink(vnode_t *vp, struct uio *uiop, cred_t *cr, caller_context_t *ct)
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1265
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1266
	fnnode_t *fnp = vntofn(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1267
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1268
	timestruc_t now;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1269
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1270
	AUTOFS_DPRINT((4, "auto_readlink: vp=%p\n", (void *)vp));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1271
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1272
	gethrestime(&now);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1273
	fnp->fn_ref_time = now.tv_sec;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1274
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1275
	if (vp->v_type != VLNK)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1276
		error = EINVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1277
	else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1278
		ASSERT(!(fnp->fn_flags & (MF_INPROG | MF_LOOKUP)));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1279
		fnp->fn_atime = now;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1280
		error = uiomove(fnp->fn_symlink, MIN(fnp->fn_symlinklen,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1281
		    uiop->uio_resid), UIO_READ, uiop);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1282
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1283
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1284
	AUTOFS_DPRINT((5, "auto_readlink: error=%d\n", error));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1285
	return (error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1286
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1287
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1288
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1289
static int
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  1290
auto_fsync(vnode_t *cp, int syncflag, cred_t *cred, caller_context_t *ct)
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1291
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1292
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1293
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1294
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1295
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1296
static void
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  1297
auto_inactive(vnode_t *vp, cred_t *cred, caller_context_t *ct)
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1298
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1299
	fnnode_t *fnp = vntofn(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1300
	fnnode_t *dfnp = fnp->fn_parent;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1301
	int count;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1302
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1303
	AUTOFS_DPRINT((4, "auto_inactive: vp=%p v_count=%u fn_link=%d\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1304
	    (void *)vp, vp->v_count, fnp->fn_linkcnt));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1305
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1306
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1307
	 * The rwlock should not be already held by this thread.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1308
	 * The assert relies on the fact that the owner field is cleared
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1309
	 * when the lock is released.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1310
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1311
	ASSERT(dfnp != NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1312
	ASSERT(rw_owner(&dfnp->fn_rwlock) != curthread);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1313
	rw_enter(&dfnp->fn_rwlock, RW_WRITER);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1314
	mutex_enter(&vp->v_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1315
	ASSERT(vp->v_count > 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1316
	count = --vp->v_count;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1317
	mutex_exit(&vp->v_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1318
	if (count == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1319
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1320
		 * Free only if node has no subdirectories.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1321
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1322
		if (fnp->fn_linkcnt == 1) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1323
			auto_disconnect(dfnp, fnp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1324
			rw_exit(&dfnp->fn_rwlock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1325
			auto_freefnnode(fnp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1326
			AUTOFS_DPRINT((5, "auto_inactive: (exit) vp=%p freed\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1327
			    (void *)vp));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1328
			return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1329
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1330
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1331
	rw_exit(&dfnp->fn_rwlock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1332
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1333
	AUTOFS_DPRINT((5, "auto_inactive: (exit) vp=%p v_count=%u fn_link=%d\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1334
	    (void *)vp, vp->v_count, fnp->fn_linkcnt));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1335
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1336
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1337
/* ARGSUSED2 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1338
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1339
auto_rwlock(vnode_t *vp, int write_lock, caller_context_t *ct)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1340
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1341
	fnnode_t *fnp = vntofn(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1342
	if (write_lock)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1343
		rw_enter(&fnp->fn_rwlock, RW_WRITER);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1344
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1345
		rw_enter(&fnp->fn_rwlock, RW_READER);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1346
	return (write_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1347
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1348
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1349
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1350
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1351
auto_rwunlock(vnode_t *vp, int write_lock, caller_context_t *ct)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1352
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1353
	fnnode_t *fnp = vntofn(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1354
	rw_exit(&fnp->fn_rwlock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1355
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1356
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1357
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1358
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1359
static int
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  1360
auto_seek(
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  1361
	struct vnode *vp,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  1362
	offset_t ooff,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  1363
	offset_t *noffp,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  1364
	caller_context_t *ct)
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1365
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1366
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1367
	 * Return 0 unconditionally, since we expect
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1368
	 * a VDIR all the time
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1369
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1370
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1371
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1372
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1373
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1374
 * Triggers the mount if needed. If the mount has been triggered by
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1375
 * another thread, it will wait for its return status, and return it.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1376
 * Whether the mount is triggered by this thread, another thread, or
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1377
 * if the vnode was already covered, '*newvp' is a
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1378
 * VN_HELD vnode pointing to the root of the filesystem covering 'vp'.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1379
 * If the node is not mounted on, and should not be mounted on, '*newvp'
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1380
 * will be NULL.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1381
 * The calling routine may use '*newvp' to do the filesystem jump.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1382
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1383
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1384
auto_trigger_mount(vnode_t *vp, cred_t *cred, vnode_t **newvp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1385
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1386
	fnnode_t *fnp = vntofn(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1387
	fninfo_t *fnip = vfstofni(vp->v_vfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1388
	vnode_t *dvp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1389
	vfs_t *vfsp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1390
	int delayed_ind;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1391
	char name[AUTOFS_MAXPATHLEN];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1392
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1393
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1394
	AUTOFS_DPRINT((4, "auto_trigger_mount: vp=%p\n", (void *)vp));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1395
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1396
	*newvp = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1397
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1398
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1399
	 * Cross-zone mount triggering is disallowed.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1400
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1401
	if (fnip->fi_zoneid != getzoneid())
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1402
		return (EPERM);	/* Not owner of mount */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1403
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1404
retry:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1405
	error = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1406
	delayed_ind = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1407
	mutex_enter(&fnp->fn_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1408
	while (fnp->fn_flags & (MF_LOOKUP | MF_INPROG)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1409
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1410
		 * Mount or lookup in progress,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1411
		 * wait for it before proceeding.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1412
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1413
		mutex_exit(&fnp->fn_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1414
		error = auto_wait4mount(fnp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1415
		if (error == AUTOFS_SHUTDOWN) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1416
			error = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1417
			goto done;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1418
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1419
		if (error && error != EAGAIN)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1420
			goto done;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1421
		error = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1422
		mutex_enter(&fnp->fn_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1423
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1424
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1425
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1426
	 * If the vfslock can't be acquired for the first time.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1427
	 * drop the fn_lock and retry next time in blocking mode.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1428
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1429
	if (vn_vfswlock(vp)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1430
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1431
		 * Lock held by another thread.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1432
		 * Perform blocking by dropping the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1433
		 * fn_lock.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1434
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1435
		mutex_exit(&fnp->fn_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1436
		error = vn_vfswlock_wait(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1437
		if (error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1438
			goto done;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1439
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1440
		 * Because fn_lock wasn't held, the state
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1441
		 * of the trigger node might have changed.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1442
		 * Need to run through the checks on trigger
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1443
		 * node again.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1444
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1445
		vn_vfsunlock(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1446
		goto retry;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1447
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1448
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1449
	vfsp = vn_mountedvfs(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1450
	if (vfsp != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1451
		mutex_exit(&fnp->fn_lock);
1153
b0029fa0379d 4845430 heavy lookup on autofs mountpoints can introduce scalability issues.
nr123932
parents: 149
diff changeset
  1452
		error = VFS_ROOT(vfsp, newvp);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1453
		vn_vfsunlock(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1454
		goto done;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1455
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1456
		vn_vfsunlock(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1457
		if ((fnp->fn_flags & MF_MOUNTPOINT) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1458
		    fnp->fn_trigger != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1459
			ASSERT(fnp->fn_dirents == NULL);
12184
0216e4439444 6864918 S10 auto_direct takes 45 mins to remount after manually unmounted a directory vs. S8 instantly
Jan Kryl <Jan.Kryl@Sun.COM>
parents: 5331
diff changeset
  1460
			mutex_exit(&fnp->fn_lock);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1461
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1462
			 * The filesystem that used to sit here has been
12184
0216e4439444 6864918 S10 auto_direct takes 45 mins to remount after manually unmounted a directory vs. S8 instantly
Jan Kryl <Jan.Kryl@Sun.COM>
parents: 5331
diff changeset
  1463
			 * forcibly unmounted. Do our best to recover.
0216e4439444 6864918 S10 auto_direct takes 45 mins to remount after manually unmounted a directory vs. S8 instantly
Jan Kryl <Jan.Kryl@Sun.COM>
parents: 5331
diff changeset
  1464
			 * Try to unmount autofs subtree below this node
0216e4439444 6864918 S10 auto_direct takes 45 mins to remount after manually unmounted a directory vs. S8 instantly
Jan Kryl <Jan.Kryl@Sun.COM>
parents: 5331
diff changeset
  1465
			 * and retry the action.
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1466
			 */
12184
0216e4439444 6864918 S10 auto_direct takes 45 mins to remount after manually unmounted a directory vs. S8 instantly
Jan Kryl <Jan.Kryl@Sun.COM>
parents: 5331
diff changeset
  1467
			if (unmount_subtree(fnp, B_TRUE) != 0) {
0216e4439444 6864918 S10 auto_direct takes 45 mins to remount after manually unmounted a directory vs. S8 instantly
Jan Kryl <Jan.Kryl@Sun.COM>
parents: 5331
diff changeset
  1468
				error = EIO;
0216e4439444 6864918 S10 auto_direct takes 45 mins to remount after manually unmounted a directory vs. S8 instantly
Jan Kryl <Jan.Kryl@Sun.COM>
parents: 5331
diff changeset
  1469
				goto done;
0216e4439444 6864918 S10 auto_direct takes 45 mins to remount after manually unmounted a directory vs. S8 instantly
Jan Kryl <Jan.Kryl@Sun.COM>
parents: 5331
diff changeset
  1470
			}
0216e4439444 6864918 S10 auto_direct takes 45 mins to remount after manually unmounted a directory vs. S8 instantly
Jan Kryl <Jan.Kryl@Sun.COM>
parents: 5331
diff changeset
  1471
			goto retry;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1472
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1473
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1474
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1475
	ASSERT(vp->v_type == VDIR);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1476
	dvp = fntovn(fnp->fn_parent);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1477
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1478
	if ((fnp->fn_dirents == NULL) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1479
	    ((fnip->fi_flags & MF_DIRECT) == 0) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1480
	    ((vp->v_flag & VROOT) == 0) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1481
	    (dvp->v_flag & VROOT)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1482
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1483
		 * If the parent of this node is the root of an indirect
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1484
		 * AUTOFS filesystem, this node is remountable.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1485
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1486
		delayed_ind = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1487
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1488
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1489
	if (delayed_ind ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1490
	    ((fnip->fi_flags & MF_DIRECT) && (fnp->fn_dirents == NULL))) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1491
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1492
		 * Trigger mount since:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1493
		 * direct mountpoint with no subdirs or
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1494
		 * delayed indirect.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1495
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1496
		AUTOFS_BLOCK_OTHERS(fnp, MF_INPROG);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1497
		fnp->fn_error = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1498
		mutex_exit(&fnp->fn_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1499
		if (delayed_ind)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1500
			(void) strcpy(name, fnp->fn_name);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1501
		else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1502
			(void) strcpy(name, ".");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1503
		fnp->fn_ref_time = gethrestime_sec();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1504
		auto_new_mount_thread(fnp, name, cred);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1505
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1506
		 * At this point we're simply another thread waiting
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1507
		 * for the mount to finish.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1508
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1509
		error = auto_wait4mount(fnp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1510
		if (error == EAGAIN)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1511
			goto retry;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1512
		if (error == AUTOFS_SHUTDOWN) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1513
			error = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1514
			goto done;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1515
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1516
		if (error == 0) {
1153
b0029fa0379d 4845430 heavy lookup on autofs mountpoints can introduce scalability issues.
nr123932
parents: 149
diff changeset
  1517
			if (error = vn_vfsrlock_wait(vp))
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1518
				goto done;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1519
			/* Reacquire after dropping locks */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1520
			vfsp = vn_mountedvfs(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1521
			if (vfsp != NULL) {
1153
b0029fa0379d 4845430 heavy lookup on autofs mountpoints can introduce scalability issues.
nr123932
parents: 149
diff changeset
  1522
				error = VFS_ROOT(vfsp, newvp);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1523
				vn_vfsunlock(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1524
			} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1525
				vn_vfsunlock(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1526
				goto retry;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1527
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1528
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1529
	} else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1530
		mutex_exit(&fnp->fn_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1531
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1532
done:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1533
	AUTOFS_DPRINT((5, "auto_trigger_mount: error=%d\n", error));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1534
	return (error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1535
}