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