usr/src/uts/common/fs/vfs.c
author llai1
Fri, 25 Aug 2006 17:24:25 -0700
changeset 2621 4ea88858d952
parent 1925 91047fd43318
child 3446 5903aece022d
permissions -rw-r--r--
PSARC/2003/246 Filesystem Driven Device Naming 5050715 logical device names not created during early boot 6292952 devfsadm mishandles optarg 6362924 devfsadm secondary link generation is not zones aware 6413127 Integrate the Devname Project 6464196 bfu should remove pt_chmod, obsoleted by /dev filesystem
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     1
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     2
 * CDDL HEADER START
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     3
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     4
 * The contents of this file are subject to the terms of the
1488
196daa2cf3db PSARC/2006/034 fsstat
rsb
parents: 994
diff changeset
     5
 * Common Development and Distribution License (the "License").
196daa2cf3db PSARC/2006/034 fsstat
rsb
parents: 994
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
/*
1488
196daa2cf3db PSARC/2006/034 fsstat
rsb
parents: 994
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
/*	Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T	*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    27
/*	  All Rights Reserved  	*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    28
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    29
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    30
 * University Copyright- Copyright (c) 1982, 1986, 1988
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    31
 * The Regents of the University of California
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    32
 * All Rights Reserved
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    33
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    34
 * University Acknowledgment- Portions of this document are derived from
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    35
 * software developed by the University of California, Berkeley, and its
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    36
 * contributors.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    37
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    38
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    39
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    40
#pragma ident	"%Z%%M%	%I%	%E% SMI"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    41
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    42
#include <sys/types.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    43
#include <sys/t_lock.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    44
#include <sys/param.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    45
#include <sys/errno.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    46
#include <sys/user.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    47
#include <sys/fstyp.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    48
#include <sys/kmem.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    49
#include <sys/systm.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    50
#include <sys/proc.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    51
#include <sys/mount.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    52
#include <sys/vfs.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    53
#include <sys/fem.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    54
#include <sys/mntent.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    55
#include <sys/stat.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    56
#include <sys/statvfs.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    57
#include <sys/statfs.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    58
#include <sys/cred.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    59
#include <sys/vnode.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    60
#include <sys/rwstlock.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    61
#include <sys/dnlc.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    62
#include <sys/file.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    63
#include <sys/time.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    64
#include <sys/atomic.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    65
#include <sys/cmn_err.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    66
#include <sys/buf.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    67
#include <sys/swap.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    68
#include <sys/debug.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    69
#include <sys/vnode.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    70
#include <sys/modctl.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    71
#include <sys/ddi.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    72
#include <sys/pathname.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    73
#include <sys/bootconf.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    74
#include <sys/dumphdr.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    75
#include <sys/dc_ki.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    76
#include <sys/poll.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    77
#include <sys/sunddi.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    78
#include <sys/sysmacros.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    79
#include <sys/zone.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    80
#include <sys/policy.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    81
#include <sys/ctfs.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    82
#include <sys/objfs.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    83
#include <sys/console.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    84
#include <sys/reboot.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    85
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    86
#include <vm/page.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    87
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    88
#include <fs/fs_subr.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    89
1520
2fb01d86c1c1 6391295 fop_create() panic when running svvs over ZFS
rsb
parents: 1488
diff changeset
    90
/* Private interfaces to create vopstats-related data structures */
2fb01d86c1c1 6391295 fop_create() panic when running svvs over ZFS
rsb
parents: 1488
diff changeset
    91
extern void		initialize_vopstats(vopstats_t *);
2fb01d86c1c1 6391295 fop_create() panic when running svvs over ZFS
rsb
parents: 1488
diff changeset
    92
extern vopstats_t	*get_fstype_vopstats(struct vfs *, struct vfssw *);
2fb01d86c1c1 6391295 fop_create() panic when running svvs over ZFS
rsb
parents: 1488
diff changeset
    93
extern vsk_anchor_t	*get_vskstat_anchor(struct vfs *);
2fb01d86c1c1 6391295 fop_create() panic when running svvs over ZFS
rsb
parents: 1488
diff changeset
    94
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    95
static void vfs_clearmntopt_nolock(mntopts_t *, const char *, int);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    96
static void vfs_setmntopt_nolock(mntopts_t *, const char *,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    97
    const char *, int, int);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    98
static int  vfs_optionisset_nolock(const mntopts_t *, const char *, char **);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    99
static void vfs_freemnttab(struct vfs *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   100
static void vfs_freeopt(mntopt_t *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   101
static void vfs_swapopttbl_nolock(mntopts_t *, mntopts_t *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   102
static void vfs_swapopttbl(mntopts_t *, mntopts_t *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   103
static void vfs_copyopttbl_extend(const mntopts_t *, mntopts_t *, int);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   104
static void vfs_createopttbl_extend(mntopts_t *, const char *,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   105
    const mntopts_t *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   106
static char **vfs_copycancelopt_extend(char **const, int);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   107
static void vfs_freecancelopt(char **);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   108
static char *getrootfs(void);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   109
static int getmacpath(dev_info_t *, void *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   110
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   111
struct ipmnt {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   112
	struct ipmnt	*mip_next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   113
	dev_t		mip_dev;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   114
	struct vfs	*mip_vfsp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   115
};
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   116
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   117
static kmutex_t		vfs_miplist_mutex;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   118
static struct ipmnt	*vfs_miplist = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   119
static struct ipmnt	*vfs_miplist_end = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   120
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   121
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   122
 * VFS global data.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   123
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   124
vnode_t *rootdir;		/* pointer to root inode vnode. */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   125
vnode_t *devicesdir;		/* pointer to inode of devices root */
2621
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   126
vnode_t	*devdir;		/* pointer to inode of dev root */
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   127
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   128
char *server_rootpath;		/* root path for diskless clients */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   129
char *server_hostname;		/* hostname of diskless server */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   130
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   131
static struct vfs root;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   132
static struct vfs devices;
2621
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   133
static struct vfs dev;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   134
struct vfs *rootvfs = &root;	/* pointer to root vfs; head of VFS list. */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   135
rvfs_t *rvfs_list;		/* array of vfs ptrs for vfs hash list */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   136
int vfshsz = 512;		/* # of heads/locks in vfs hash arrays */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   137
				/* must be power of 2!	*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   138
timespec_t vfs_mnttab_ctime;	/* mnttab created time */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   139
timespec_t vfs_mnttab_mtime;	/* mnttab last modified time */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   140
char *vfs_dummyfstype = "\0";
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   141
struct pollhead vfs_pollhd;	/* for mnttab pollers */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   142
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   143
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   144
 * Table for generic options recognized in the VFS layer and acted
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   145
 * on at this level before parsing file system specific options.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   146
 * The nosuid option is stronger than any of the devices and setuid
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   147
 * options, so those are canceled when nosuid is seen.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   148
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   149
 * All options which are added here need to be added to the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   150
 * list of standard options in usr/src/cmd/fs.d/fslib.c as well.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   151
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   152
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   153
 * VFS Mount options table
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   154
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   155
static char *ro_cancel[] = { MNTOPT_RW, NULL };
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   156
static char *rw_cancel[] = { MNTOPT_RO, NULL };
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   157
static char *suid_cancel[] = { MNTOPT_NOSUID, NULL };
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   158
static char *nosuid_cancel[] = { MNTOPT_SUID, MNTOPT_DEVICES, MNTOPT_NODEVICES,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   159
    MNTOPT_NOSETUID, MNTOPT_SETUID, NULL };
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   160
static char *devices_cancel[] = { MNTOPT_NODEVICES, NULL };
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   161
static char *nodevices_cancel[] = { MNTOPT_DEVICES, NULL };
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   162
static char *setuid_cancel[] = { MNTOPT_NOSETUID, NULL };
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   163
static char *nosetuid_cancel[] = { MNTOPT_SETUID, NULL };
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   164
static char *nbmand_cancel[] = { MNTOPT_NONBMAND, NULL };
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   165
static char *nonbmand_cancel[] = { MNTOPT_NBMAND, NULL };
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   166
static char *exec_cancel[] = { MNTOPT_NOEXEC, NULL };
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   167
static char *noexec_cancel[] = { MNTOPT_EXEC, NULL };
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   168
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   169
static const mntopt_t mntopts[] = {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   170
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   171
 *	option name		cancel options		default arg	flags
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   172
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   173
	{ MNTOPT_REMOUNT,	NULL,			NULL,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   174
		MO_NODISPLAY, (void *)0 },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   175
	{ MNTOPT_RO,		ro_cancel,		NULL,		0,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   176
		(void *)0 },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   177
	{ MNTOPT_RW,		rw_cancel,		NULL,		0,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   178
		(void *)0 },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   179
	{ MNTOPT_SUID,		suid_cancel,		NULL,		0,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   180
		(void *)0 },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   181
	{ MNTOPT_NOSUID,	nosuid_cancel,		NULL,		0,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   182
		(void *)0 },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   183
	{ MNTOPT_DEVICES,	devices_cancel,		NULL,		0,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   184
		(void *)0 },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   185
	{ MNTOPT_NODEVICES,	nodevices_cancel,	NULL,		0,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   186
		(void *)0 },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   187
	{ MNTOPT_SETUID,	setuid_cancel,		NULL,		0,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   188
		(void *)0 },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   189
	{ MNTOPT_NOSETUID,	nosetuid_cancel,	NULL,		0,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   190
		(void *)0 },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   191
	{ MNTOPT_NBMAND,	nbmand_cancel,		NULL,		0,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   192
		(void *)0 },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   193
	{ MNTOPT_NONBMAND,	nonbmand_cancel,	NULL,		0,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   194
		(void *)0 },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   195
	{ MNTOPT_EXEC,		exec_cancel,		NULL,		0,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   196
		(void *)0 },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   197
	{ MNTOPT_NOEXEC,	noexec_cancel,		NULL,		0,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   198
		(void *)0 },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   199
};
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   200
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   201
const mntopts_t vfs_mntopts = {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   202
	sizeof (mntopts) / sizeof (mntopt_t),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   203
	(mntopt_t *)&mntopts[0]
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   204
};
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   205
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   206
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   207
 * File system operation dispatch functions.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   208
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   209
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   210
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   211
fsop_mount(vfs_t *vfsp, vnode_t *mvp, struct mounta *uap, cred_t *cr)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   212
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   213
	return (*(vfsp)->vfs_op->vfs_mount)(vfsp, mvp, uap, cr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   214
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   215
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   216
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   217
fsop_unmount(vfs_t *vfsp, int flag, cred_t *cr)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   218
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   219
	return (*(vfsp)->vfs_op->vfs_unmount)(vfsp, flag, cr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   220
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   221
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   222
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   223
fsop_root(vfs_t *vfsp, vnode_t **vpp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   224
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   225
	refstr_t *mntpt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   226
	int ret = (*(vfsp)->vfs_op->vfs_root)(vfsp, vpp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   227
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   228
	 * Make sure this root has a path.  With lofs, it is possible to have
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   229
	 * a NULL mountpoint.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   230
	 */
254
349581d9fc98 6175313 io provider exposes our reluctance to set vnode paths
eschrock
parents: 0
diff changeset
   231
	if (ret == 0 && vfsp->vfs_mntpt != NULL && (*vpp)->v_path == NULL) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   232
		mntpt = vfs_getmntpoint(vfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   233
		vn_setpath_str(*vpp, refstr_value(mntpt),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   234
		    strlen(refstr_value(mntpt)));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   235
		refstr_rele(mntpt);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   236
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   237
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   238
	return (ret);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   239
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   240
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   241
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   242
fsop_statfs(vfs_t *vfsp, statvfs64_t *sp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   243
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   244
	return (*(vfsp)->vfs_op->vfs_statvfs)(vfsp, sp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   245
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   246
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   247
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   248
fsop_sync(vfs_t *vfsp, short flag, cred_t *cr)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   249
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   250
	return (*(vfsp)->vfs_op->vfs_sync)(vfsp, flag, cr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   251
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   252
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   253
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   254
fsop_vget(vfs_t *vfsp, vnode_t **vpp, fid_t *fidp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   255
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   256
	return (*(vfsp)->vfs_op->vfs_vget)(vfsp, vpp, fidp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   257
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   258
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   259
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   260
fsop_mountroot(vfs_t *vfsp, enum whymountroot reason)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   261
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   262
	return (*(vfsp)->vfs_op->vfs_mountroot)(vfsp, reason);
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
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   266
fsop_freefs(vfs_t *vfsp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   267
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   268
	(*(vfsp)->vfs_op->vfs_freevfs)(vfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   269
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   270
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   271
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   272
fsop_vnstate(vfs_t *vfsp, vnode_t *vp, vntrans_t nstate)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   273
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   274
	return ((*(vfsp)->vfs_op->vfs_vnstate)(vfsp, vp, nstate));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   275
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   276
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   277
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   278
fsop_sync_by_kind(int fstype, short flag, cred_t *cr)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   279
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   280
	ASSERT((fstype >= 0) && (fstype < nfstype));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   281
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   282
	if (ALLOCATED_VFSSW(&vfssw[fstype]) && VFS_INSTALLED(&vfssw[fstype]))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   283
		return (*vfssw[fstype].vsw_vfsops.vfs_sync) (NULL, flag, cr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   284
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   285
		return (ENOTSUP);
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
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   289
 * File system initialization.  vfs_setfsops() must be called from a file
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   290
 * system's init routine.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   291
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   292
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   293
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   294
fs_copyfsops(const fs_operation_def_t *template, vfsops_t *actual,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   295
    int *unused_ops)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   296
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   297
	static const fs_operation_trans_def_t vfs_ops_table[] = {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   298
		VFSNAME_MOUNT, offsetof(vfsops_t, vfs_mount),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   299
			fs_nosys, fs_nosys,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   300
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   301
		VFSNAME_UNMOUNT, offsetof(vfsops_t, vfs_unmount),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   302
			fs_nosys, fs_nosys,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   303
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   304
		VFSNAME_ROOT, offsetof(vfsops_t, vfs_root),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   305
			fs_nosys, fs_nosys,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   306
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   307
		VFSNAME_STATVFS, offsetof(vfsops_t, vfs_statvfs),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   308
			fs_nosys, fs_nosys,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   309
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   310
		VFSNAME_SYNC, offsetof(vfsops_t, vfs_sync),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   311
			(fs_generic_func_p) fs_sync,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   312
			(fs_generic_func_p) fs_sync,	/* No errors allowed */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   313
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   314
		VFSNAME_VGET, offsetof(vfsops_t, vfs_vget),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   315
			fs_nosys, fs_nosys,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   316
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   317
		VFSNAME_MOUNTROOT, offsetof(vfsops_t, vfs_mountroot),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   318
			fs_nosys, fs_nosys,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   319
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   320
		VFSNAME_FREEVFS, offsetof(vfsops_t, vfs_freevfs),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   321
			(fs_generic_func_p)fs_freevfs,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   322
			(fs_generic_func_p)fs_freevfs,	/* Shouldn't fail */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   323
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   324
		VFSNAME_VNSTATE, offsetof(vfsops_t, vfs_vnstate),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   325
			(fs_generic_func_p)fs_nosys,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   326
			(fs_generic_func_p)fs_nosys,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   327
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   328
		NULL, 0, NULL, NULL
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   329
	};
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   330
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   331
	return (fs_build_vector(actual, unused_ops, vfs_ops_table, template));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   332
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   333
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   334
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   335
vfs_setfsops(int fstype, const fs_operation_def_t *template, vfsops_t **actual)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   336
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   337
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   338
	int unused_ops;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   339
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   340
	/* Verify that fstype refers to a loaded fs (and not fsid 0). */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   341
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   342
	if ((fstype <= 0) || (fstype >= nfstype))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   343
		return (EINVAL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   344
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   345
	if (!ALLOCATED_VFSSW(&vfssw[fstype]))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   346
		return (EINVAL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   347
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   348
	/* Set up the operations vector. */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   349
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   350
	error = fs_copyfsops(template, &vfssw[fstype].vsw_vfsops, &unused_ops);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   351
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   352
	if (error != 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   353
		return (error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   354
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   355
	vfssw[fstype].vsw_flag |= VSW_INSTALLED;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   356
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   357
	if (actual != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   358
		*actual = &vfssw[fstype].vsw_vfsops;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   359
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   360
#if DEBUG
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   361
	if (unused_ops != 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   362
		cmn_err(CE_WARN, "vfs_setfsops: %s: %d operations supplied "
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   363
		    "but not used", vfssw[fstype].vsw_name, unused_ops);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   364
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   365
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   366
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   367
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   368
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   369
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   370
vfs_makefsops(const fs_operation_def_t *template, vfsops_t **actual)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   371
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   372
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   373
	int unused_ops;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   374
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   375
	*actual = (vfsops_t *)kmem_alloc(sizeof (vfsops_t), KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   376
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   377
	error = fs_copyfsops(template, *actual, &unused_ops);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   378
	if (error != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   379
		kmem_free(*actual, sizeof (vfsops_t));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   380
		*actual = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   381
		return (error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   382
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   383
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   384
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   385
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   386
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   387
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   388
 * Free a vfsops structure created as a result of vfs_makefsops().
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   389
 * NOTE: For a vfsops structure initialized by vfs_setfsops(), use
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   390
 * vfs_freevfsops_by_type().
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   391
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   392
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   393
vfs_freevfsops(vfsops_t *vfsops)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   394
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   395
	kmem_free(vfsops, sizeof (vfsops_t));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   396
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   397
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   398
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   399
 * Since the vfsops structure is part of the vfssw table and wasn't
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   400
 * really allocated, we're not really freeing anything.  We keep
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   401
 * the name for consistency with vfs_freevfsops().  We do, however,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   402
 * need to take care of a little bookkeeping.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   403
 * NOTE: For a vfsops structure created by vfs_setfsops(), use
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   404
 * vfs_freevfsops_by_type().
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   405
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   406
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   407
vfs_freevfsops_by_type(int fstype)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   408
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   409
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   410
	/* Verify that fstype refers to a loaded fs (and not fsid 0). */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   411
	if ((fstype <= 0) || (fstype >= nfstype))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   412
		return (EINVAL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   413
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   414
	WLOCK_VFSSW();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   415
	if ((vfssw[fstype].vsw_flag & VSW_INSTALLED) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   416
		WUNLOCK_VFSSW();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   417
		return (EINVAL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   418
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   419
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   420
	vfssw[fstype].vsw_flag &= ~VSW_INSTALLED;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   421
	WUNLOCK_VFSSW();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   422
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   423
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   424
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   425
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   426
/* Support routines used to reference vfs_op */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   427
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   428
/* Set the operations vector for a vfs */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   429
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   430
vfs_setops(vfs_t *vfsp, vfsops_t *vfsops)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   431
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   432
	vfsops_t	*op;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   433
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   434
	ASSERT(vfsp != NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   435
	ASSERT(vfsops != NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   436
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   437
	op = vfsp->vfs_op;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   438
	membar_consumer();
1925
91047fd43318 PSARC 2006/270 vfs_femhead change to vfs_implp
rsb
parents: 1678
diff changeset
   439
	if ((vfsp->vfs_implp == NULL || vfsp->vfs_femhead == NULL) &&
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   440
	    casptr(&vfsp->vfs_op, op, vfsops) == op) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   441
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   442
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   443
	fsem_setvfsops(vfsp, vfsops);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   444
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   445
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   446
/* Retrieve the operations vector for a vfs */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   447
vfsops_t *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   448
vfs_getops(vfs_t *vfsp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   449
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   450
	vfsops_t	*op;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   451
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   452
	ASSERT(vfsp != NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   453
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   454
	op = vfsp->vfs_op;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   455
	membar_consumer();
1925
91047fd43318 PSARC 2006/270 vfs_femhead change to vfs_implp
rsb
parents: 1678
diff changeset
   456
	if ((vfsp->vfs_implp == NULL || vfsp->vfs_femhead == NULL) &&
91047fd43318 PSARC 2006/270 vfs_femhead change to vfs_implp
rsb
parents: 1678
diff changeset
   457
	    op == vfsp->vfs_op) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   458
		return (op);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   459
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   460
		return (fsem_getvfsops(vfsp));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   461
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   462
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   463
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   464
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   465
 * Returns non-zero (1) if the vfsops matches that of the vfs.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   466
 * Returns zero (0) if not.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   467
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   468
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   469
vfs_matchops(vfs_t *vfsp, vfsops_t *vfsops)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   470
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   471
	return (vfs_getops(vfsp) == vfsops);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   472
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   473
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   474
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   475
 * Returns non-zero (1) if the file system has installed a non-default,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   476
 * non-error vfs_sync routine.  Returns zero (0) otherwise.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   477
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   478
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   479
vfs_can_sync(vfs_t *vfsp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   480
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   481
	/* vfs_sync() routine is not the default/error function */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   482
	return (vfs_getops(vfsp)->vfs_sync != fs_sync);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   483
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   484
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   485
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   486
 * Initialize a vfs structure.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   487
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   488
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   489
vfs_init(vfs_t *vfsp, vfsops_t *op, void *data)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   490
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   491
	vfsp->vfs_count = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   492
	vfsp->vfs_next = vfsp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   493
	vfsp->vfs_prev = vfsp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   494
	vfsp->vfs_zone_next = vfsp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   495
	vfsp->vfs_zone_prev = vfsp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   496
	vfsp->vfs_flag = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   497
	vfsp->vfs_data = (data);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   498
	vfsp->vfs_resource = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   499
	vfsp->vfs_mntpt = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   500
	vfsp->vfs_mntopts.mo_count = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   501
	vfsp->vfs_mntopts.mo_list = NULL;
1925
91047fd43318 PSARC 2006/270 vfs_femhead change to vfs_implp
rsb
parents: 1678
diff changeset
   502
	vfsp->vfs_implp = NULL;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   503
	vfsp->vfs_zone = NULL;
1488
196daa2cf3db PSARC/2006/034 fsstat
rsb
parents: 994
diff changeset
   504
	/*
1925
91047fd43318 PSARC 2006/270 vfs_femhead change to vfs_implp
rsb
parents: 1678
diff changeset
   505
	 * Note: Don't initialize any member of the vfs_impl_t structure
91047fd43318 PSARC 2006/270 vfs_femhead change to vfs_implp
rsb
parents: 1678
diff changeset
   506
	 * here as it could be a problem for unbundled file systems.
1488
196daa2cf3db PSARC/2006/034 fsstat
rsb
parents: 994
diff changeset
   507
	 */
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   508
	vfs_setops((vfsp), (op));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   509
	sema_init(&vfsp->vfs_reflock, 1, NULL, SEMA_DEFAULT, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   510
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   511
1925
91047fd43318 PSARC 2006/270 vfs_femhead change to vfs_implp
rsb
parents: 1678
diff changeset
   512
/*
91047fd43318 PSARC 2006/270 vfs_femhead change to vfs_implp
rsb
parents: 1678
diff changeset
   513
 * Allocate and initialize the vfs implementation private data
91047fd43318 PSARC 2006/270 vfs_femhead change to vfs_implp
rsb
parents: 1678
diff changeset
   514
 * structure, vfs_impl_t.
91047fd43318 PSARC 2006/270 vfs_femhead change to vfs_implp
rsb
parents: 1678
diff changeset
   515
 */
91047fd43318 PSARC 2006/270 vfs_femhead change to vfs_implp
rsb
parents: 1678
diff changeset
   516
void
91047fd43318 PSARC 2006/270 vfs_femhead change to vfs_implp
rsb
parents: 1678
diff changeset
   517
vfsimpl_setup(vfs_t *vfsp)
91047fd43318 PSARC 2006/270 vfs_femhead change to vfs_implp
rsb
parents: 1678
diff changeset
   518
{
91047fd43318 PSARC 2006/270 vfs_femhead change to vfs_implp
rsb
parents: 1678
diff changeset
   519
	vfsp->vfs_implp = kmem_alloc(sizeof (vfs_impl_t), KM_SLEEP);
91047fd43318 PSARC 2006/270 vfs_femhead change to vfs_implp
rsb
parents: 1678
diff changeset
   520
	/* Note that this are #define'd in vfs.h */
91047fd43318 PSARC 2006/270 vfs_femhead change to vfs_implp
rsb
parents: 1678
diff changeset
   521
	vfsp->vfs_femhead = NULL;
91047fd43318 PSARC 2006/270 vfs_femhead change to vfs_implp
rsb
parents: 1678
diff changeset
   522
	vfsp->vfs_vskap = NULL;
91047fd43318 PSARC 2006/270 vfs_femhead change to vfs_implp
rsb
parents: 1678
diff changeset
   523
	vfsp->vfs_fstypevsp = NULL;
91047fd43318 PSARC 2006/270 vfs_femhead change to vfs_implp
rsb
parents: 1678
diff changeset
   524
}
91047fd43318 PSARC 2006/270 vfs_femhead change to vfs_implp
rsb
parents: 1678
diff changeset
   525
91047fd43318 PSARC 2006/270 vfs_femhead change to vfs_implp
rsb
parents: 1678
diff changeset
   526
/*
91047fd43318 PSARC 2006/270 vfs_femhead change to vfs_implp
rsb
parents: 1678
diff changeset
   527
 * Release the vfs_impl_t structure, if it exists. Some unbundled
91047fd43318 PSARC 2006/270 vfs_femhead change to vfs_implp
rsb
parents: 1678
diff changeset
   528
 * filesystems may not use the newer version of vfs and thus
91047fd43318 PSARC 2006/270 vfs_femhead change to vfs_implp
rsb
parents: 1678
diff changeset
   529
 * would not contain this implementation private data structure.
91047fd43318 PSARC 2006/270 vfs_femhead change to vfs_implp
rsb
parents: 1678
diff changeset
   530
 */
91047fd43318 PSARC 2006/270 vfs_femhead change to vfs_implp
rsb
parents: 1678
diff changeset
   531
void
91047fd43318 PSARC 2006/270 vfs_femhead change to vfs_implp
rsb
parents: 1678
diff changeset
   532
vfsimpl_teardown(vfs_t *vfsp)
91047fd43318 PSARC 2006/270 vfs_femhead change to vfs_implp
rsb
parents: 1678
diff changeset
   533
{
91047fd43318 PSARC 2006/270 vfs_femhead change to vfs_implp
rsb
parents: 1678
diff changeset
   534
	vfs_impl_t	*vip = vfsp->vfs_implp;
91047fd43318 PSARC 2006/270 vfs_femhead change to vfs_implp
rsb
parents: 1678
diff changeset
   535
91047fd43318 PSARC 2006/270 vfs_femhead change to vfs_implp
rsb
parents: 1678
diff changeset
   536
	if (vip == NULL)
91047fd43318 PSARC 2006/270 vfs_femhead change to vfs_implp
rsb
parents: 1678
diff changeset
   537
		return;
91047fd43318 PSARC 2006/270 vfs_femhead change to vfs_implp
rsb
parents: 1678
diff changeset
   538
91047fd43318 PSARC 2006/270 vfs_femhead change to vfs_implp
rsb
parents: 1678
diff changeset
   539
	if (vip->vi_femhead) {
91047fd43318 PSARC 2006/270 vfs_femhead change to vfs_implp
rsb
parents: 1678
diff changeset
   540
		ASSERT(vip->vi_femhead->femh_list == NULL);
91047fd43318 PSARC 2006/270 vfs_femhead change to vfs_implp
rsb
parents: 1678
diff changeset
   541
		mutex_destroy(&vip->vi_femhead->femh_lock);
91047fd43318 PSARC 2006/270 vfs_femhead change to vfs_implp
rsb
parents: 1678
diff changeset
   542
		kmem_free(vip->vi_femhead, sizeof (*(vip->vi_femhead)));
91047fd43318 PSARC 2006/270 vfs_femhead change to vfs_implp
rsb
parents: 1678
diff changeset
   543
		vip->vi_femhead = NULL;
91047fd43318 PSARC 2006/270 vfs_femhead change to vfs_implp
rsb
parents: 1678
diff changeset
   544
	}
91047fd43318 PSARC 2006/270 vfs_femhead change to vfs_implp
rsb
parents: 1678
diff changeset
   545
91047fd43318 PSARC 2006/270 vfs_femhead change to vfs_implp
rsb
parents: 1678
diff changeset
   546
	kmem_free(vfsp->vfs_implp, sizeof (vfs_impl_t));
91047fd43318 PSARC 2006/270 vfs_femhead change to vfs_implp
rsb
parents: 1678
diff changeset
   547
	vfsp->vfs_implp = NULL;
91047fd43318 PSARC 2006/270 vfs_femhead change to vfs_implp
rsb
parents: 1678
diff changeset
   548
}
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   549
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   550
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   551
 * VFS system calls: mount, umount, syssync, statfs, fstatfs, statvfs,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   552
 * fstatvfs, and sysfs moved to common/syscall.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   553
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   554
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   555
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   556
 * Update every mounted file system.  We call the vfs_sync operation of
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   557
 * each file system type, passing it a NULL vfsp to indicate that all
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   558
 * mounted file systems of that type should be updated.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   559
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   560
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   561
vfs_sync(int flag)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   562
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   563
	struct vfssw *vswp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   564
	RLOCK_VFSSW();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   565
	for (vswp = &vfssw[1]; vswp < &vfssw[nfstype]; vswp++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   566
		if (ALLOCATED_VFSSW(vswp) && VFS_INSTALLED(vswp)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   567
			vfs_refvfssw(vswp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   568
			RUNLOCK_VFSSW();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   569
			(void) (*vswp->vsw_vfsops.vfs_sync)(NULL, flag,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   570
			    CRED());
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   571
			vfs_unrefvfssw(vswp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   572
			RLOCK_VFSSW();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   573
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   574
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   575
	RUNLOCK_VFSSW();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   576
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   577
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   578
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   579
sync(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   580
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   581
	vfs_sync(0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   582
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   583
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   584
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   585
 * External routines.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   586
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   587
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   588
krwlock_t vfssw_lock;	/* lock accesses to vfssw */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   589
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   590
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   591
 * Lock for accessing the vfs linked list.  Initialized in vfs_mountroot(),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   592
 * but otherwise should be accessed only via vfs_list_lock() and
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   593
 * vfs_list_unlock().  Also used to protect the timestamp for mods to the list.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   594
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   595
static krwlock_t vfslist;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   596
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   597
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   598
 * Mount devfs on /devices. This is done right after root is mounted
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   599
 * to provide device access support for the system
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   600
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   601
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   602
vfs_mountdevices(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   603
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   604
	struct vfssw *vsw;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   605
	struct vnode *mvp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   606
	struct mounta mounta = {	/* fake mounta for devfs_mount() */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   607
		NULL,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   608
		NULL,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   609
		MS_SYSSPACE,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   610
		NULL,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   611
		NULL,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   612
		0,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   613
		NULL,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   614
		0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   615
	};
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   616
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   617
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   618
	 * _init devfs module to fill in the vfssw
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   619
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   620
	if (modload("fs", "devfs") == -1)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   621
		cmn_err(CE_PANIC, "Cannot _init devfs module\n");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   622
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   623
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   624
	 * Hold vfs
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   625
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   626
	RLOCK_VFSSW();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   627
	vsw = vfs_getvfsswbyname("devfs");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   628
	VFS_INIT(&devices, &vsw->vsw_vfsops, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   629
	VFS_HOLD(&devices);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   630
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   631
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   632
	 * Locate mount point
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   633
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   634
	if (lookupname("/devices", UIO_SYSSPACE, FOLLOW, NULLVPP, &mvp))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   635
		cmn_err(CE_PANIC, "Cannot find /devices\n");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   636
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   637
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   638
	 * Perform the mount of /devices
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   639
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   640
	if (VFS_MOUNT(&devices, mvp, &mounta, CRED()))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   641
		cmn_err(CE_PANIC, "Cannot mount /devices\n");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   642
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   643
	RUNLOCK_VFSSW();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   644
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   645
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   646
	 * Set appropriate members and add to vfs list for mnttab display
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   647
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   648
	vfs_setresource(&devices, "/devices");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   649
	vfs_setmntpoint(&devices, "/devices");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   650
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   651
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   652
	 * Hold the root of /devices so it won't go away
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   653
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   654
	if (VFS_ROOT(&devices, &devicesdir))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   655
		cmn_err(CE_PANIC, "vfs_mountdevices: not devices root");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   656
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   657
	if (vfs_lock(&devices) != 0) {
2621
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   658
		VN_RELE(devicesdir);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   659
		cmn_err(CE_NOTE, "Cannot acquire vfs_lock of /devices");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   660
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   661
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   662
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   663
	if (vn_vfswlock(mvp) != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   664
		vfs_unlock(&devices);
2621
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   665
		VN_RELE(devicesdir);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   666
		cmn_err(CE_NOTE, "Cannot acquire vfswlock of /devices");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   667
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   668
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   669
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   670
	vfs_add(mvp, &devices, 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   671
	vn_vfsunlock(mvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   672
	vfs_unlock(&devices);
2621
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   673
	VN_RELE(devicesdir);
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   674
}
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   675
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   676
/*
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   677
 * mount the first instance of /dev  to root and remain mounted
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   678
 */
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   679
static void
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   680
vfs_mountdev1(void)
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   681
{
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   682
	struct vfssw *vsw;
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   683
	struct vnode *mvp;
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   684
	struct mounta mounta = {	/* fake mounta for sdev_mount() */
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   685
		NULL,
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   686
		NULL,
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   687
		MS_SYSSPACE | MS_OVERLAY,
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   688
		NULL,
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   689
		NULL,
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   690
		0,
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   691
		NULL,
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   692
		0
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   693
	};
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   694
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   695
	/*
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   696
	 * _init dev module to fill in the vfssw
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   697
	 */
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   698
	if (modload("fs", "dev") == -1)
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   699
		cmn_err(CE_PANIC, "Cannot _init dev module\n");
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   700
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   701
	/*
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   702
	 * Hold vfs
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   703
	 */
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   704
	RLOCK_VFSSW();
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   705
	vsw = vfs_getvfsswbyname("dev");
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   706
	VFS_INIT(&dev, &vsw->vsw_vfsops, NULL);
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   707
	VFS_HOLD(&dev);
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   708
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   709
	/*
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   710
	 * Locate mount point
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   711
	 */
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   712
	if (lookupname("/dev", UIO_SYSSPACE, FOLLOW, NULLVPP, &mvp))
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   713
		cmn_err(CE_PANIC, "Cannot find /dev\n");
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   714
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   715
	/*
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   716
	 * Perform the mount of /dev
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   717
	 */
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   718
	if (VFS_MOUNT(&dev, mvp, &mounta, CRED()))
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   719
		cmn_err(CE_PANIC, "Cannot mount /dev 1\n");
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   720
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   721
	RUNLOCK_VFSSW();
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   722
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   723
	/*
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   724
	 * Set appropriate members and add to vfs list for mnttab display
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   725
	 */
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   726
	vfs_setresource(&dev, "/dev");
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   727
	vfs_setmntpoint(&dev, "/dev");
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   728
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   729
	/*
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   730
	 * Hold the root of /dev so it won't go away
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   731
	 */
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   732
	if (VFS_ROOT(&dev, &devdir))
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   733
		cmn_err(CE_PANIC, "vfs_mountdev1: not dev root");
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   734
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   735
	if (vfs_lock(&dev) != 0) {
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   736
		VN_RELE(devdir);
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   737
		cmn_err(CE_NOTE, "Cannot acquire vfs_lock of /dev");
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   738
		return;
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   739
	}
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   740
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   741
	if (vn_vfswlock(mvp) != 0) {
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   742
		vfs_unlock(&dev);
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   743
		VN_RELE(devdir);
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   744
		cmn_err(CE_NOTE, "Cannot acquire vfswlock of /dev");
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   745
		return;
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   746
	}
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   747
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   748
	vfs_add(mvp, &dev, 0);
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   749
	vn_vfsunlock(mvp);
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   750
	vfs_unlock(&dev);
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   751
	VN_RELE(devdir);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   752
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   753
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   754
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   755
 * Mount required filesystem. This is done right after root is mounted.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   756
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   757
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   758
vfs_mountfs(char *module, char *spec, char *path)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   759
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   760
	struct vnode *mvp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   761
	struct mounta mounta;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   762
	vfs_t *vfsp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   763
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   764
	mounta.flags = MS_SYSSPACE | MS_DATA;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   765
	mounta.fstype = module;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   766
	mounta.spec = spec;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   767
	mounta.dir = path;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   768
	if (lookupname(path, UIO_SYSSPACE, FOLLOW, NULLVPP, &mvp)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   769
		cmn_err(CE_WARN, "Cannot find %s\n", path);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   770
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   771
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   772
	if (domount(NULL, &mounta, mvp, CRED(), &vfsp))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   773
		cmn_err(CE_WARN, "Cannot mount %s\n", path);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   774
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   775
		VFS_RELE(vfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   776
	VN_RELE(mvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   777
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   778
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   779
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   780
 * vfs_mountroot is called by main() to mount the root filesystem.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   781
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   782
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   783
vfs_mountroot(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   784
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   785
	struct vnode	*rvp = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   786
	char		*path;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   787
	size_t		plen;
1488
196daa2cf3db PSARC/2006/034 fsstat
rsb
parents: 994
diff changeset
   788
	struct vfssw	*vswp;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   789
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   790
	rw_init(&vfssw_lock, NULL, RW_DEFAULT, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   791
	rw_init(&vfslist, NULL, RW_DEFAULT, NULL);
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
	 * Alloc the vfs hash bucket array and locks
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   795
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   796
	rvfs_list = kmem_zalloc(vfshsz * sizeof (rvfs_t), KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   797
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   798
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   799
	 * Call machine-dependent routine "rootconf" to choose a root
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   800
	 * file system type.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   801
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   802
	if (rootconf())
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   803
		cmn_err(CE_PANIC, "vfs_mountroot: cannot mount root");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   804
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   805
	 * Get vnode for '/'.  Set up rootdir, u.u_rdir and u.u_cdir
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   806
	 * to point to it.  These are used by lookuppn() so that it
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   807
	 * knows where to start from ('/' or '.').
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   808
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   809
	vfs_setmntpoint(rootvfs, "/");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   810
	if (VFS_ROOT(rootvfs, &rootdir))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   811
		cmn_err(CE_PANIC, "vfs_mountroot: no root vnode");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   812
	u.u_cdir = rootdir;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   813
	VN_HOLD(u.u_cdir);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   814
	u.u_rdir = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   815
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   816
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   817
	 * Setup the global zone's rootvp, now that it exists.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   818
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   819
	global_zone->zone_rootvp = rootdir;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   820
	VN_HOLD(global_zone->zone_rootvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   821
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   822
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   823
	 * Notify the module code that it can begin using the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   824
	 * root filesystem instead of the boot program's services.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   825
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   826
	modrootloaded = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   827
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   828
	 * Set up mnttab information for root
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   829
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   830
	vfs_setresource(rootvfs, rootfs.bo_name);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   831
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   832
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   833
	 * Notify cluster software that the root filesystem is available.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   834
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   835
	clboot_mountroot();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   836
1488
196daa2cf3db PSARC/2006/034 fsstat
rsb
parents: 994
diff changeset
   837
	/* Now that we're all done with the root FS, set up its vopstats */
196daa2cf3db PSARC/2006/034 fsstat
rsb
parents: 994
diff changeset
   838
	if ((vswp = vfs_getvfsswbyvfsops(vfs_getops(rootvfs))) != NULL) {
196daa2cf3db PSARC/2006/034 fsstat
rsb
parents: 994
diff changeset
   839
		/* Set flag for statistics collection */
196daa2cf3db PSARC/2006/034 fsstat
rsb
parents: 994
diff changeset
   840
		if (vswp->vsw_flag & VSW_STATS) {
1520
2fb01d86c1c1 6391295 fop_create() panic when running svvs over ZFS
rsb
parents: 1488
diff changeset
   841
			initialize_vopstats(&rootvfs->vfs_vopstats);
1488
196daa2cf3db PSARC/2006/034 fsstat
rsb
parents: 994
diff changeset
   842
			rootvfs->vfs_flag |= VFS_STATS;
1520
2fb01d86c1c1 6391295 fop_create() panic when running svvs over ZFS
rsb
parents: 1488
diff changeset
   843
			rootvfs->vfs_fstypevsp =
2fb01d86c1c1 6391295 fop_create() panic when running svvs over ZFS
rsb
parents: 1488
diff changeset
   844
			    get_fstype_vopstats(rootvfs, vswp);
2fb01d86c1c1 6391295 fop_create() panic when running svvs over ZFS
rsb
parents: 1488
diff changeset
   845
			rootvfs->vfs_vskap = get_vskstat_anchor(rootvfs);
1488
196daa2cf3db PSARC/2006/034 fsstat
rsb
parents: 994
diff changeset
   846
		}
196daa2cf3db PSARC/2006/034 fsstat
rsb
parents: 994
diff changeset
   847
		vfs_unrefvfssw(vswp);
196daa2cf3db PSARC/2006/034 fsstat
rsb
parents: 994
diff changeset
   848
	}
196daa2cf3db PSARC/2006/034 fsstat
rsb
parents: 994
diff changeset
   849
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   850
	/*
2621
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   851
	 * Mount /devices, /dev instance 1, /system/contract, /etc/mnttab,
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   852
	 * /etc/svc/volatile, /system/object, and /proc.
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   853
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   854
	vfs_mountdevices();
2621
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   855
	vfs_mountdev1();
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   856
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   857
	vfs_mountfs("ctfs", "ctfs", CTFS_ROOT);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   858
	vfs_mountfs("proc", "/proc", "/proc");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   859
	vfs_mountfs("mntfs", "/etc/mnttab", "/etc/mnttab");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   860
	vfs_mountfs("tmpfs", "/etc/svc/volatile", "/etc/svc/volatile");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   861
	vfs_mountfs("objfs", "objfs", OBJFS_ROOT);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   862
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   863
#ifdef __sparc
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   864
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   865
	 * This bit of magic can go away when we convert sparc to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   866
	 * the new boot architecture based on ramdisk.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   867
	 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   868
	 * Booting off a mirrored root volume:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   869
	 * At this point, we have booted and mounted root on a
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   870
	 * single component of the mirror.  Complete the boot
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   871
	 * by configuring SVM and converting the root to the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   872
	 * dev_t of the mirrored root device.  This dev_t conversion
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   873
	 * only works because the underlying device doesn't change.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   874
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   875
	if (root_is_svm) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   876
		if (svm_rootconf()) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   877
			cmn_err(CE_PANIC, "vfs_mountroot: cannot remount root");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   878
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   879
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   880
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   881
		 * mnttab should reflect the new root device
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   882
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   883
		vfs_lock_wait(rootvfs);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   884
		vfs_setresource(rootvfs, rootfs.bo_name);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   885
		vfs_unlock(rootvfs);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   886
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   887
#endif /* __sparc */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   888
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   889
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   890
	 * Look up the root device via devfs so that a dv_node is
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   891
	 * created for it. The vnode is never VN_RELE()ed.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   892
	 * We allocate more than MAXPATHLEN so that the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   893
	 * buffer passed to i_ddi_prompath_to_devfspath() is
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   894
	 * exactly MAXPATHLEN (the function expects a buffer
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   895
	 * of that length).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   896
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   897
	plen = strlen("/devices");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   898
	path = kmem_alloc(plen + MAXPATHLEN, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   899
	(void) strcpy(path, "/devices");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   900
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   901
	if (i_ddi_prompath_to_devfspath(rootfs.bo_name, path + plen)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   902
	    != DDI_SUCCESS ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   903
	    lookupname(path, UIO_SYSSPACE, FOLLOW, NULLVPP, &rvp)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   904
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   905
		/* NUL terminate in case "path" has garbage */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   906
		path[plen + MAXPATHLEN - 1] = '\0';
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   907
#ifdef	DEBUG
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   908
		cmn_err(CE_WARN, "!Cannot lookup root device: %s", path);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   909
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   910
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   911
	kmem_free(path, plen + MAXPATHLEN);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   912
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   913
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   914
/*
994
83b8875ae3f3 6256783 /etc/mnttab gets screwed-up when an unprivileged user tries to remount in a local zone
evanl
parents: 254
diff changeset
   915
 * If remount failed and we're in a zone we need to check for the zone
83b8875ae3f3 6256783 /etc/mnttab gets screwed-up when an unprivileged user tries to remount in a local zone
evanl
parents: 254
diff changeset
   916
 * root path and strip it before the call to vfs_setpath().
83b8875ae3f3 6256783 /etc/mnttab gets screwed-up when an unprivileged user tries to remount in a local zone
evanl
parents: 254
diff changeset
   917
 *
83b8875ae3f3 6256783 /etc/mnttab gets screwed-up when an unprivileged user tries to remount in a local zone
evanl
parents: 254
diff changeset
   918
 * If strpath doesn't begin with the zone_rootpath the original
83b8875ae3f3 6256783 /etc/mnttab gets screwed-up when an unprivileged user tries to remount in a local zone
evanl
parents: 254
diff changeset
   919
 * strpath is returned unchanged.
83b8875ae3f3 6256783 /etc/mnttab gets screwed-up when an unprivileged user tries to remount in a local zone
evanl
parents: 254
diff changeset
   920
 */
83b8875ae3f3 6256783 /etc/mnttab gets screwed-up when an unprivileged user tries to remount in a local zone
evanl
parents: 254
diff changeset
   921
static const char *
83b8875ae3f3 6256783 /etc/mnttab gets screwed-up when an unprivileged user tries to remount in a local zone
evanl
parents: 254
diff changeset
   922
stripzonepath(const char *strpath)
83b8875ae3f3 6256783 /etc/mnttab gets screwed-up when an unprivileged user tries to remount in a local zone
evanl
parents: 254
diff changeset
   923
{
83b8875ae3f3 6256783 /etc/mnttab gets screwed-up when an unprivileged user tries to remount in a local zone
evanl
parents: 254
diff changeset
   924
	char *str1, *str2;
83b8875ae3f3 6256783 /etc/mnttab gets screwed-up when an unprivileged user tries to remount in a local zone
evanl
parents: 254
diff changeset
   925
	int i;
83b8875ae3f3 6256783 /etc/mnttab gets screwed-up when an unprivileged user tries to remount in a local zone
evanl
parents: 254
diff changeset
   926
	zone_t *zonep = curproc->p_zone;
83b8875ae3f3 6256783 /etc/mnttab gets screwed-up when an unprivileged user tries to remount in a local zone
evanl
parents: 254
diff changeset
   927
83b8875ae3f3 6256783 /etc/mnttab gets screwed-up when an unprivileged user tries to remount in a local zone
evanl
parents: 254
diff changeset
   928
	if (zonep->zone_rootpath == NULL || strpath == NULL) {
83b8875ae3f3 6256783 /etc/mnttab gets screwed-up when an unprivileged user tries to remount in a local zone
evanl
parents: 254
diff changeset
   929
		return (NULL);
83b8875ae3f3 6256783 /etc/mnttab gets screwed-up when an unprivileged user tries to remount in a local zone
evanl
parents: 254
diff changeset
   930
	}
83b8875ae3f3 6256783 /etc/mnttab gets screwed-up when an unprivileged user tries to remount in a local zone
evanl
parents: 254
diff changeset
   931
83b8875ae3f3 6256783 /etc/mnttab gets screwed-up when an unprivileged user tries to remount in a local zone
evanl
parents: 254
diff changeset
   932
	/*
83b8875ae3f3 6256783 /etc/mnttab gets screwed-up when an unprivileged user tries to remount in a local zone
evanl
parents: 254
diff changeset
   933
	 * we check for the end of the string at one past the
83b8875ae3f3 6256783 /etc/mnttab gets screwed-up when an unprivileged user tries to remount in a local zone
evanl
parents: 254
diff changeset
   934
	 * current position because the zone_rootpath always
83b8875ae3f3 6256783 /etc/mnttab gets screwed-up when an unprivileged user tries to remount in a local zone
evanl
parents: 254
diff changeset
   935
	 * ends with "/" but we don't want to strip that off.
83b8875ae3f3 6256783 /etc/mnttab gets screwed-up when an unprivileged user tries to remount in a local zone
evanl
parents: 254
diff changeset
   936
	 */
83b8875ae3f3 6256783 /etc/mnttab gets screwed-up when an unprivileged user tries to remount in a local zone
evanl
parents: 254
diff changeset
   937
	str1 = zonep->zone_rootpath;
83b8875ae3f3 6256783 /etc/mnttab gets screwed-up when an unprivileged user tries to remount in a local zone
evanl
parents: 254
diff changeset
   938
	str2 = (char *)strpath;
83b8875ae3f3 6256783 /etc/mnttab gets screwed-up when an unprivileged user tries to remount in a local zone
evanl
parents: 254
diff changeset
   939
	ASSERT(str1[0] != '\0');
83b8875ae3f3 6256783 /etc/mnttab gets screwed-up when an unprivileged user tries to remount in a local zone
evanl
parents: 254
diff changeset
   940
	for (i = 0; str1[i + 1] != '\0'; i++) {
83b8875ae3f3 6256783 /etc/mnttab gets screwed-up when an unprivileged user tries to remount in a local zone
evanl
parents: 254
diff changeset
   941
		if (str1[i] != str2[i])
83b8875ae3f3 6256783 /etc/mnttab gets screwed-up when an unprivileged user tries to remount in a local zone
evanl
parents: 254
diff changeset
   942
			return ((char *)strpath);
83b8875ae3f3 6256783 /etc/mnttab gets screwed-up when an unprivileged user tries to remount in a local zone
evanl
parents: 254
diff changeset
   943
	}
83b8875ae3f3 6256783 /etc/mnttab gets screwed-up when an unprivileged user tries to remount in a local zone
evanl
parents: 254
diff changeset
   944
	return (&str2[i]);
83b8875ae3f3 6256783 /etc/mnttab gets screwed-up when an unprivileged user tries to remount in a local zone
evanl
parents: 254
diff changeset
   945
}
83b8875ae3f3 6256783 /etc/mnttab gets screwed-up when an unprivileged user tries to remount in a local zone
evanl
parents: 254
diff changeset
   946
83b8875ae3f3 6256783 /etc/mnttab gets screwed-up when an unprivileged user tries to remount in a local zone
evanl
parents: 254
diff changeset
   947
/*
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   948
 * Common mount code.  Called from the system call entry point, from autofs,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   949
 * and from pxfs.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   950
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   951
 * Takes the effective file system type, mount arguments, the mount point
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   952
 * vnode, flags specifying whether the mount is a remount and whether it
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   953
 * should be entered into the vfs list, and credentials.  Fills in its vfspp
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   954
 * parameter with the mounted file system instance's vfs.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   955
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   956
 * Note that the effective file system type is specified as a string.  It may
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   957
 * be null, in which case it's determined from the mount arguments, and may
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   958
 * differ from the type specified in the mount arguments; this is a hook to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   959
 * allow interposition when instantiating file system instances.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   960
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   961
 * The caller is responsible for releasing its own hold on the mount point
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   962
 * vp (this routine does its own hold when necessary).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   963
 * Also note that for remounts, the mount point vp should be the vnode for
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   964
 * the root of the file system rather than the vnode that the file system
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   965
 * is mounted on top of.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   966
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   967
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   968
domount(char *fsname, struct mounta *uap, vnode_t *vp, struct cred *credp,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   969
	struct vfs **vfspp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   970
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   971
	struct vfssw	*vswp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   972
	vfsops_t	*vfsops;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   973
	struct vfs	*vfsp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   974
	struct vnode	*bvp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   975
	dev_t		bdev = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   976
	mntopts_t	mnt_mntopts;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   977
	int		error = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   978
	int		copyout_error = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   979
	int		ovflags;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   980
	char		*opts = uap->optptr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   981
	char		*inargs = opts;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   982
	int		optlen = uap->optlen;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   983
	int		remount;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   984
	int		rdonly;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   985
	int		nbmand = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   986
	int		delmip = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   987
	int		addmip = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   988
	int		splice = ((uap->flags & MS_NOSPLICE) == 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   989
	int		fromspace = (uap->flags & MS_SYSSPACE) ?
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   990
				UIO_SYSSPACE : UIO_USERSPACE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   991
	char		*resource = NULL, *mountpt = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   992
	refstr_t	*oldresource, *oldmntpt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   993
	struct pathname	pn, rpn;
1520
2fb01d86c1c1 6391295 fop_create() panic when running svvs over ZFS
rsb
parents: 1488
diff changeset
   994
	vsk_anchor_t	*vskap;
0
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
	 * The v_flag value for the mount point vp is permanently set
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   998
	 * to VVFSLOCK so that no one bypasses the vn_vfs*locks routine
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   999
	 * for mount point locking.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1000
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1001
	mutex_enter(&vp->v_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1002
	vp->v_flag |= VVFSLOCK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1003
	mutex_exit(&vp->v_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1004
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1005
	mnt_mntopts.mo_count = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1006
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1007
	 * Find the ops vector to use to invoke the file system-specific mount
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1008
	 * method.  If the fsname argument is non-NULL, use it directly.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1009
	 * Otherwise, dig the file system type information out of the mount
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1010
	 * arguments.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1011
	 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1012
	 * A side effect is to hold the vfssw entry.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1013
	 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1014
	 * Mount arguments can be specified in several ways, which are
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1015
	 * distinguished by flag bit settings.  The preferred way is to set
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1016
	 * MS_OPTIONSTR, indicating an 8 argument mount with the file system
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1017
	 * type supplied as a character string and the last two arguments
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1018
	 * being a pointer to a character buffer and the size of the buffer.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1019
	 * On entry, the buffer holds a null terminated list of options; on
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1020
	 * return, the string is the list of options the file system
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1021
	 * recognized. If MS_DATA is set arguments five and six point to a
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1022
	 * block of binary data which the file system interprets.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1023
	 * A further wrinkle is that some callers don't set MS_FSS and MS_DATA
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1024
	 * consistently with these conventions.  To handle them, we check to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1025
	 * see whether the pointer to the file system name has a numeric value
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1026
	 * less than 256.  If so, we treat it as an index.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1027
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1028
	if (fsname != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1029
		if ((vswp = vfs_getvfssw(fsname)) == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1030
			return (EINVAL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1031
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1032
	} else if (uap->flags & (MS_OPTIONSTR | MS_DATA | MS_FSS)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1033
		size_t n;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1034
		uint_t fstype;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1035
		char name[FSTYPSZ];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1036
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1037
		if ((fstype = (uintptr_t)uap->fstype) < 256) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1038
			RLOCK_VFSSW();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1039
			if (fstype == 0 || fstype >= nfstype ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1040
			    !ALLOCATED_VFSSW(&vfssw[fstype])) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1041
				RUNLOCK_VFSSW();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1042
				return (EINVAL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1043
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1044
			(void) strcpy(name, vfssw[fstype].vsw_name);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1045
			RUNLOCK_VFSSW();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1046
			if ((vswp = vfs_getvfssw(name)) == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1047
				return (EINVAL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1048
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1049
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1050
			 * Handle either kernel or user address space.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1051
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1052
			if (uap->flags & MS_SYSSPACE) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1053
				error = copystr(uap->fstype, name,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1054
				    FSTYPSZ, &n);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1055
			} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1056
				error = copyinstr(uap->fstype, name,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1057
				    FSTYPSZ, &n);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1058
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1059
			if (error) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1060
				if (error == ENAMETOOLONG)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1061
					return (EINVAL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1062
				return (error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1063
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1064
			if ((vswp = vfs_getvfssw(name)) == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1065
				return (EINVAL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1066
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1067
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1068
		if ((vswp = vfs_getvfsswbyvfsops(vfs_getops(rootvfs))) == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1069
			return (EINVAL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1070
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1071
	if (!VFS_INSTALLED(vswp))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1072
		return (EINVAL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1073
	vfsops = &vswp->vsw_vfsops;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1074
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1075
	vfs_copyopttbl(&vswp->vsw_optproto, &mnt_mntopts);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1076
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1077
	 * Fetch mount options and parse them for generic vfs options
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1078
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1079
	if (uap->flags & MS_OPTIONSTR) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1080
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1081
		 * Limit the buffer size
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1082
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1083
		if (optlen < 0 || optlen > MAX_MNTOPT_STR) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1084
			error = EINVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1085
			goto errout;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1086
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1087
		if ((uap->flags & MS_SYSSPACE) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1088
			inargs = kmem_alloc(MAX_MNTOPT_STR, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1089
			inargs[0] = '\0';
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1090
			if (optlen) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1091
				error = copyinstr(opts, inargs, (size_t)optlen,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1092
					NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1093
				if (error) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1094
					goto errout;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1095
				}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1096
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1097
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1098
		vfs_parsemntopts(&mnt_mntopts, inargs, 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1099
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1100
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1101
	 * Flag bits override the options string.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1102
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1103
	if (uap->flags & MS_REMOUNT)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1104
		vfs_setmntopt_nolock(&mnt_mntopts, MNTOPT_REMOUNT, NULL, 0, 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1105
	if (uap->flags & MS_RDONLY)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1106
		vfs_setmntopt_nolock(&mnt_mntopts, MNTOPT_RO, NULL, 0, 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1107
	if (uap->flags & MS_NOSUID)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1108
		vfs_setmntopt_nolock(&mnt_mntopts, MNTOPT_NOSUID, NULL, 0, 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1109
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1110
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1111
	 * Check if this is a remount; must be set in the option string and
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1112
	 * the file system must support a remount option.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1113
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1114
	if (remount = vfs_optionisset_nolock(&mnt_mntopts,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1115
	    MNTOPT_REMOUNT, NULL)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1116
		if (!(vswp->vsw_flag & VSW_CANREMOUNT)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1117
			error = ENOTSUP;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1118
			goto errout;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1119
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1120
		uap->flags |= MS_REMOUNT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1121
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1122
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1123
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1124
	 * uap->flags and vfs_optionisset() should agree.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1125
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1126
	if (rdonly = vfs_optionisset_nolock(&mnt_mntopts, MNTOPT_RO, NULL)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1127
		uap->flags |= MS_RDONLY;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1128
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1129
	if (vfs_optionisset_nolock(&mnt_mntopts, MNTOPT_NOSUID, NULL)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1130
		uap->flags |= MS_NOSUID;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1131
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1132
	nbmand = vfs_optionisset_nolock(&mnt_mntopts, MNTOPT_NBMAND, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1133
	ASSERT(splice || !remount);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1134
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1135
	 * If we are splicing the fs into the namespace,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1136
	 * perform mount point checks.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1137
	 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1138
	 * We want to resolve the path for the mount point to eliminate
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1139
	 * '.' and ".." and symlinks in mount points; we can't do the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1140
	 * same for the resource string, since it would turn
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1141
	 * "/dev/dsk/c0t0d0s0" into "/devices/pci@...".  We need to do
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1142
	 * this before grabbing vn_vfswlock(), because otherwise we
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1143
	 * would deadlock with lookuppn().
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1144
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1145
	if (splice) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1146
		ASSERT(vp->v_count > 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1147
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1148
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1149
		 * Pick up mount point and device from appropriate space.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1150
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1151
		if (pn_get(uap->spec, fromspace, &pn) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1152
			resource = kmem_alloc(pn.pn_pathlen + 1,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1153
			    KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1154
			(void) strcpy(resource, pn.pn_path);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1155
			pn_free(&pn);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1156
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1157
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1158
		 * Do a lookupname prior to taking the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1159
		 * writelock. Mark this as completed if
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1160
		 * successful for later cleanup and addition to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1161
		 * the mount in progress table.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1162
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1163
		if ((uap->flags & MS_GLOBAL) == 0 &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1164
		    lookupname(uap->spec, fromspace,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1165
			    FOLLOW, NULL, &bvp) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1166
			addmip = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1167
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1168
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1169
		if ((error = pn_get(uap->dir, fromspace, &pn)) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1170
			pathname_t *pnp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1171
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1172
			if (*pn.pn_path != '/') {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1173
				error = EINVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1174
				pn_free(&pn);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1175
				goto errout;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1176
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1177
			pn_alloc(&rpn);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1178
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1179
			 * Kludge to prevent autofs from deadlocking with
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1180
			 * itself when it calls domount().
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1181
			 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1182
			 * If autofs is calling, it is because it is doing
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1183
			 * (autofs) mounts in the process of an NFS mount.  A
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1184
			 * lookuppn() here would cause us to block waiting for
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1185
			 * said NFS mount to complete, which can't since this
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1186
			 * is the thread that was supposed to doing it.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1187
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1188
			if (fromspace == UIO_USERSPACE) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1189
				if ((error = lookuppn(&pn, &rpn, FOLLOW, NULL,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1190
				    NULL)) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1191
					pnp = &rpn;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1192
				} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1193
					/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1194
					 * The file disappeared or otherwise
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1195
					 * became inaccessible since we opened
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1196
					 * it; might as well fail the mount
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1197
					 * since the mount point is no longer
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1198
					 * accessible.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1199
					 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1200
					pn_free(&rpn);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1201
					pn_free(&pn);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1202
					goto errout;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1203
				}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1204
			} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1205
				pnp = &pn;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1206
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1207
			mountpt = kmem_alloc(pnp->pn_pathlen + 1, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1208
			(void) strcpy(mountpt, pnp->pn_path);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1209
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1210
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1211
			 * If the addition of the zone's rootpath
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1212
			 * would push us over a total path length
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1213
			 * of MAXPATHLEN, we fail the mount with
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1214
			 * ENAMETOOLONG, which is what we would have
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1215
			 * gotten if we were trying to perform the same
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1216
			 * mount in the global zone.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1217
			 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1218
			 * strlen() doesn't count the trailing
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1219
			 * '\0', but zone_rootpathlen counts both a
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1220
			 * trailing '/' and the terminating '\0'.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1221
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1222
			if ((curproc->p_zone->zone_rootpathlen - 1 +
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1223
			    strlen(mountpt)) > MAXPATHLEN ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1224
			    (resource != NULL &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1225
			    (curproc->p_zone->zone_rootpathlen - 1 +
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1226
			    strlen(resource)) > MAXPATHLEN)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1227
				error = ENAMETOOLONG;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1228
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1229
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1230
			pn_free(&rpn);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1231
			pn_free(&pn);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1232
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1233
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1234
		if (error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1235
			goto errout;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1236
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1237
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1238
		 * Prevent path name resolution from proceeding past
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1239
		 * the mount point.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1240
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1241
		if (vn_vfswlock(vp) != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1242
			error = EBUSY;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1243
			goto errout;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1244
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1245
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1246
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1247
		 * Verify that it's legitimate to establish a mount on
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1248
		 * the prospective mount point.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1249
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1250
		if (vn_mountedvfs(vp) != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1251
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1252
			 * The mount point lock was obtained after some
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1253
			 * other thread raced through and established a mount.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1254
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1255
			vn_vfsunlock(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1256
			error = EBUSY;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1257
			goto errout;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1258
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1259
		if (vp->v_flag & VNOMOUNT) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1260
			vn_vfsunlock(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1261
			error = EINVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1262
			goto errout;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1263
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1264
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1265
	if ((uap->flags & (MS_DATA | MS_OPTIONSTR)) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1266
		uap->dataptr = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1267
		uap->datalen = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1268
	}
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
	 * If this is a remount, we don't want to create a new VFS.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1272
	 * Instead, we pass the existing one with a remount flag.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1273
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1274
	if (remount) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1275
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1276
		 * Confirm that the mount point is the root vnode of the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1277
		 * file system that is being remounted.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1278
		 * This can happen if the user specifies a different
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1279
		 * mount point directory pathname in the (re)mount command.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1280
		 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1281
		 * Code below can only be reached if splice is true, so it's
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1282
		 * safe to do vn_vfsunlock() here.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1283
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1284
		if ((vp->v_flag & VROOT) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1285
			vn_vfsunlock(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1286
			error = ENOENT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1287
			goto errout;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1288
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1289
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1290
		 * Disallow making file systems read-only unless file system
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1291
		 * explicitly allows it in its vfssw.  Ignore other flags.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1292
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1293
		if (rdonly && vn_is_readonly(vp) == 0 &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1294
		    (vswp->vsw_flag & VSW_CANRWRO) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1295
			vn_vfsunlock(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1296
			error = EINVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1297
			goto errout;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1298
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1299
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1300
		 * Changing the NBMAND setting on remounts is permitted
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1301
		 * but logged since it can lead to unexpected behavior.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1302
		 * We also counsel against using it for / and /usr.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1303
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1304
		if ((nbmand && ((vp->v_vfsp->vfs_flag & VFS_NBMAND) == 0)) ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1305
		    (!nbmand && (vp->v_vfsp->vfs_flag & VFS_NBMAND))) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1306
			cmn_err(CE_WARN, "domount: nbmand turned %s via "
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1307
			    "remounting %s", nbmand ? "on" : "off",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1308
			    refstr_value(vp->v_vfsp->vfs_mntpt));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1309
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1310
		vfsp = vp->v_vfsp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1311
		ovflags = vfsp->vfs_flag;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1312
		vfsp->vfs_flag |= VFS_REMOUNT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1313
		vfsp->vfs_flag &= ~VFS_RDONLY;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1314
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1315
		vfsp = kmem_alloc(sizeof (vfs_t), KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1316
		VFS_INIT(vfsp, vfsops, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1317
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1318
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1319
	VFS_HOLD(vfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1320
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1321
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1322
	 * The vfs_reflock is not used anymore the code below explicitly
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1323
	 * holds it preventing others accesing it directly.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1324
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1325
	if ((sema_tryp(&vfsp->vfs_reflock) == 0) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1326
	    !(vfsp->vfs_flag & VFS_REMOUNT))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1327
		cmn_err(CE_WARN,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1328
		    "mount type %s couldn't get vfs_reflock\n", vswp->vsw_name);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1329
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1330
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1331
	 * Lock the vfs. If this is a remount we want to avoid spurious umount
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1332
	 * failures that happen as a side-effect of fsflush() and other mount
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1333
	 * and unmount operations that might be going on simultaneously and
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1334
	 * may have locked the vfs currently. To not return EBUSY immediately
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1335
	 * here we use vfs_lock_wait() instead vfs_lock() for the remount case.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1336
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1337
	if (!remount) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1338
		if (error = vfs_lock(vfsp)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1339
			vfsp->vfs_flag = ovflags;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1340
			if (splice)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1341
				vn_vfsunlock(vp);
1925
91047fd43318 PSARC 2006/270 vfs_femhead change to vfs_implp
rsb
parents: 1678
diff changeset
  1342
			if (vfsp->vfs_implp)
91047fd43318 PSARC 2006/270 vfs_femhead change to vfs_implp
rsb
parents: 1678
diff changeset
  1343
				vfsimpl_teardown(vfsp);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1344
			kmem_free(vfsp, sizeof (struct vfs));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1345
			goto errout;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1346
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1347
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1348
		vfs_lock_wait(vfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1349
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1350
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1351
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1352
	 * Add device to mount in progress table, global mounts require special
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1353
	 * handling. It is possible that we have already done the lookupname
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1354
	 * on a spliced, non-global fs. If so, we don't want to do it again
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1355
	 * since we cannot do a lookupname after taking the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1356
	 * wlock above. This case is for a non-spliced, non-global filesystem.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1357
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1358
	if (!addmip) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1359
	    if ((uap->flags & MS_GLOBAL) == 0 &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1360
		lookupname(uap->spec, fromspace, FOLLOW, NULL, &bvp) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1361
			addmip = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1362
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1363
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1364
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1365
	if (addmip) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1366
		bdev = bvp->v_rdev;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1367
		VN_RELE(bvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1368
		vfs_addmip(bdev, vfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1369
		addmip = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1370
		delmip = 1;
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
	 * Invalidate cached entry for the mount point.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1374
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1375
	if (splice)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1376
		dnlc_purge_vp(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1377
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1378
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1379
	 * If have an option string but the filesystem doesn't supply a
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1380
	 * prototype options table, create a table with the global
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1381
	 * options and sufficient room to accept all the options in the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1382
	 * string.  Then parse the passed in option string
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1383
	 * accepting all the options in the string.  This gives us an
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1384
	 * option table with all the proper cancel properties for the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1385
	 * global options.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1386
	 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1387
	 * Filesystems that supply a prototype options table are handled
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1388
	 * earlier in this function.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1389
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1390
	if (uap->flags & MS_OPTIONSTR) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1391
		if (!(vswp->vsw_flag & VSW_HASPROTO)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1392
			mntopts_t tmp_mntopts;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1393
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1394
			tmp_mntopts.mo_count = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1395
			vfs_createopttbl_extend(&tmp_mntopts, inargs,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1396
			    &mnt_mntopts);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1397
			vfs_parsemntopts(&tmp_mntopts, inargs, 1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1398
			vfs_swapopttbl_nolock(&mnt_mntopts, &tmp_mntopts);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1399
			vfs_freeopttbl(&tmp_mntopts);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1400
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1401
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1402
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1403
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1404
	 * Serialize with zone creations.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1405
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1406
	mount_in_progress();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1407
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1408
	 * Instantiate (or reinstantiate) the file system.  If appropriate,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1409
	 * splice it into the file system name space.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1410
	 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1411
	 * We want VFS_MOUNT() to be able to override the vfs_resource
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1412
	 * string if necessary (ie, mntfs), and also for a remount to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1413
	 * change the same (necessary when remounting '/' during boot).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1414
	 * So we set up vfs_mntpt and vfs_resource to what we think they
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1415
	 * should be, then hand off control to VFS_MOUNT() which can
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1416
	 * override this.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1417
	 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1418
	 * For safety's sake, when changing vfs_resource or vfs_mntpt of
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1419
	 * a vfs which is on the vfs list (i.e. during a remount), we must
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1420
	 * never set those fields to NULL. Several bits of code make
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1421
	 * assumptions that the fields are always valid.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1422
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1423
	vfs_swapopttbl(&mnt_mntopts, &vfsp->vfs_mntopts);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1424
	if (remount) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1425
		if ((oldresource = vfsp->vfs_resource) != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1426
			refstr_hold(oldresource);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1427
		if ((oldmntpt = vfsp->vfs_mntpt) != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1428
			refstr_hold(oldmntpt);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1429
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1430
	vfs_setresource(vfsp, resource);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1431
	vfs_setmntpoint(vfsp, mountpt);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1432
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1433
	error = VFS_MOUNT(vfsp, vp, uap, credp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1434
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1435
	if (uap->flags & MS_RDONLY)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1436
		vfs_setmntopt(vfsp, MNTOPT_RO, NULL, 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1437
	if (uap->flags & MS_NOSUID)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1438
		vfs_setmntopt(vfsp, MNTOPT_NOSUID, NULL, 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1439
	if (uap->flags & MS_GLOBAL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1440
		vfs_setmntopt(vfsp, MNTOPT_GLOBAL, NULL, 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1441
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1442
	if (error) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1443
		if (remount) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1444
			/* put back pre-remount options */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1445
			vfs_swapopttbl(&mnt_mntopts, &vfsp->vfs_mntopts);
994
83b8875ae3f3 6256783 /etc/mnttab gets screwed-up when an unprivileged user tries to remount in a local zone
evanl
parents: 254
diff changeset
  1446
			vfs_setmntpoint(vfsp, (stripzonepath(
83b8875ae3f3 6256783 /etc/mnttab gets screwed-up when an unprivileged user tries to remount in a local zone
evanl
parents: 254
diff changeset
  1447
					refstr_value(oldmntpt))));
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1448
			if (oldmntpt)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1449
				refstr_rele(oldmntpt);
994
83b8875ae3f3 6256783 /etc/mnttab gets screwed-up when an unprivileged user tries to remount in a local zone
evanl
parents: 254
diff changeset
  1450
			vfs_setresource(vfsp, (stripzonepath(
83b8875ae3f3 6256783 /etc/mnttab gets screwed-up when an unprivileged user tries to remount in a local zone
evanl
parents: 254
diff changeset
  1451
					refstr_value(oldresource))));
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1452
			if (oldresource)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1453
				refstr_rele(oldresource);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1454
			vfsp->vfs_flag = ovflags;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1455
			vfs_unlock(vfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1456
			VFS_RELE(vfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1457
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1458
			vfs_unlock(vfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1459
			vfs_freemnttab(vfsp);
1925
91047fd43318 PSARC 2006/270 vfs_femhead change to vfs_implp
rsb
parents: 1678
diff changeset
  1460
			if (vfsp->vfs_implp)
91047fd43318 PSARC 2006/270 vfs_femhead change to vfs_implp
rsb
parents: 1678
diff changeset
  1461
				vfsimpl_teardown(vfsp);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1462
			kmem_free(vfsp, sizeof (struct vfs));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1463
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1464
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1465
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1466
		 * Set the mount time to now
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1467
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1468
		vfsp->vfs_mtime = ddi_get_time();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1469
		if (remount) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1470
			vfsp->vfs_flag &= ~VFS_REMOUNT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1471
			if (oldresource)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1472
				refstr_rele(oldresource);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1473
			if (oldmntpt)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1474
				refstr_rele(oldmntpt);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1475
		} else if (splice) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1476
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1477
			 * Link vfsp into the name space at the mount
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1478
			 * point. Vfs_add() is responsible for
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1479
			 * holding the mount point which will be
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1480
			 * released when vfs_remove() is called.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1481
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1482
			vfs_add(vp, vfsp, uap->flags);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1483
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1484
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1485
			 * Hold the reference to file system which is
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1486
			 * not linked into the name space.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1487
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1488
			vfsp->vfs_zone = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1489
			VFS_HOLD(vfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1490
			vfsp->vfs_vnodecovered = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1491
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1492
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1493
		 * Set flags for global options encountered
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1494
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1495
		if (vfs_optionisset(vfsp, MNTOPT_RO, NULL))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1496
			vfsp->vfs_flag |= VFS_RDONLY;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1497
		else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1498
			vfsp->vfs_flag &= ~VFS_RDONLY;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1499
		if (vfs_optionisset(vfsp, MNTOPT_NOSUID, NULL)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1500
			vfsp->vfs_flag |= (VFS_NOSETUID|VFS_NODEVICES);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1501
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1502
			if (vfs_optionisset(vfsp, MNTOPT_NODEVICES, NULL))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1503
				vfsp->vfs_flag |= VFS_NODEVICES;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1504
			else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1505
				vfsp->vfs_flag &= ~VFS_NODEVICES;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1506
			if (vfs_optionisset(vfsp, MNTOPT_NOSETUID, NULL))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1507
				vfsp->vfs_flag |= VFS_NOSETUID;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1508
			else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1509
				vfsp->vfs_flag &= ~VFS_NOSETUID;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1510
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1511
		if (vfs_optionisset(vfsp, MNTOPT_NBMAND, NULL))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1512
			vfsp->vfs_flag |= VFS_NBMAND;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1513
		else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1514
			vfsp->vfs_flag &= ~VFS_NBMAND;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1515
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1516
		if (vfs_optionisset(vfsp, MNTOPT_XATTR, NULL))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1517
			vfsp->vfs_flag |= VFS_XATTR;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1518
		else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1519
			vfsp->vfs_flag &= ~VFS_XATTR;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1520
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1521
		if (vfs_optionisset(vfsp, MNTOPT_NOEXEC, NULL))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1522
			vfsp->vfs_flag |= VFS_NOEXEC;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1523
		else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1524
			vfsp->vfs_flag &= ~VFS_NOEXEC;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1525
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1526
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1527
		 * Now construct the output option string of options
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1528
		 * we recognized.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1529
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1530
		if (uap->flags & MS_OPTIONSTR) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1531
			vfs_list_read_lock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1532
			copyout_error = vfs_buildoptionstr(
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1533
				&vfsp->vfs_mntopts, inargs, optlen);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1534
			vfs_list_unlock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1535
			if (copyout_error == 0 &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1536
			    (uap->flags & MS_SYSSPACE) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1537
				copyout_error = copyoutstr(inargs, opts,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1538
				    optlen, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1539
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1540
		}
1488
196daa2cf3db PSARC/2006/034 fsstat
rsb
parents: 994
diff changeset
  1541
1520
2fb01d86c1c1 6391295 fop_create() panic when running svvs over ZFS
rsb
parents: 1488
diff changeset
  1542
		/*
2fb01d86c1c1 6391295 fop_create() panic when running svvs over ZFS
rsb
parents: 1488
diff changeset
  1543
		 * If this isn't a remount, set up the vopstats before
1678
cd336ddf9a1c 6397933 fs node paniced while mounting global filesystem (/global/.devices/node@x)
rsb
parents: 1520
diff changeset
  1544
		 * anyone can touch this. We only allow spliced file
cd336ddf9a1c 6397933 fs node paniced while mounting global filesystem (/global/.devices/node@x)
rsb
parents: 1520
diff changeset
  1545
		 * systems (file systems which are in the namespace) to
cd336ddf9a1c 6397933 fs node paniced while mounting global filesystem (/global/.devices/node@x)
rsb
parents: 1520
diff changeset
  1546
		 * have the VFS_STATS flag set.
cd336ddf9a1c 6397933 fs node paniced while mounting global filesystem (/global/.devices/node@x)
rsb
parents: 1520
diff changeset
  1547
		 * NOTE: PxFS mounts the underlying file system with
cd336ddf9a1c 6397933 fs node paniced while mounting global filesystem (/global/.devices/node@x)
rsb
parents: 1520
diff changeset
  1548
		 * MS_NOSPLICE set and copies those vfs_flags to its private
cd336ddf9a1c 6397933 fs node paniced while mounting global filesystem (/global/.devices/node@x)
rsb
parents: 1520
diff changeset
  1549
		 * vfs structure. As a result, PxFS should never have
cd336ddf9a1c 6397933 fs node paniced while mounting global filesystem (/global/.devices/node@x)
rsb
parents: 1520
diff changeset
  1550
		 * the VFS_STATS flag or else we might access the vfs
cd336ddf9a1c 6397933 fs node paniced while mounting global filesystem (/global/.devices/node@x)
rsb
parents: 1520
diff changeset
  1551
		 * statistics-related fields prior to them being
cd336ddf9a1c 6397933 fs node paniced while mounting global filesystem (/global/.devices/node@x)
rsb
parents: 1520
diff changeset
  1552
		 * properly initialized.
1520
2fb01d86c1c1 6391295 fop_create() panic when running svvs over ZFS
rsb
parents: 1488
diff changeset
  1553
		 */
1678
cd336ddf9a1c 6397933 fs node paniced while mounting global filesystem (/global/.devices/node@x)
rsb
parents: 1520
diff changeset
  1554
		if (!remount && (vswp->vsw_flag & VSW_STATS) && splice) {
1520
2fb01d86c1c1 6391295 fop_create() panic when running svvs over ZFS
rsb
parents: 1488
diff changeset
  1555
			initialize_vopstats(&vfsp->vfs_vopstats);
2fb01d86c1c1 6391295 fop_create() panic when running svvs over ZFS
rsb
parents: 1488
diff changeset
  1556
			/*
2fb01d86c1c1 6391295 fop_create() panic when running svvs over ZFS
rsb
parents: 1488
diff changeset
  1557
			 * We need to set vfs_vskap to NULL because there's
2fb01d86c1c1 6391295 fop_create() panic when running svvs over ZFS
rsb
parents: 1488
diff changeset
  1558
			 * a chance it won't be set below.  This is checked
2fb01d86c1c1 6391295 fop_create() panic when running svvs over ZFS
rsb
parents: 1488
diff changeset
  1559
			 * in teardown_vopstats() so we can't have garbage.
2fb01d86c1c1 6391295 fop_create() panic when running svvs over ZFS
rsb
parents: 1488
diff changeset
  1560
			 */
2fb01d86c1c1 6391295 fop_create() panic when running svvs over ZFS
rsb
parents: 1488
diff changeset
  1561
			vfsp->vfs_vskap = NULL;
1488
196daa2cf3db PSARC/2006/034 fsstat
rsb
parents: 994
diff changeset
  1562
			vfsp->vfs_flag |= VFS_STATS;
1520
2fb01d86c1c1 6391295 fop_create() panic when running svvs over ZFS
rsb
parents: 1488
diff changeset
  1563
			vfsp->vfs_fstypevsp = get_fstype_vopstats(vfsp, vswp);
1488
196daa2cf3db PSARC/2006/034 fsstat
rsb
parents: 994
diff changeset
  1564
		}
196daa2cf3db PSARC/2006/034 fsstat
rsb
parents: 994
diff changeset
  1565
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1566
		vfs_unlock(vfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1567
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1568
	mount_completed();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1569
	if (splice)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1570
		vn_vfsunlock(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1571
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1572
	if ((error == 0) && (copyout_error == 0)) {
1520
2fb01d86c1c1 6391295 fop_create() panic when running svvs over ZFS
rsb
parents: 1488
diff changeset
  1573
		if (!remount) {
2fb01d86c1c1 6391295 fop_create() panic when running svvs over ZFS
rsb
parents: 1488
diff changeset
  1574
			/*
2fb01d86c1c1 6391295 fop_create() panic when running svvs over ZFS
rsb
parents: 1488
diff changeset
  1575
			 * Don't call get_vskstat_anchor() while holding
2fb01d86c1c1 6391295 fop_create() panic when running svvs over ZFS
rsb
parents: 1488
diff changeset
  1576
			 * locks since it allocates memory and calls
2fb01d86c1c1 6391295 fop_create() panic when running svvs over ZFS
rsb
parents: 1488
diff changeset
  1577
			 * VFS_STATVFS().  For NFS, the latter can generate
2fb01d86c1c1 6391295 fop_create() panic when running svvs over ZFS
rsb
parents: 1488
diff changeset
  1578
			 * an over-the-wire call.
2fb01d86c1c1 6391295 fop_create() panic when running svvs over ZFS
rsb
parents: 1488
diff changeset
  1579
			 */
2fb01d86c1c1 6391295 fop_create() panic when running svvs over ZFS
rsb
parents: 1488
diff changeset
  1580
			vskap = get_vskstat_anchor(vfsp);
2fb01d86c1c1 6391295 fop_create() panic when running svvs over ZFS
rsb
parents: 1488
diff changeset
  1581
			/* Only take the lock if we have something to do */
2fb01d86c1c1 6391295 fop_create() panic when running svvs over ZFS
rsb
parents: 1488
diff changeset
  1582
			if (vskap != NULL) {
2fb01d86c1c1 6391295 fop_create() panic when running svvs over ZFS
rsb
parents: 1488
diff changeset
  1583
				vfs_lock_wait(vfsp);
2fb01d86c1c1 6391295 fop_create() panic when running svvs over ZFS
rsb
parents: 1488
diff changeset
  1584
				if (vfsp->vfs_flag & VFS_STATS) {
2fb01d86c1c1 6391295 fop_create() panic when running svvs over ZFS
rsb
parents: 1488
diff changeset
  1585
					vfsp->vfs_vskap = vskap;
2fb01d86c1c1 6391295 fop_create() panic when running svvs over ZFS
rsb
parents: 1488
diff changeset
  1586
				}
2fb01d86c1c1 6391295 fop_create() panic when running svvs over ZFS
rsb
parents: 1488
diff changeset
  1587
				vfs_unlock(vfsp);
2fb01d86c1c1 6391295 fop_create() panic when running svvs over ZFS
rsb
parents: 1488
diff changeset
  1588
			}
2fb01d86c1c1 6391295 fop_create() panic when running svvs over ZFS
rsb
parents: 1488
diff changeset
  1589
		}
1488
196daa2cf3db PSARC/2006/034 fsstat
rsb
parents: 994
diff changeset
  1590
		/* Return vfsp to caller. */
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1591
		*vfspp = vfsp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1592
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1593
errout:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1594
	vfs_freeopttbl(&mnt_mntopts);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1595
	if (resource != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1596
		kmem_free(resource, strlen(resource) + 1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1597
	if (mountpt != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1598
		kmem_free(mountpt, strlen(mountpt) + 1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1599
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1600
	 * It is possible we errored prior to adding to mount in progress
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1601
	 * table. Must free vnode we acquired with successful lookupname.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1602
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1603
	if (addmip)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1604
		VN_RELE(bvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1605
	if (delmip)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1606
		vfs_delmip(vfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1607
	ASSERT(vswp != NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1608
	vfs_unrefvfssw(vswp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1609
	if (inargs != opts)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1610
		kmem_free(inargs, MAX_MNTOPT_STR);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1611
	if (copyout_error) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1612
		VFS_RELE(vfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1613
		error = copyout_error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1614
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1615
	return (error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1616
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1617
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1618
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1619
vfs_setpath(struct vfs *vfsp, refstr_t **refp, const char *newpath)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1620
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1621
	size_t len;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1622
	refstr_t *ref;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1623
	zone_t *zone = curproc->p_zone;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1624
	char *sp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1625
	int have_list_lock = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1626
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1627
	ASSERT(!VFS_ON_LIST(vfsp) || vfs_lock_held(vfsp));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1628
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1629
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1630
	 * New path must be less than MAXPATHLEN because mntfs
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1631
	 * will only display up to MAXPATHLEN bytes. This is currently
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1632
	 * safe, because domount() uses pn_get(), and other callers
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1633
	 * similarly cap the size to fewer than MAXPATHLEN bytes.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1634
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1635
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1636
	ASSERT(strlen(newpath) < MAXPATHLEN);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1637
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1638
	/* mntfs requires consistency while vfs list lock is held */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1639
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1640
	if (VFS_ON_LIST(vfsp)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1641
		have_list_lock = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1642
		vfs_list_lock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1643
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1644
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1645
	if (*refp != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1646
		refstr_rele(*refp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1647
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1648
	/* Do we need to modify the path? */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1649
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1650
	if (zone == global_zone || *newpath != '/') {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1651
		ref = refstr_alloc(newpath);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1652
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1653
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1654
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1655
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1656
	 * Truncate the trailing '/' in the zoneroot, and merge
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1657
	 * in the zone's rootpath with the "newpath" (resource
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1658
	 * or mountpoint) passed in.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1659
	 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1660
	 * The size of the required buffer is thus the size of
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1661
	 * the buffer required for the passed-in newpath
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1662
	 * (strlen(newpath) + 1), plus the size of the buffer
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1663
	 * required to hold zone_rootpath (zone_rootpathlen)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1664
	 * minus one for one of the now-superfluous NUL
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1665
	 * terminations, minus one for the trailing '/'.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1666
	 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1667
	 * That gives us:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1668
	 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1669
	 * (strlen(newpath) + 1) + zone_rootpathlen - 1 - 1
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1670
	 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1671
	 * Which is what we have below.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1672
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1673
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1674
	len = strlen(newpath) + zone->zone_rootpathlen - 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1675
	sp = kmem_alloc(len, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1676
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1677
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1678
	 * Copy everything including the trailing slash, which
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1679
	 * we then overwrite with the NUL character.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1680
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1681
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1682
	(void) strcpy(sp, zone->zone_rootpath);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1683
	sp[zone->zone_rootpathlen - 2] = '\0';
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1684
	(void) strcat(sp, newpath);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1685
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1686
	ref = refstr_alloc(sp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1687
	kmem_free(sp, len);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1688
out:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1689
	*refp = ref;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1690
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1691
	if (have_list_lock) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1692
		vfs_mnttab_modtimeupd();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1693
		vfs_list_unlock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1694
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1695
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1696
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1697
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1698
 * Record a mounted resource name in a vfs structure.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1699
 * If vfsp is already mounted, caller must hold the vfs lock.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1700
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1701
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1702
vfs_setresource(struct vfs *vfsp, const char *resource)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1703
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1704
	if (resource == NULL || resource[0] == '\0')
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1705
		resource = VFS_NORESOURCE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1706
	vfs_setpath(vfsp, &vfsp->vfs_resource, resource);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1707
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1708
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1709
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1710
 * Record a mount point name in a vfs structure.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1711
 * If vfsp is already mounted, caller must hold the vfs lock.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1712
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1713
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1714
vfs_setmntpoint(struct vfs *vfsp, const char *mntpt)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1715
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1716
	if (mntpt == NULL || mntpt[0] == '\0')
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1717
		mntpt = VFS_NOMNTPT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1718
	vfs_setpath(vfsp, &vfsp->vfs_mntpt, mntpt);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1719
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1720
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1721
/* Returns the vfs_resource. Caller must call refstr_rele() when finished. */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1722
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1723
refstr_t *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1724
vfs_getresource(const struct vfs *vfsp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1725
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1726
	refstr_t *resource;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1727
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1728
	vfs_list_read_lock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1729
	resource = vfsp->vfs_resource;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1730
	refstr_hold(resource);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1731
	vfs_list_unlock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1732
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1733
	return (resource);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1734
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1735
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1736
/* Returns the vfs_mntpt. Caller must call refstr_rele() when finished. */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1737
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1738
refstr_t *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1739
vfs_getmntpoint(const struct vfs *vfsp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1740
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1741
	refstr_t *mntpt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1742
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1743
	vfs_list_read_lock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1744
	mntpt = vfsp->vfs_mntpt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1745
	refstr_hold(mntpt);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1746
	vfs_list_unlock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1747
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1748
	return (mntpt);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1749
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1750
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1751
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1752
 * Create an empty options table with enough empty slots to hold all
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1753
 * The options in the options string passed as an argument.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1754
 * Potentially prepend another options table.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1755
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1756
 * Note: caller is responsible for locking the vfs list, if needed,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1757
 *       to protect mops.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1758
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1759
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1760
vfs_createopttbl_extend(mntopts_t *mops, const char *opts,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1761
    const mntopts_t *mtmpl)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1762
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1763
	const char *s = opts;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1764
	uint_t count;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1765
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1766
	if (opts == NULL || *opts == '\0') {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1767
		count = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1768
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1769
		count = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1770
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1771
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1772
		 * Count number of options in the string
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1773
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1774
		for (s = strchr(s, ','); s != NULL; s = strchr(s, ',')) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1775
			count++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1776
			s++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1777
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1778
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1779
	vfs_copyopttbl_extend(mtmpl, mops, count);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1780
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1781
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1782
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1783
 * Create an empty options table with enough empty slots to hold all
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1784
 * The options in the options string passed as an argument.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1785
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1786
 * This function is *not* for general use by filesystems.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1787
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1788
 * Note: caller is responsible for locking the vfs list, if needed,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1789
 *       to protect mops.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1790
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1791
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1792
vfs_createopttbl(mntopts_t *mops, const char *opts)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1793
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1794
	vfs_createopttbl_extend(mops, opts, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1795
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1796
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1797
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1798
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1799
 * Swap two mount options tables
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1800
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1801
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1802
vfs_swapopttbl_nolock(mntopts_t *optbl1, mntopts_t *optbl2)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1803
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1804
	uint_t tmpcnt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1805
	mntopt_t *tmplist;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1806
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1807
	tmpcnt = optbl2->mo_count;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1808
	tmplist = optbl2->mo_list;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1809
	optbl2->mo_count = optbl1->mo_count;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1810
	optbl2->mo_list = optbl1->mo_list;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1811
	optbl1->mo_count = tmpcnt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1812
	optbl1->mo_list = tmplist;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1813
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1814
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1815
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1816
vfs_swapopttbl(mntopts_t *optbl1, mntopts_t *optbl2)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1817
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1818
	vfs_list_lock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1819
	vfs_swapopttbl_nolock(optbl1, optbl2);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1820
	vfs_mnttab_modtimeupd();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1821
	vfs_list_unlock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1822
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1823
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1824
static char **
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1825
vfs_copycancelopt_extend(char **const moc, int extend)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1826
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1827
	int i = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1828
	int j;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1829
	char **result;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1830
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1831
	if (moc != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1832
		for (; moc[i] != NULL; i++)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1833
			/* count number of options to cancel */;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1834
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1835
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1836
	if (i + extend == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1837
		return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1838
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1839
	result = kmem_alloc((i + extend + 1) * sizeof (char *), KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1840
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1841
	for (j = 0; j < i; j++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1842
		result[j] = kmem_alloc(strlen(moc[j]) + 1, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1843
		(void) strcpy(result[j], moc[j]);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1844
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1845
	for (; j <= i + extend; j++)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1846
		result[j] = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1847
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1848
	return (result);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1849
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1850
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1851
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1852
vfs_copyopt(const mntopt_t *s, mntopt_t *d)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1853
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1854
	char *sp, *dp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1855
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1856
	d->mo_flags = s->mo_flags;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1857
	d->mo_data = s->mo_data;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1858
	sp = s->mo_name;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1859
	if (sp != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1860
		dp = kmem_alloc(strlen(sp) + 1, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1861
		(void) strcpy(dp, sp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1862
		d->mo_name = dp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1863
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1864
		d->mo_name = NULL; /* should never happen */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1865
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1866
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1867
	d->mo_cancel = vfs_copycancelopt_extend(s->mo_cancel, 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1868
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1869
	sp = s->mo_arg;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1870
	if (sp != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1871
		dp = kmem_alloc(strlen(sp) + 1, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1872
		(void) strcpy(dp, sp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1873
		d->mo_arg = dp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1874
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1875
		d->mo_arg = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1876
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1877
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1878
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1879
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1880
 * Copy a mount options table, possibly allocating some spare
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1881
 * slots at the end.  It is permissible to copy_extend the NULL table.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1882
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1883
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1884
vfs_copyopttbl_extend(const mntopts_t *smo, mntopts_t *dmo, int extra)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1885
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1886
	uint_t i, count;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1887
	mntopt_t *motbl;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1888
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1889
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1890
	 * Clear out any existing stuff in the options table being initialized
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1891
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1892
	vfs_freeopttbl(dmo);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1893
	count = (smo == NULL) ? 0 : smo->mo_count;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1894
	if ((count + extra) == 0)	/* nothing to do */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1895
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1896
	dmo->mo_count = count + extra;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1897
	motbl = kmem_zalloc((count + extra) * sizeof (mntopt_t), KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1898
	dmo->mo_list = motbl;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1899
	for (i = 0; i < count; i++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1900
		vfs_copyopt(&smo->mo_list[i], &motbl[i]);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1901
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1902
	for (i = count; i < count + extra; i++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1903
		motbl[i].mo_flags = MO_EMPTY;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1904
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1905
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1906
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1907
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1908
 * Copy a mount options table.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1909
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1910
 * This function is *not* for general use by filesystems.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1911
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1912
 * Note: caller is responsible for locking the vfs list, if needed,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1913
 *       to protect smo and dmo.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1914
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1915
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1916
vfs_copyopttbl(const mntopts_t *smo, mntopts_t *dmo)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1917
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1918
	vfs_copyopttbl_extend(smo, dmo, 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1919
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1920
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1921
static char **
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1922
vfs_mergecancelopts(const mntopt_t *mop1, const mntopt_t *mop2)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1923
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1924
	int c1 = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1925
	int c2 = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1926
	char **result;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1927
	char **sp1, **sp2, **dp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1928
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1929
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1930
	 * First we count both lists of cancel options.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1931
	 * If either is NULL or has no elements, we return a copy of
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1932
	 * the other.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1933
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1934
	if (mop1->mo_cancel != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1935
		for (; mop1->mo_cancel[c1] != NULL; c1++)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1936
			/* count cancel options in mop1 */;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1937
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1938
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1939
	if (c1 == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1940
		return (vfs_copycancelopt_extend(mop2->mo_cancel, 0));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1941
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1942
	if (mop2->mo_cancel != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1943
		for (; mop2->mo_cancel[c2] != NULL; c2++)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1944
			/* count cancel options in mop2 */;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1945
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1946
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1947
	result = vfs_copycancelopt_extend(mop1->mo_cancel, c2);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1948
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1949
	if (c2 == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1950
		return (result);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1951
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1952
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1953
	 * When we get here, we've got two sets of cancel options;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1954
	 * we need to merge the two sets.  We know that the result
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1955
	 * array has "c1+c2+1" entries and in the end we might shrink
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1956
	 * it.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1957
	 * Result now has a copy of the c1 entries from mop1; we'll
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1958
	 * now lookup all the entries of mop2 in mop1 and copy it if
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1959
	 * it is unique.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1960
	 * This operation is O(n^2) but it's only called once per
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1961
	 * filesystem per duplicate option.  This is a situation
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1962
	 * which doesn't arise with the filesystems in ON and
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1963
	 * n is generally 1.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1964
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1965
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1966
	dp = &result[c1];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1967
	for (sp2 = mop2->mo_cancel; *sp2 != NULL; sp2++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1968
		for (sp1 = mop1->mo_cancel; *sp1 != NULL; sp1++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1969
			if (strcmp(*sp1, *sp2) == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1970
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1971
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1972
		if (*sp1 == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1973
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1974
			 * Option *sp2 not found in mop1, so copy it.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1975
			 * The calls to vfs_copycancelopt_extend()
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1976
			 * guarantee that there's enough room.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1977
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1978
			*dp = kmem_alloc(strlen(*sp2) + 1, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1979
			(void) strcpy(*dp++, *sp2);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1980
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1981
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1982
	if (dp != &result[c1+c2]) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1983
		size_t bytes = (dp - result + 1) * sizeof (char *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1984
		char **nres = kmem_alloc(bytes, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1985
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1986
		bcopy(result, nres, bytes);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1987
		kmem_free(result, (c1 + c2 + 1) * sizeof (char *));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1988
		result = nres;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1989
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1990
	return (result);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1991
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1992
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1993
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1994
 * Merge two mount option tables (outer and inner) into one.  This is very
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1995
 * similar to "merging" global variables and automatic variables in C.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1996
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1997
 * This isn't (and doesn't have to be) fast.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1998
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1999
 * This function is *not* for general use by filesystems.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2000
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2001
 * Note: caller is responsible for locking the vfs list, if needed,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2002
 *       to protect omo, imo & dmo.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2003
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2004
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2005
vfs_mergeopttbl(const mntopts_t *omo, const mntopts_t *imo, mntopts_t *dmo)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2006
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2007
	uint_t i, count;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2008
	mntopt_t *mop, *motbl;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2009
	uint_t freeidx;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2010
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2011
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2012
	 * First determine how much space we need to allocate.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2013
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2014
	count = omo->mo_count;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2015
	for (i = 0; i < imo->mo_count; i++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2016
		if (imo->mo_list[i].mo_flags & MO_EMPTY)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2017
			continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2018
		if (vfs_hasopt(omo, imo->mo_list[i].mo_name) == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2019
			count++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2020
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2021
	ASSERT(count >= omo->mo_count &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2022
	    count <= omo->mo_count + imo->mo_count);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2023
	motbl = kmem_alloc(count * sizeof (mntopt_t), KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2024
	for (i = 0; i < omo->mo_count; i++)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2025
		vfs_copyopt(&omo->mo_list[i], &motbl[i]);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2026
	freeidx = omo->mo_count;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2027
	for (i = 0; i < imo->mo_count; i++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2028
		if (imo->mo_list[i].mo_flags & MO_EMPTY)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2029
			continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2030
		if ((mop = vfs_hasopt(omo, imo->mo_list[i].mo_name)) != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2031
			char **newcanp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2032
			uint_t index = mop - omo->mo_list;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2033
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2034
			newcanp = vfs_mergecancelopts(mop, &motbl[index]);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2035
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2036
			vfs_freeopt(&motbl[index]);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2037
			vfs_copyopt(&imo->mo_list[i], &motbl[index]);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2038
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2039
			vfs_freecancelopt(motbl[index].mo_cancel);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2040
			motbl[index].mo_cancel = newcanp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2041
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2042
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2043
			 * If it's a new option, just copy it over to the first
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2044
			 * free location.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2045
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2046
			vfs_copyopt(&imo->mo_list[i], &motbl[freeidx++]);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2047
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2048
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2049
	dmo->mo_count = count;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2050
	dmo->mo_list = motbl;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2051
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2052
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2053
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2054
 * Functions to set and clear mount options in a mount options table.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2055
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2056
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2057
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2058
 * Clear a mount option, if it exists.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2059
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2060
 * The update_mnttab arg indicates whether mops is part of a vfs that is on
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2061
 * the vfs list.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2062
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2063
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2064
vfs_clearmntopt_nolock(mntopts_t *mops, const char *opt, int update_mnttab)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2065
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2066
	struct mntopt *mop;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2067
	uint_t i, count;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2068
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2069
	ASSERT(!update_mnttab || RW_WRITE_HELD(&vfslist));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2070
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2071
	count = mops->mo_count;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2072
	for (i = 0; i < count; i++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2073
		mop = &mops->mo_list[i];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2074
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2075
		if (mop->mo_flags & MO_EMPTY)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2076
			continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2077
		if (strcmp(opt, mop->mo_name))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2078
			continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2079
		mop->mo_flags &= ~MO_SET;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2080
		if (mop->mo_arg != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2081
			kmem_free(mop->mo_arg, strlen(mop->mo_arg) + 1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2082
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2083
		mop->mo_arg = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2084
		if (update_mnttab)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2085
			vfs_mnttab_modtimeupd();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2086
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2087
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2088
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2089
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2090
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2091
vfs_clearmntopt(struct vfs *vfsp, const char *opt)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2092
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2093
	int gotlock = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2094
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2095
	if (VFS_ON_LIST(vfsp)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2096
		gotlock = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2097
		vfs_list_lock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2098
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2099
	vfs_clearmntopt_nolock(&vfsp->vfs_mntopts, opt, gotlock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2100
	if (gotlock)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2101
		vfs_list_unlock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2102
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2103
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2104
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2105
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2106
 * Set a mount option on.  If it's not found in the table, it's silently
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2107
 * ignored.  If the option has MO_IGNORE set, it is still set unless the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2108
 * VFS_NOFORCEOPT bit is set in the flags.  Also, VFS_DISPLAY/VFS_NODISPLAY flag
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2109
 * bits can be used to toggle the MO_NODISPLAY bit for the option.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2110
 * If the VFS_CREATEOPT flag bit is set then the first option slot with
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2111
 * MO_EMPTY set is created as the option passed in.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2112
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2113
 * The update_mnttab arg indicates whether mops is part of a vfs that is on
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2114
 * the vfs list.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2115
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2116
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2117
vfs_setmntopt_nolock(mntopts_t *mops, const char *opt,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2118
    const char *arg, int flags, int update_mnttab)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2119
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2120
	mntopt_t *mop;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2121
	uint_t i, count;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2122
	char *sp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2123
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2124
	ASSERT(!update_mnttab || RW_WRITE_HELD(&vfslist));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2125
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2126
	if (flags & VFS_CREATEOPT) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2127
		if (vfs_hasopt(mops, opt) != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2128
			flags &= ~VFS_CREATEOPT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2129
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2130
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2131
	count = mops->mo_count;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2132
	for (i = 0; i < count; i++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2133
		mop = &mops->mo_list[i];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2134
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2135
		if (mop->mo_flags & MO_EMPTY) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2136
			if ((flags & VFS_CREATEOPT) == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2137
				continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2138
			sp = kmem_alloc(strlen(opt) + 1, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2139
			(void) strcpy(sp, opt);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2140
			mop->mo_name = sp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2141
			if (arg != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2142
				mop->mo_flags = MO_HASVALUE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2143
			else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2144
				mop->mo_flags = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2145
		} else if (strcmp(opt, mop->mo_name)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2146
			continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2147
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2148
		if ((mop->mo_flags & MO_IGNORE) && (flags & VFS_NOFORCEOPT))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2149
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2150
		if (arg != NULL && (mop->mo_flags & MO_HASVALUE) != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2151
			sp = kmem_alloc(strlen(arg) + 1, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2152
			(void) strcpy(sp, arg);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2153
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2154
			sp = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2155
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2156
		if (mop->mo_arg != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2157
			kmem_free(mop->mo_arg, strlen(mop->mo_arg) + 1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2158
		mop->mo_arg = sp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2159
		if (flags & VFS_DISPLAY)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2160
			mop->mo_flags &= ~MO_NODISPLAY;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2161
		if (flags & VFS_NODISPLAY)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2162
			mop->mo_flags |= MO_NODISPLAY;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2163
		mop->mo_flags |= MO_SET;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2164
		if (mop->mo_cancel != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2165
			char **cp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2166
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2167
			for (cp = mop->mo_cancel; *cp != NULL; cp++)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2168
				vfs_clearmntopt_nolock(mops, *cp, 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2169
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2170
		if (update_mnttab)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2171
			vfs_mnttab_modtimeupd();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2172
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2173
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2174
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2175
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2176
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2177
vfs_setmntopt(struct vfs *vfsp, const char *opt, const char *arg, int flags)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2178
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2179
	int gotlock = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2180
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2181
	if (VFS_ON_LIST(vfsp)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2182
		gotlock = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2183
		vfs_list_lock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2184
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2185
	vfs_setmntopt_nolock(&vfsp->vfs_mntopts, opt, arg, flags, gotlock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2186
	if (gotlock)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2187
		vfs_list_unlock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2188
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2189
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2190
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2191
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2192
 * Add a "tag" option to a mounted file system's options list.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2193
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2194
 * Note: caller is responsible for locking the vfs list, if needed,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2195
 *       to protect mops.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2196
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2197
static mntopt_t *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2198
vfs_addtag(mntopts_t *mops, const char *tag)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2199
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2200
	uint_t count;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2201
	mntopt_t *mop, *motbl;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2202
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2203
	count = mops->mo_count + 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2204
	motbl = kmem_zalloc(count * sizeof (mntopt_t), KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2205
	if (mops->mo_count) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2206
		size_t len = (count - 1) * sizeof (mntopt_t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2207
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2208
		bcopy(mops->mo_list, motbl, len);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2209
		kmem_free(mops->mo_list, len);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2210
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2211
	mops->mo_count = count;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2212
	mops->mo_list = motbl;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2213
	mop = &motbl[count - 1];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2214
	mop->mo_flags = MO_TAG;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2215
	mop->mo_name = kmem_alloc(strlen(tag) + 1, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2216
	(void) strcpy(mop->mo_name, tag);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2217
	return (mop);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2218
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2219
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2220
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2221
 * Allow users to set arbitrary "tags" in a vfs's mount options.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2222
 * Broader use within the kernel is discouraged.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2223
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2224
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2225
vfs_settag(uint_t major, uint_t minor, const char *mntpt, const char *tag,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2226
    cred_t *cr)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2227
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2228
	vfs_t *vfsp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2229
	mntopts_t *mops;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2230
	mntopt_t *mop;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2231
	int found = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2232
	dev_t dev = makedevice(major, minor);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2233
	int err = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2234
	char *buf = kmem_alloc(MAX_MNTOPT_STR, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2235
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2236
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2237
	 * Find the desired mounted file system
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2238
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2239
	vfs_list_lock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2240
	vfsp = rootvfs;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2241
	do {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2242
		if (vfsp->vfs_dev == dev &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2243
		    strcmp(mntpt, refstr_value(vfsp->vfs_mntpt)) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2244
			found = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2245
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2246
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2247
		vfsp = vfsp->vfs_next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2248
	} while (vfsp != rootvfs);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2249
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2250
	if (!found) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2251
		err = EINVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2252
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2253
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2254
	err = secpolicy_fs_config(cr, vfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2255
	if (err != 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2256
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2257
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2258
	mops = &vfsp->vfs_mntopts;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2259
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2260
	 * Add tag if it doesn't already exist
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2261
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2262
	if ((mop = vfs_hasopt(mops, tag)) == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2263
		int len;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2264
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2265
		(void) vfs_buildoptionstr(mops, buf, MAX_MNTOPT_STR);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2266
		len = strlen(buf);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2267
		if (len + strlen(tag) + 2 > MAX_MNTOPT_STR) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2268
			err = ENAMETOOLONG;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2269
			goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2270
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2271
		mop = vfs_addtag(mops, tag);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2272
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2273
	if ((mop->mo_flags & MO_TAG) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2274
		err = EINVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2275
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2276
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2277
	vfs_setmntopt_nolock(mops, tag, NULL, 0, 1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2278
out:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2279
	vfs_list_unlock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2280
	kmem_free(buf, MAX_MNTOPT_STR);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2281
	return (err);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2282
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2283
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2284
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2285
 * Allow users to remove arbitrary "tags" in a vfs's mount options.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2286
 * Broader use within the kernel is discouraged.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2287
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2288
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2289
vfs_clrtag(uint_t major, uint_t minor, const char *mntpt, const char *tag,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2290
    cred_t *cr)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2291
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2292
	vfs_t *vfsp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2293
	mntopt_t *mop;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2294
	int found = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2295
	dev_t dev = makedevice(major, minor);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2296
	int err = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2297
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2298
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2299
	 * Find the desired mounted file system
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2300
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2301
	vfs_list_lock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2302
	vfsp = rootvfs;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2303
	do {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2304
		if (vfsp->vfs_dev == dev &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2305
		    strcmp(mntpt, refstr_value(vfsp->vfs_mntpt)) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2306
			found = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2307
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2308
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2309
		vfsp = vfsp->vfs_next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2310
	} while (vfsp != rootvfs);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2311
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2312
	if (!found) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2313
		err = EINVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2314
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2315
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2316
	err = secpolicy_fs_config(cr, vfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2317
	if (err != 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2318
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2319
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2320
	if ((mop = vfs_hasopt(&vfsp->vfs_mntopts, tag)) == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2321
		err = EINVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2322
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2323
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2324
	if ((mop->mo_flags & MO_TAG) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2325
		err = EINVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2326
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2327
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2328
	vfs_clearmntopt_nolock(&vfsp->vfs_mntopts, tag, 1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2329
out:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2330
	vfs_list_unlock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2331
	return (err);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2332
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2333
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2334
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2335
 * Function to parse an option string and fill in a mount options table.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2336
 * Unknown options are silently ignored.  The input option string is modified
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2337
 * by replacing separators with nulls.  If the create flag is set, options
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2338
 * not found in the table are just added on the fly.  The table must have
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2339
 * an option slot marked MO_EMPTY to add an option on the fly.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2340
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2341
 * This function is *not* for general use by filesystems.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2342
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2343
 * Note: caller is responsible for locking the vfs list, if needed,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2344
 *       to protect mops..
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2345
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2346
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2347
vfs_parsemntopts(mntopts_t *mops, char *osp, int create)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2348
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2349
	char *s = osp, *p, *nextop, *valp, *cp, *ep;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2350
	int setflg = VFS_NOFORCEOPT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2351
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2352
	if (osp == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2353
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2354
	while (*s != '\0') {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2355
		p = strchr(s, ',');	/* find next option */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2356
		if (p == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2357
			cp = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2358
			p = s + strlen(s);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2359
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2360
			cp = p;		/* save location of comma */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2361
			*p++ = '\0';	/* mark end and point to next option */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2362
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2363
		nextop = p;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2364
		p = strchr(s, '=');	/* look for value */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2365
		if (p == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2366
			valp = NULL;	/* no value supplied */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2367
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2368
			ep = p;		/* save location of equals */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2369
			*p++ = '\0';	/* end option and point to value */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2370
			valp = p;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2371
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2372
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2373
		 * set option into options table
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2374
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2375
		if (create)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2376
			setflg |= VFS_CREATEOPT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2377
		vfs_setmntopt_nolock(mops, s, valp, setflg, 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2378
		if (cp != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2379
			*cp = ',';	/* restore the comma */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2380
		if (valp != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2381
			*ep = '=';	/* restore the equals */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2382
		s = nextop;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2383
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2384
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2385
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2386
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2387
 * Function to inquire if an option exists in a mount options table.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2388
 * Returns a pointer to the option if it exists, else NULL.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2389
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2390
 * This function is *not* for general use by filesystems.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2391
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2392
 * Note: caller is responsible for locking the vfs list, if needed,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2393
 *       to protect mops.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2394
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2395
struct mntopt *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2396
vfs_hasopt(const mntopts_t *mops, const char *opt)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2397
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2398
	struct mntopt *mop;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2399
	uint_t i, count;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2400
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2401
	count = mops->mo_count;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2402
	for (i = 0; i < count; i++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2403
		mop = &mops->mo_list[i];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2404
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2405
		if (mop->mo_flags & MO_EMPTY)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2406
			continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2407
		if (strcmp(opt, mop->mo_name) == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2408
			return (mop);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2409
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2410
	return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2411
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2412
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2413
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2414
 * Function to inquire if an option is set in a mount options table.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2415
 * Returns non-zero if set and fills in the arg pointer with a pointer to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2416
 * the argument string or NULL if there is no argument string.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2417
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2418
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2419
vfs_optionisset_nolock(const mntopts_t *mops, const char *opt, char **argp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2420
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2421
	struct mntopt *mop;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2422
	uint_t i, count;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2423
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2424
	count = mops->mo_count;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2425
	for (i = 0; i < count; i++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2426
		mop = &mops->mo_list[i];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2427
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2428
		if (mop->mo_flags & MO_EMPTY)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2429
			continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2430
		if (strcmp(opt, mop->mo_name))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2431
			continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2432
		if ((mop->mo_flags & MO_SET) == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2433
			return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2434
		if (argp != NULL && (mop->mo_flags & MO_HASVALUE) != 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2435
			*argp = mop->mo_arg;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2436
		return (1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2437
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2438
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2439
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2440
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2441
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2442
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2443
vfs_optionisset(const struct vfs *vfsp, const char *opt, char **argp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2444
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2445
	int ret;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2446
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2447
	vfs_list_read_lock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2448
	ret = vfs_optionisset_nolock(&vfsp->vfs_mntopts, opt, argp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2449
	vfs_list_unlock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2450
	return (ret);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2451
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2452
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2453
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2454
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2455
 * Construct a comma separated string of the options set in the given
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2456
 * mount table, return the string in the given buffer.  Return non-zero if
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2457
 * the buffer would overflow.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2458
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2459
 * This function is *not* for general use by filesystems.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2460
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2461
 * Note: caller is responsible for locking the vfs list, if needed,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2462
 *       to protect mp.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2463
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2464
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2465
vfs_buildoptionstr(const mntopts_t *mp, char *buf, int len)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2466
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2467
	char *cp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2468
	uint_t i;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2469
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2470
	buf[0] = '\0';
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2471
	cp = buf;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2472
	for (i = 0; i < mp->mo_count; i++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2473
		struct mntopt *mop;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2474
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2475
		mop = &mp->mo_list[i];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2476
		if (mop->mo_flags & MO_SET) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2477
			int optlen, comma = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2478
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2479
			if (buf[0] != '\0')
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2480
				comma = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2481
			optlen = strlen(mop->mo_name);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2482
			if (strlen(buf) + comma + optlen + 1 > len)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2483
				goto err;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2484
			if (comma)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2485
				*cp++ = ',';
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2486
			(void) strcpy(cp, mop->mo_name);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2487
			cp += optlen;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2488
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2489
			 * Append option value if there is one
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2490
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2491
			if (mop->mo_arg != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2492
				int arglen;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2493
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2494
				arglen = strlen(mop->mo_arg);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2495
				if (strlen(buf) + arglen + 2 > len)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2496
					goto err;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2497
				*cp++ = '=';
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2498
				(void) strcpy(cp, mop->mo_arg);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2499
				cp += arglen;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2500
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2501
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2502
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2503
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2504
err:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2505
	return (EOVERFLOW);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2506
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2507
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2508
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2509
vfs_freecancelopt(char **moc)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2510
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2511
	if (moc != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2512
		int ccnt = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2513
		char **cp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2514
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2515
		for (cp = moc; *cp != NULL; cp++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2516
			kmem_free(*cp, strlen(*cp) + 1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2517
			ccnt++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2518
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2519
		kmem_free(moc, (ccnt + 1) * sizeof (char *));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2520
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2521
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2522
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2523
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2524
vfs_freeopt(mntopt_t *mop)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2525
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2526
	if (mop->mo_name != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2527
		kmem_free(mop->mo_name, strlen(mop->mo_name) + 1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2528
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2529
	vfs_freecancelopt(mop->mo_cancel);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2530
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2531
	if (mop->mo_arg != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2532
		kmem_free(mop->mo_arg, strlen(mop->mo_arg) + 1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2533
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2534
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2535
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2536
 * Free a mount options table
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2537
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2538
 * This function is *not* for general use by filesystems.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2539
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2540
 * Note: caller is responsible for locking the vfs list, if needed,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2541
 *       to protect mp.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2542
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2543
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2544
vfs_freeopttbl(mntopts_t *mp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2545
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2546
	uint_t i, count;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2547
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2548
	count = mp->mo_count;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2549
	for (i = 0; i < count; i++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2550
		vfs_freeopt(&mp->mo_list[i]);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2551
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2552
	if (count) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2553
		kmem_free(mp->mo_list, sizeof (mntopt_t) * count);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2554
		mp->mo_count = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2555
		mp->mo_list = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2556
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2557
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2558
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2559
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2560
 * Free any mnttab information recorded in the vfs struct.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2561
 * The vfs must not be on the vfs list.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2562
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2563
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2564
vfs_freemnttab(struct vfs *vfsp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2565
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2566
	ASSERT(!VFS_ON_LIST(vfsp));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2567
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2568
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2569
	 * Free device and mount point information
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2570
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2571
	if (vfsp->vfs_mntpt != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2572
		refstr_rele(vfsp->vfs_mntpt);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2573
		vfsp->vfs_mntpt = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2574
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2575
	if (vfsp->vfs_resource != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2576
		refstr_rele(vfsp->vfs_resource);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2577
		vfsp->vfs_resource = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2578
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2579
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2580
	 * Now free mount options information
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2581
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2582
	vfs_freeopttbl(&vfsp->vfs_mntopts);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2583
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2584
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2585
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2586
 * Return the last mnttab modification time
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2587
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2588
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2589
vfs_mnttab_modtime(timespec_t *ts)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2590
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2591
	ASSERT(RW_LOCK_HELD(&vfslist));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2592
	*ts = vfs_mnttab_mtime;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2593
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2594
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2595
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2596
 * See if mnttab is changed
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2597
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2598
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2599
vfs_mnttab_poll(timespec_t *old, struct pollhead **phpp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2600
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2601
	int changed;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2602
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2603
	*phpp = (struct pollhead *)NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2604
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2605
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2606
	 * Note: don't grab vfs list lock before accessing vfs_mnttab_mtime.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2607
	 * Can lead to deadlock against vfs_mnttab_modtimeupd(). It is safe
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2608
	 * to not grab the vfs list lock because tv_sec is monotonically
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2609
	 * increasing.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2610
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2611
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2612
	changed = (old->tv_nsec != vfs_mnttab_mtime.tv_nsec) ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2613
	    (old->tv_sec != vfs_mnttab_mtime.tv_sec);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2614
	if (!changed) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2615
		*phpp = &vfs_pollhd;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2616
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2617
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2618
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2619
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2620
 * Update the mnttab modification time and wake up any waiters for
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2621
 * mnttab changes
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2622
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2623
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2624
vfs_mnttab_modtimeupd()
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2625
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2626
	hrtime_t oldhrt, newhrt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2627
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2628
	ASSERT(RW_WRITE_HELD(&vfslist));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2629
	oldhrt = ts2hrt(&vfs_mnttab_mtime);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2630
	gethrestime(&vfs_mnttab_mtime);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2631
	newhrt = ts2hrt(&vfs_mnttab_mtime);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2632
	if (oldhrt == (hrtime_t)0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2633
		vfs_mnttab_ctime = vfs_mnttab_mtime;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2634
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2635
	 * Attempt to provide unique mtime (like uniqtime but not).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2636
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2637
	if (newhrt == oldhrt) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2638
		newhrt++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2639
		hrt2ts(newhrt, &vfs_mnttab_mtime);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2640
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2641
	pollwakeup(&vfs_pollhd, (short)POLLRDBAND);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2642
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2643
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2644
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2645
dounmount(struct vfs *vfsp, int flag, cred_t *cr)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2646
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2647
	vnode_t *coveredvp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2648
	int error;
1488
196daa2cf3db PSARC/2006/034 fsstat
rsb
parents: 994
diff changeset
  2649
	extern void teardown_vopstats(vfs_t *);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2650
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2651
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2652
	 * Get covered vnode. This will be NULL if the vfs is not linked
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2653
	 * into the file system name space (i.e., domount() with MNT_NOSPICE).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2654
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2655
	coveredvp = vfsp->vfs_vnodecovered;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2656
	ASSERT(coveredvp == NULL || vn_vfswlock_held(coveredvp));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2657
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2658
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2659
	 * Purge all dnlc entries for this vfs.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2660
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2661
	(void) dnlc_purge_vfsp(vfsp, 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2662
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2663
	/* For forcible umount, skip VFS_SYNC() since it may hang */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2664
	if ((flag & MS_FORCE) == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2665
		(void) VFS_SYNC(vfsp, 0, cr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2666
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2667
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2668
	 * Lock the vfs to maintain fs status quo during unmount.  This
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2669
	 * has to be done after the sync because ufs_update tries to acquire
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2670
	 * the vfs_reflock.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2671
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2672
	vfs_lock_wait(vfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2673
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2674
	if (error = VFS_UNMOUNT(vfsp, flag, cr)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2675
		vfs_unlock(vfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2676
		if (coveredvp != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2677
			vn_vfsunlock(coveredvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2678
	} else if (coveredvp != NULL) {
1488
196daa2cf3db PSARC/2006/034 fsstat
rsb
parents: 994
diff changeset
  2679
		teardown_vopstats(vfsp);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2680
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2681
		 * vfs_remove() will do a VN_RELE(vfsp->vfs_vnodecovered)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2682
		 * when it frees vfsp so we do a VN_HOLD() so we can
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2683
		 * continue to use coveredvp afterwards.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2684
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2685
		VN_HOLD(coveredvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2686
		vfs_remove(vfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2687
		vn_vfsunlock(coveredvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2688
		VN_RELE(coveredvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2689
	} else {
1488
196daa2cf3db PSARC/2006/034 fsstat
rsb
parents: 994
diff changeset
  2690
		teardown_vopstats(vfsp);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2691
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2692
		 * Release the reference to vfs that is not linked
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2693
		 * into the name space.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2694
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2695
		vfs_unlock(vfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2696
		VFS_RELE(vfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2697
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2698
	return (error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2699
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2700
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2701
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2702
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2703
 * Vfs_unmountall() is called by uadmin() to unmount all
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2704
 * mounted file systems (except the root file system) during shutdown.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2705
 * It follows the existing locking protocol when traversing the vfs list
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2706
 * to sync and unmount vfses. Even though there should be no
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2707
 * other thread running while the system is shutting down, it is prudent
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2708
 * to still follow the locking protocol.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2709
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2710
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2711
vfs_unmountall(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2712
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2713
	struct vfs *vfsp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2714
	struct vfs *prev_vfsp = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2715
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2716
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2717
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2718
	 * Toss all dnlc entries now so that the per-vfs sync
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2719
	 * and unmount operations don't have to slog through
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2720
	 * a bunch of uninteresting vnodes over and over again.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2721
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2722
	dnlc_purge();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2723
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2724
	vfs_list_lock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2725
	for (vfsp = rootvfs->vfs_prev; vfsp != rootvfs; vfsp = prev_vfsp) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2726
		prev_vfsp = vfsp->vfs_prev;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2727
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2728
		if (vfs_lock(vfsp) != 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2729
			continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2730
		error = vn_vfswlock(vfsp->vfs_vnodecovered);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2731
		vfs_unlock(vfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2732
		if (error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2733
			continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2734
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2735
		vfs_list_unlock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2736
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2737
		(void) VFS_SYNC(vfsp, SYNC_CLOSE, CRED());
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2738
		(void) dounmount(vfsp, 0, CRED());
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2739
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2740
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2741
		 * Since we dropped the vfslist lock above we must
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2742
		 * verify that next_vfsp still exists, else start over.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2743
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2744
		vfs_list_lock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2745
		for (vfsp = rootvfs->vfs_prev;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2746
			vfsp != rootvfs; vfsp = vfsp->vfs_prev)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2747
			if (vfsp == prev_vfsp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2748
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2749
		if (vfsp == rootvfs && prev_vfsp != rootvfs)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2750
			prev_vfsp = rootvfs->vfs_prev;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2751
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2752
	vfs_list_unlock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2753
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2754
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2755
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2756
 * Called to add an entry to the end of the vfs mount in progress list
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2757
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2758
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2759
vfs_addmip(dev_t dev, struct vfs *vfsp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2760
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2761
	struct ipmnt *mipp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2762
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2763
	mipp = (struct ipmnt *)kmem_alloc(sizeof (struct ipmnt), KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2764
	mipp->mip_next = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2765
	mipp->mip_dev = dev;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2766
	mipp->mip_vfsp = vfsp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2767
	mutex_enter(&vfs_miplist_mutex);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2768
	if (vfs_miplist_end != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2769
		vfs_miplist_end->mip_next = mipp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2770
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2771
		vfs_miplist = mipp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2772
	vfs_miplist_end = mipp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2773
	mutex_exit(&vfs_miplist_mutex);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2774
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2775
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2776
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2777
 * Called to remove an entry from the mount in progress list
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2778
 * Either because the mount completed or it failed.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2779
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2780
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2781
vfs_delmip(struct vfs *vfsp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2782
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2783
	struct ipmnt *mipp, *mipprev;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2784
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2785
	mutex_enter(&vfs_miplist_mutex);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2786
	mipprev = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2787
	for (mipp = vfs_miplist;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2788
		mipp && mipp->mip_vfsp != vfsp; mipp = mipp->mip_next) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2789
		mipprev = mipp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2790
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2791
	if (mipp == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2792
		return; /* shouldn't happen */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2793
	if (mipp == vfs_miplist_end)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2794
		vfs_miplist_end = mipprev;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2795
	if (mipprev == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2796
		vfs_miplist = mipp->mip_next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2797
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2798
		mipprev->mip_next = mipp->mip_next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2799
	mutex_exit(&vfs_miplist_mutex);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2800
	kmem_free(mipp, sizeof (struct ipmnt));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2801
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2802
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2803
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2804
 * vfs_add is called by a specific filesystem's mount routine to add
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2805
 * the new vfs into the vfs list/hash and to cover the mounted-on vnode.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2806
 * The vfs should already have been locked by the caller.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2807
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2808
 * coveredvp is NULL if this is the root.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2809
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2810
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2811
vfs_add(vnode_t *coveredvp, struct vfs *vfsp, int mflag)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2812
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2813
	int newflag;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2814
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2815
	ASSERT(vfs_lock_held(vfsp));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2816
	VFS_HOLD(vfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2817
	newflag = vfsp->vfs_flag;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2818
	if (mflag & MS_RDONLY)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2819
		newflag |= VFS_RDONLY;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2820
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2821
		newflag &= ~VFS_RDONLY;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2822
	if (mflag & MS_NOSUID)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2823
		newflag |= (VFS_NOSETUID|VFS_NODEVICES);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2824
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2825
		newflag &= ~(VFS_NOSETUID|VFS_NODEVICES);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2826
	if (mflag & MS_NOMNTTAB)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2827
		newflag |= VFS_NOMNTTAB;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2828
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2829
		newflag &= ~VFS_NOMNTTAB;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2830
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2831
	if (coveredvp != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2832
		ASSERT(vn_vfswlock_held(coveredvp));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2833
		coveredvp->v_vfsmountedhere = vfsp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2834
		VN_HOLD(coveredvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2835
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2836
	vfsp->vfs_vnodecovered = coveredvp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2837
	vfsp->vfs_flag = newflag;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2838
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2839
	vfs_list_add(vfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2840
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2841
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2842
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2843
 * Remove a vfs from the vfs list, null out the pointer from the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2844
 * covered vnode to the vfs (v_vfsmountedhere), and null out the pointer
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2845
 * from the vfs to the covered vnode (vfs_vnodecovered). Release the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2846
 * reference to the vfs and to the covered vnode.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2847
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2848
 * Called from dounmount after it's confirmed with the file system
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2849
 * that the unmount is legal.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2850
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2851
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2852
vfs_remove(struct vfs *vfsp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2853
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2854
	vnode_t *vp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2855
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2856
	ASSERT(vfs_lock_held(vfsp));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2857
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2858
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2859
	 * Can't unmount root.  Should never happen because fs will
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2860
	 * be busy.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2861
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2862
	if (vfsp == rootvfs)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2863
		cmn_err(CE_PANIC, "vfs_remove: unmounting root");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2864
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2865
	vfs_list_remove(vfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2866
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2867
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2868
	 * Unhook from the file system name space.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2869
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2870
	vp = vfsp->vfs_vnodecovered;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2871
	ASSERT(vn_vfswlock_held(vp));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2872
	vp->v_vfsmountedhere = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2873
	vfsp->vfs_vnodecovered = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2874
	VN_RELE(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2875
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2876
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2877
	 * Release lock and wakeup anybody waiting.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2878
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2879
	vfs_unlock(vfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2880
	VFS_RELE(vfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2881
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2882
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2883
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2884
 * Lock a filesystem to prevent access to it while mounting,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2885
 * unmounting and syncing.  Return EBUSY immediately if lock
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2886
 * can't be acquired.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2887
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2888
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2889
vfs_lock(vfs_t *vfsp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2890
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2891
	vn_vfslocks_entry_t *vpvfsentry;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2892
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2893
	vpvfsentry = vn_vfslocks_getlock(vfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2894
	if (rwst_tryenter(&vpvfsentry->ve_lock, RW_WRITER))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2895
		return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2896
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2897
	vn_vfslocks_rele(vpvfsentry);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2898
	return (EBUSY);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2899
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2900
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2901
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2902
vfs_rlock(vfs_t *vfsp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2903
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2904
	vn_vfslocks_entry_t *vpvfsentry;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2905
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2906
	vpvfsentry = vn_vfslocks_getlock(vfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2907
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2908
	if (rwst_tryenter(&vpvfsentry->ve_lock, RW_READER))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2909
		return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2910
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2911
	vn_vfslocks_rele(vpvfsentry);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2912
	return (EBUSY);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2913
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2914
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2915
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2916
vfs_lock_wait(vfs_t *vfsp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2917
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2918
	vn_vfslocks_entry_t *vpvfsentry;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2919
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2920
	vpvfsentry = vn_vfslocks_getlock(vfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2921
	rwst_enter(&vpvfsentry->ve_lock, RW_WRITER);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2922
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2923
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2924
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2925
vfs_rlock_wait(vfs_t *vfsp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2926
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2927
	vn_vfslocks_entry_t *vpvfsentry;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2928
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2929
	vpvfsentry = vn_vfslocks_getlock(vfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2930
	rwst_enter(&vpvfsentry->ve_lock, RW_READER);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2931
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2932
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2933
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2934
 * Unlock a locked filesystem.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2935
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2936
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2937
vfs_unlock(vfs_t *vfsp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2938
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2939
	vn_vfslocks_entry_t *vpvfsentry;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2940
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2941
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2942
	 * vfs_unlock will mimic sema_v behaviour to fix 4748018.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2943
	 * And these changes should remain for the patch changes as it is.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2944
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2945
	if (panicstr)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2946
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2947
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2948
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2949
	 * ve_refcount needs to be dropped twice here.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2950
	 * 1. To release refernce after a call to vfs_locks_getlock()
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2951
	 * 2. To release the reference from the locking routines like
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2952
	 *    vfs_rlock_wait/vfs_wlock_wait/vfs_wlock etc,.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2953
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2954
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2955
	vpvfsentry = vn_vfslocks_getlock(vfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2956
	vn_vfslocks_rele(vpvfsentry);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2957
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2958
	rwst_exit(&vpvfsentry->ve_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2959
	vn_vfslocks_rele(vpvfsentry);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2960
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2961
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2962
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2963
 * Utility routine that allows a filesystem to construct its
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2964
 * fsid in "the usual way" - by munging some underlying dev_t and
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2965
 * the filesystem type number into the 64-bit fsid.  Note that
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2966
 * this implicitly relies on dev_t persistence to make filesystem
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2967
 * id's persistent.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2968
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2969
 * There's nothing to prevent an individual fs from constructing its
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2970
 * fsid in a different way, and indeed they should.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2971
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2972
 * Since we want fsids to be 32-bit quantities (so that they can be
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2973
 * exported identically by either 32-bit or 64-bit APIs, as well as
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2974
 * the fact that fsid's are "known" to NFS), we compress the device
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2975
 * number given down to 32-bits, and panic if that isn't possible.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2976
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2977
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2978
vfs_make_fsid(fsid_t *fsi, dev_t dev, int val)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2979
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2980
	if (!cmpldev((dev32_t *)&fsi->val[0], dev))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2981
		panic("device number too big for fsid!");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2982
	fsi->val[1] = val;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2983
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2984
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2985
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2986
vfs_lock_held(vfs_t *vfsp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2987
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2988
	int held;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2989
	vn_vfslocks_entry_t *vpvfsentry;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2990
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2991
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2992
	 * vfs_lock_held will mimic sema_held behaviour
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2993
	 * if panicstr is set. And these changes should remain
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2994
	 * for the patch changes as it is.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2995
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2996
	if (panicstr)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2997
		return (1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2998
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2999
	vpvfsentry = vn_vfslocks_getlock(vfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3000
	held = rwst_lock_held(&vpvfsentry->ve_lock, RW_WRITER);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3001
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3002
	vn_vfslocks_rele(vpvfsentry);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3003
	return (held);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3004
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3005
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3006
struct _kthread *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3007
vfs_lock_owner(vfs_t *vfsp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3008
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3009
	struct _kthread *owner;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3010
	vn_vfslocks_entry_t *vpvfsentry;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3011
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3012
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3013
	 * vfs_wlock_held will mimic sema_held behaviour
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3014
	 * if panicstr is set. And these changes should remain
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3015
	 * for the patch changes as it is.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3016
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3017
	if (panicstr)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3018
		return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3019
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3020
	vpvfsentry = vn_vfslocks_getlock(vfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3021
	owner = rwst_owner(&vpvfsentry->ve_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3022
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3023
	vn_vfslocks_rele(vpvfsentry);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3024
	return (owner);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3025
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3026
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3027
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3028
 * vfs list locking.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3029
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3030
 * Rather than manipulate the vfslist lock directly, we abstract into lock
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3031
 * and unlock routines to allow the locking implementation to be changed for
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3032
 * clustering.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3033
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3034
 * Whenever the vfs list is modified through its hash links, the overall list
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3035
 * lock must be obtained before locking the relevant hash bucket.  But to see
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3036
 * whether a given vfs is on the list, it suffices to obtain the lock for the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3037
 * hash bucket without getting the overall list lock.  (See getvfs() below.)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3038
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3039
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3040
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3041
vfs_list_lock()
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3042
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3043
	rw_enter(&vfslist, RW_WRITER);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3044
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3045
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3046
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3047
vfs_list_read_lock()
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3048
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3049
	rw_enter(&vfslist, RW_READER);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3050
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3051
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3052
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3053
vfs_list_unlock()
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3054
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3055
	rw_exit(&vfslist);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3056
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3057
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3058
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3059
 * Low level worker routines for adding entries to and removing entries from
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3060
 * the vfs list.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3061
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3062
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3063
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3064
vfs_hash_add(struct vfs *vfsp, int insert_at_head)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3065
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3066
	int vhno;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3067
	struct vfs **hp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3068
	dev_t dev;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3069
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3070
	ASSERT(RW_WRITE_HELD(&vfslist));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3071
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3072
	dev = expldev(vfsp->vfs_fsid.val[0]);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3073
	vhno = VFSHASH(getmajor(dev), getminor(dev));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3074
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3075
	mutex_enter(&rvfs_list[vhno].rvfs_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3076
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3077
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3078
	 * Link into the hash table, inserting it at the end, so that LOFS
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3079
	 * with the same fsid as UFS (or other) file systems will not hide the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3080
	 * UFS.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3081
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3082
	if (insert_at_head) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3083
		vfsp->vfs_hash = rvfs_list[vhno].rvfs_head;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3084
		rvfs_list[vhno].rvfs_head = vfsp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3085
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3086
		for (hp = &rvfs_list[vhno].rvfs_head; *hp != NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3087
		    hp = &(*hp)->vfs_hash)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3088
			continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3089
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3090
		 * hp now contains the address of the pointer to update
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3091
		 * to effect the insertion.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3092
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3093
		vfsp->vfs_hash = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3094
		*hp = vfsp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3095
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3096
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3097
	rvfs_list[vhno].rvfs_len++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3098
	mutex_exit(&rvfs_list[vhno].rvfs_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3099
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3100
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3101
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3102
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3103
vfs_hash_remove(struct vfs *vfsp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3104
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3105
	int vhno;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3106
	struct vfs *tvfsp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3107
	dev_t dev;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3108
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3109
	ASSERT(RW_WRITE_HELD(&vfslist));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3110
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3111
	dev = expldev(vfsp->vfs_fsid.val[0]);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3112
	vhno = VFSHASH(getmajor(dev), getminor(dev));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3113
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3114
	mutex_enter(&rvfs_list[vhno].rvfs_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3115
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3116
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3117
	 * Remove from hash.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3118
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3119
	if (rvfs_list[vhno].rvfs_head == vfsp) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3120
		rvfs_list[vhno].rvfs_head = vfsp->vfs_hash;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3121
		rvfs_list[vhno].rvfs_len--;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3122
		goto foundit;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3123
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3124
	for (tvfsp = rvfs_list[vhno].rvfs_head; tvfsp != NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3125
	    tvfsp = tvfsp->vfs_hash) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3126
		if (tvfsp->vfs_hash == vfsp) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3127
			tvfsp->vfs_hash = vfsp->vfs_hash;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3128
			rvfs_list[vhno].rvfs_len--;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3129
			goto foundit;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3130
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3131
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3132
	cmn_err(CE_WARN, "vfs_list_remove: vfs not found in hash");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3133
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3134
foundit:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3135
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3136
	mutex_exit(&rvfs_list[vhno].rvfs_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3137
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3138
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3139
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3140
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3141
vfs_list_add(struct vfs *vfsp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3142
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3143
	zone_t *zone;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3144
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3145
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3146
	 * The zone that owns the mount is the one that performed the mount.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3147
	 * Note that this isn't necessarily the same as the zone mounted into.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3148
	 * The corresponding zone_rele() will be done when the vfs_t is
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3149
	 * being free'd.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3150
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3151
	vfsp->vfs_zone = curproc->p_zone;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3152
	zone_hold(vfsp->vfs_zone);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3153
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3154
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3155
	 * Find the zone mounted into, and put this mount on its vfs list.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3156
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3157
	zone = zone_find_by_path(refstr_value(vfsp->vfs_mntpt));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3158
	ASSERT(zone != NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3159
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3160
	 * Special casing for the root vfs.  This structure is allocated
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3161
	 * statically and hooked onto rootvfs at link time.  During the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3162
	 * vfs_mountroot call at system startup time, the root file system's
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3163
	 * VFS_MOUNTROOT routine will call vfs_add with this root vfs struct
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3164
	 * as argument.  The code below must detect and handle this special
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3165
	 * case.  The only apparent justification for this special casing is
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3166
	 * to ensure that the root file system appears at the head of the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3167
	 * list.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3168
	 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3169
	 * XXX:	I'm assuming that it's ok to do normal list locking when
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3170
	 *	adding the entry for the root file system (this used to be
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3171
	 *	done with no locks held).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3172
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3173
	vfs_list_lock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3174
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3175
	 * Link into the vfs list proper.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3176
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3177
	if (vfsp == &root) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3178
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3179
		 * Assert: This vfs is already on the list as its first entry.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3180
		 * Thus, there's nothing to do.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3181
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3182
		ASSERT(rootvfs == vfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3183
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3184
		 * Add it to the head of the global zone's vfslist.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3185
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3186
		ASSERT(zone == global_zone);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3187
		ASSERT(zone->zone_vfslist == NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3188
		zone->zone_vfslist = vfsp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3189
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3190
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3191
		 * Link to end of list using vfs_prev (as rootvfs is now a
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3192
		 * doubly linked circular list) so list is in mount order for
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3193
		 * mnttab use.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3194
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3195
		rootvfs->vfs_prev->vfs_next = vfsp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3196
		vfsp->vfs_prev = rootvfs->vfs_prev;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3197
		rootvfs->vfs_prev = vfsp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3198
		vfsp->vfs_next = rootvfs;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3199
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3200
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3201
		 * Do it again for the zone-private list (which may be NULL).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3202
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3203
		if (zone->zone_vfslist == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3204
			ASSERT(zone != global_zone);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3205
			zone->zone_vfslist = vfsp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3206
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3207
			zone->zone_vfslist->vfs_zone_prev->vfs_zone_next = vfsp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3208
			vfsp->vfs_zone_prev = zone->zone_vfslist->vfs_zone_prev;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3209
			zone->zone_vfslist->vfs_zone_prev = vfsp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3210
			vfsp->vfs_zone_next = zone->zone_vfslist;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3211
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3212
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3213
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3214
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3215
	 * Link into the hash table, inserting it at the end, so that LOFS
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3216
	 * with the same fsid as UFS (or other) file systems will not hide
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3217
	 * the UFS.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3218
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3219
	vfs_hash_add(vfsp, 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3220
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3221
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3222
	 * update the mnttab modification time
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3223
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3224
	vfs_mnttab_modtimeupd();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3225
	vfs_list_unlock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3226
	zone_rele(zone);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3227
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3228
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3229
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3230
vfs_list_remove(struct vfs *vfsp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3231
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3232
	zone_t *zone;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3233
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3234
	zone = zone_find_by_path(refstr_value(vfsp->vfs_mntpt));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3235
	ASSERT(zone != NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3236
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3237
	 * Callers are responsible for preventing attempts to unmount the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3238
	 * root.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3239
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3240
	ASSERT(vfsp != rootvfs);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3241
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3242
	vfs_list_lock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3243
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3244
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3245
	 * Remove from hash.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3246
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3247
	vfs_hash_remove(vfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3248
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3249
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3250
	 * Remove from vfs list.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3251
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3252
	vfsp->vfs_prev->vfs_next = vfsp->vfs_next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3253
	vfsp->vfs_next->vfs_prev = vfsp->vfs_prev;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3254
	vfsp->vfs_next = vfsp->vfs_prev = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3255
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3256
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3257
	 * Remove from zone-specific vfs list.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3258
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3259
	if (zone->zone_vfslist == vfsp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3260
		zone->zone_vfslist = vfsp->vfs_zone_next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3261
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3262
	if (vfsp->vfs_zone_next == vfsp) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3263
		ASSERT(vfsp->vfs_zone_prev == vfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3264
		ASSERT(zone->zone_vfslist == vfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3265
		zone->zone_vfslist = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3266
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3267
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3268
	vfsp->vfs_zone_prev->vfs_zone_next = vfsp->vfs_zone_next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3269
	vfsp->vfs_zone_next->vfs_zone_prev = vfsp->vfs_zone_prev;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3270
	vfsp->vfs_zone_next = vfsp->vfs_zone_prev = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3271
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3272
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3273
	 * update the mnttab modification time
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3274
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3275
	vfs_mnttab_modtimeupd();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3276
	vfs_list_unlock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3277
	zone_rele(zone);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3278
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3279
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3280
struct vfs *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3281
getvfs(fsid_t *fsid)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3282
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3283
	struct vfs *vfsp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3284
	int val0 = fsid->val[0];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3285
	int val1 = fsid->val[1];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3286
	dev_t dev = expldev(val0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3287
	int vhno = VFSHASH(getmajor(dev), getminor(dev));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3288
	kmutex_t *hmp = &rvfs_list[vhno].rvfs_lock;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3289
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3290
	mutex_enter(hmp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3291
	for (vfsp = rvfs_list[vhno].rvfs_head; vfsp; vfsp = vfsp->vfs_hash) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3292
		if (vfsp->vfs_fsid.val[0] == val0 &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3293
		    vfsp->vfs_fsid.val[1] == val1) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3294
			VFS_HOLD(vfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3295
			mutex_exit(hmp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3296
			return (vfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3297
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3298
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3299
	mutex_exit(hmp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3300
	return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3301
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3302
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3303
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3304
 * Search the vfs mount in progress list for a specified device/vfs entry.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3305
 * Returns 0 if the first entry in the list that the device matches has the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3306
 * given vfs pointer as well.  If the device matches but a different vfs
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3307
 * pointer is encountered in the list before the given vfs pointer then
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3308
 * a 1 is returned.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3309
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3310
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3311
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3312
vfs_devmounting(dev_t dev, struct vfs *vfsp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3313
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3314
	int retval = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3315
	struct ipmnt *mipp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3316
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3317
	mutex_enter(&vfs_miplist_mutex);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3318
	for (mipp = vfs_miplist; mipp != NULL; mipp = mipp->mip_next) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3319
		if (mipp->mip_dev == dev) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3320
			if (mipp->mip_vfsp != vfsp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3321
				retval = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3322
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3323
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3324
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3325
	mutex_exit(&vfs_miplist_mutex);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3326
	return (retval);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3327
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3328
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3329
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3330
 * Search the vfs list for a specified device.  Returns 1, if entry is found
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3331
 * or 0 if no suitable entry is found.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3332
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3333
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3334
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3335
vfs_devismounted(dev_t dev)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3336
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3337
	struct vfs *vfsp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3338
	int found;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3339
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3340
	vfs_list_read_lock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3341
	vfsp = rootvfs;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3342
	found = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3343
	do {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3344
		if (vfsp->vfs_dev == dev) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3345
			found = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3346
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3347
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3348
		vfsp = vfsp->vfs_next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3349
	} while (vfsp != rootvfs);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3350
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3351
	vfs_list_unlock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3352
	return (found);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3353
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3354
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3355
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3356
 * Search the vfs list for a specified device.  Returns a pointer to it
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3357
 * or NULL if no suitable entry is found. The caller of this routine
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3358
 * is responsible for releasing the returned vfs pointer.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3359
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3360
struct vfs *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3361
vfs_dev2vfsp(dev_t dev)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3362
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3363
	struct vfs *vfsp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3364
	int found;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3365
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3366
	vfs_list_read_lock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3367
	vfsp = rootvfs;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3368
	found = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3369
	do {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3370
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3371
		 * The following could be made more efficient by making
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3372
		 * the entire loop use vfs_zone_next if the call is from
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3373
		 * a zone.  The only callers, however, ustat(2) and
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3374
		 * umount2(2), don't seem to justify the added
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3375
		 * complexity at present.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3376
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3377
		if (vfsp->vfs_dev == dev &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3378
		    ZONE_PATH_VISIBLE(refstr_value(vfsp->vfs_mntpt),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3379
		    curproc->p_zone)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3380
			VFS_HOLD(vfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3381
			found = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3382
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3383
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3384
		vfsp = vfsp->vfs_next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3385
	} while (vfsp != rootvfs);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3386
	vfs_list_unlock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3387
	return (found ? vfsp: NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3388
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3389
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3390
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3391
 * Search the vfs list for a specified mntpoint.  Returns a pointer to it
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3392
 * or NULL if no suitable entry is found. The caller of this routine
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3393
 * is responsible for releasing the returned vfs pointer.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3394
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3395
 * Note that if multiple mntpoints match, the last one matching is
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3396
 * returned in an attempt to return the "top" mount when overlay
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3397
 * mounts are covering the same mount point.  This is accomplished by starting
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3398
 * at the end of the list and working our way backwards, stopping at the first
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3399
 * matching mount.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3400
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3401
struct vfs *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3402
vfs_mntpoint2vfsp(const char *mp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3403
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3404
	struct vfs *vfsp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3405
	struct vfs *retvfsp = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3406
	zone_t *zone = curproc->p_zone;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3407
	struct vfs *list;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3408
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3409
	vfs_list_read_lock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3410
	if (getzoneid() == GLOBAL_ZONEID) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3411
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3412
		 * The global zone may see filesystems in any zone.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3413
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3414
		vfsp = rootvfs->vfs_prev;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3415
		do {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3416
			if (strcmp(refstr_value(vfsp->vfs_mntpt), mp) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3417
				retvfsp = vfsp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3418
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3419
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3420
			vfsp = vfsp->vfs_prev;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3421
		} while (vfsp != rootvfs->vfs_prev);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3422
	} else if ((list = zone->zone_vfslist) != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3423
		const char *mntpt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3424
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3425
		vfsp = list->vfs_zone_prev;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3426
		do {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3427
			mntpt = refstr_value(vfsp->vfs_mntpt);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3428
			mntpt = ZONE_PATH_TRANSLATE(mntpt, zone);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3429
			if (strcmp(mntpt, mp) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3430
				retvfsp = vfsp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3431
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3432
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3433
			vfsp = vfsp->vfs_zone_prev;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3434
		} while (vfsp != list->vfs_zone_prev);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3435
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3436
	if (retvfsp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3437
		VFS_HOLD(retvfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3438
	vfs_list_unlock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3439
	return (retvfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3440
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3441
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3442
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3443
 * Search the vfs list for a specified vfsops.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3444
 * if vfs entry is found then return 1, else 0.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3445
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3446
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3447
vfs_opsinuse(vfsops_t *ops)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3448
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3449
	struct vfs *vfsp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3450
	int found;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3451
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3452
	vfs_list_read_lock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3453
	vfsp = rootvfs;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3454
	found = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3455
	do {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3456
		if (vfs_getops(vfsp) == ops) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3457
			found = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3458
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3459
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3460
		vfsp = vfsp->vfs_next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3461
	} while (vfsp != rootvfs);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3462
	vfs_list_unlock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3463
	return (found);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3464
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3465
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3466
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3467
 * Allocate an entry in vfssw for a file system type
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3468
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3469
struct vfssw *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3470
allocate_vfssw(char *type)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3471
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3472
	struct vfssw *vswp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3473
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3474
	if (type[0] == '\0' || strlen(type) + 1 > _ST_FSTYPSZ) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3475
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3476
		 * The vfssw table uses the empty string to identify an
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3477
		 * available entry; we cannot add any type which has
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3478
		 * a leading NUL. The string length is limited to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3479
		 * the size of the st_fstype array in struct stat.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3480
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3481
		return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3482
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3483
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3484
	ASSERT(VFSSW_WRITE_LOCKED());
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3485
	for (vswp = &vfssw[1]; vswp < &vfssw[nfstype]; vswp++)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3486
		if (!ALLOCATED_VFSSW(vswp)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3487
			vswp->vsw_name = kmem_alloc(strlen(type) + 1, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3488
			(void) strcpy(vswp->vsw_name, type);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3489
			ASSERT(vswp->vsw_count == 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3490
			vswp->vsw_count = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3491
			mutex_init(&vswp->vsw_lock, NULL, MUTEX_DEFAULT, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3492
			return (vswp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3493
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3494
	return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3495
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3496
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3497
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3498
 * Impose additional layer of translation between vfstype names
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3499
 * and module names in the filesystem.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3500
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3501
static char *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3502
vfs_to_modname(char *vfstype)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3503
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3504
	if (strcmp(vfstype, "proc") == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3505
		vfstype = "procfs";
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3506
	} else if (strcmp(vfstype, "fd") == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3507
		vfstype = "fdfs";
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3508
	} else if (strncmp(vfstype, "nfs", 3) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3509
		vfstype = "nfs";
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3510
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3511
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3512
	return (vfstype);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3513
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3514
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3515
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3516
 * Find a vfssw entry given a file system type name.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3517
 * Try to autoload the filesystem if it's not found.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3518
 * If it's installed, return the vfssw locked to prevent unloading.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3519
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3520
struct vfssw *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3521
vfs_getvfssw(char *type)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3522
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3523
	struct vfssw *vswp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3524
	char	*modname;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3525
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3526
	RLOCK_VFSSW();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3527
	vswp = vfs_getvfsswbyname(type);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3528
	modname = vfs_to_modname(type);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3529
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3530
	if (rootdir == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3531
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3532
		 * If we haven't yet loaded the root file system, then our
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3533
		 * _init won't be called until later. Allocate vfssw entry,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3534
		 * because mod_installfs won't be called.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3535
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3536
		if (vswp == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3537
			RUNLOCK_VFSSW();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3538
			WLOCK_VFSSW();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3539
			if ((vswp = vfs_getvfsswbyname(type)) == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3540
				if ((vswp = allocate_vfssw(type)) == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3541
					WUNLOCK_VFSSW();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3542
					return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3543
				}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3544
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3545
			WUNLOCK_VFSSW();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3546
			RLOCK_VFSSW();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3547
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3548
		if (!VFS_INSTALLED(vswp)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3549
			RUNLOCK_VFSSW();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3550
			(void) modloadonly("fs", modname);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3551
		} else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3552
			RUNLOCK_VFSSW();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3553
		return (vswp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3554
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3555
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3556
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3557
	 * Try to load the filesystem.  Before calling modload(), we drop
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3558
	 * our lock on the VFS switch table, and pick it up after the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3559
	 * module is loaded.  However, there is a potential race:  the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3560
	 * module could be unloaded after the call to modload() completes
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3561
	 * but before we pick up the lock and drive on.  Therefore,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3562
	 * we keep reloading the module until we've loaded the module
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3563
	 * _and_ we have the lock on the VFS switch table.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3564
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3565
	while (vswp == NULL || !VFS_INSTALLED(vswp)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3566
		RUNLOCK_VFSSW();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3567
		if (modload("fs", modname) == -1)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3568
			return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3569
		RLOCK_VFSSW();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3570
		if (vswp == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3571
			if ((vswp = vfs_getvfsswbyname(type)) == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3572
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3573
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3574
	RUNLOCK_VFSSW();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3575
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3576
	return (vswp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3577
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3578
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3579
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3580
 * Find a vfssw entry given a file system type name.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3581
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3582
struct vfssw *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3583
vfs_getvfsswbyname(char *type)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3584
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3585
	struct vfssw *vswp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3586
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3587
	ASSERT(VFSSW_LOCKED());
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3588
	if (type == NULL || *type == '\0')
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3589
		return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3590
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3591
	for (vswp = &vfssw[1]; vswp < &vfssw[nfstype]; vswp++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3592
		if (strcmp(type, vswp->vsw_name) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3593
			vfs_refvfssw(vswp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3594
			return (vswp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3595
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3596
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3597
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3598
	return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3599
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3600
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3601
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3602
 * Find a vfssw entry given a set of vfsops.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3603
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3604
struct vfssw *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3605
vfs_getvfsswbyvfsops(vfsops_t *vfsops)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3606
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3607
	struct vfssw *vswp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3608
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3609
	RLOCK_VFSSW();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3610
	for (vswp = &vfssw[1]; vswp < &vfssw[nfstype]; vswp++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3611
		if (ALLOCATED_VFSSW(vswp) && &vswp->vsw_vfsops == vfsops) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3612
			vfs_refvfssw(vswp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3613
			RUNLOCK_VFSSW();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3614
			return (vswp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3615
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3616
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3617
	RUNLOCK_VFSSW();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3618
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3619
	return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3620
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3621
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3622
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3623
 * Reference a vfssw entry.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3624
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3625
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3626
vfs_refvfssw(struct vfssw *vswp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3627
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3628
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3629
	mutex_enter(&vswp->vsw_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3630
	vswp->vsw_count++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3631
	mutex_exit(&vswp->vsw_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3632
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3633
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3634
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3635
 * Unreference a vfssw entry.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3636
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3637
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3638
vfs_unrefvfssw(struct vfssw *vswp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3639
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3640
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3641
	mutex_enter(&vswp->vsw_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3642
	vswp->vsw_count--;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3643
	mutex_exit(&vswp->vsw_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3644
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3645
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3646
int sync_timeout = 30;		/* timeout for syncing a page during panic */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3647
int sync_timeleft;		/* portion of sync_timeout remaining */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3648
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3649
static int sync_retries = 20;	/* number of retries when not making progress */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3650
static int sync_triesleft;	/* portion of sync_retries remaining */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3651
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3652
static pgcnt_t old_pgcnt, new_pgcnt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3653
static int new_bufcnt, old_bufcnt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3654
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3655
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3656
 * Sync all of the mounted filesystems, and then wait for the actual i/o to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3657
 * complete.  We wait by counting the number of dirty pages and buffers,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3658
 * pushing them out using bio_busy() and page_busy(), and then counting again.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3659
 * This routine is used during both the uadmin A_SHUTDOWN code as well as
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3660
 * the SYNC phase of the panic code (see comments in panic.c).  It should only
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3661
 * be used after some higher-level mechanism has quiesced the system so that
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3662
 * new writes are not being initiated while we are waiting for completion.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3663
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3664
 * To ensure finite running time, our algorithm uses two timeout mechanisms:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3665
 * sync_timeleft (a timer implemented by the omnipresent deadman() cyclic), and
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3666
 * sync_triesleft (a progress counter used by the vfs_syncall() loop below).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3667
 * Together these ensure that syncing completes if our i/o paths are stuck.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3668
 * The counters are declared above so they can be found easily in the debugger.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3669
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3670
 * The sync_timeleft counter is reset by bio_busy() and page_busy() using the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3671
 * vfs_syncprogress() subroutine whenever we make progress through the lists of
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3672
 * pages and buffers.  It is decremented and expired by the deadman() cyclic.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3673
 * When vfs_syncall() decides it is done, we disable the deadman() counter by
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3674
 * setting sync_timeleft to zero.  This timer guards against vfs_syncall()
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3675
 * deadlocking or hanging inside of a broken filesystem or driver routine.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3676
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3677
 * The sync_triesleft counter is updated by vfs_syncall() itself.  If we make
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3678
 * sync_retries consecutive calls to bio_busy() and page_busy() without
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3679
 * decreasing either the number of dirty buffers or dirty pages below the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3680
 * lowest count we have seen so far, we give up and return from vfs_syncall().
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3681
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3682
 * Each loop iteration ends with a call to delay() one second to allow time for
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3683
 * i/o completion and to permit the user time to read our progress messages.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3684
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3685
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3686
vfs_syncall(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3687
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3688
	if (rootdir == NULL && !modrootloaded)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3689
		return; /* panic during boot - no filesystems yet */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3690
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3691
	printf("syncing file systems...");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3692
	vfs_syncprogress();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3693
	sync();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3694
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3695
	vfs_syncprogress();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3696
	sync_triesleft = sync_retries;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3697
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3698
	old_bufcnt = new_bufcnt = INT_MAX;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3699
	old_pgcnt = new_pgcnt = ULONG_MAX;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3700
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3701
	while (sync_triesleft > 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3702
		old_bufcnt = MIN(old_bufcnt, new_bufcnt);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3703
		old_pgcnt = MIN(old_pgcnt, new_pgcnt);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3704
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3705
		new_bufcnt = bio_busy(B_TRUE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3706
		new_pgcnt = page_busy(B_TRUE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3707
		vfs_syncprogress();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3708
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3709
		if (new_bufcnt == 0 && new_pgcnt == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3710
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3711
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3712
		if (new_bufcnt < old_bufcnt || new_pgcnt < old_pgcnt)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3713
			sync_triesleft = sync_retries;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3714
		else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3715
			sync_triesleft--;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3716
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3717
		if (new_bufcnt)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3718
			printf(" [%d]", new_bufcnt);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3719
		if (new_pgcnt)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3720
			printf(" %lu", new_pgcnt);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3721
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3722
		delay(hz);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3723
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3724
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3725
	if (new_bufcnt != 0 || new_pgcnt != 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3726
		printf(" done (not all i/o completed)\n");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3727
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3728
		printf(" done\n");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3729
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3730
	sync_timeleft = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3731
	delay(hz);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3732
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3733
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3734
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3735
 * If we are in the middle of the sync phase of panic, reset sync_timeleft to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3736
 * sync_timeout to indicate that we are making progress and the deadman()
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3737
 * omnipresent cyclic should not yet time us out.  Note that it is safe to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3738
 * store to sync_timeleft here since the deadman() is firing at high-level
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3739
 * on top of us.  If we are racing with the deadman(), either the deadman()
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3740
 * will decrement the old value and then we will reset it, or we will
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3741
 * reset it and then the deadman() will immediately decrement it.  In either
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3742
 * case, correct behavior results.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3743
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3744
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3745
vfs_syncprogress(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3746
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3747
	if (panicstr)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3748
		sync_timeleft = sync_timeout;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3749
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3750
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3751
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3752
 * Map VFS flags to statvfs flags.  These shouldn't really be separate
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3753
 * flags at all.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3754
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3755
uint_t
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3756
vf_to_stf(uint_t vf)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3757
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3758
	uint_t stf = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3759
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3760
	if (vf & VFS_RDONLY)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3761
		stf |= ST_RDONLY;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3762
	if (vf & VFS_NOSETUID)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3763
		stf |= ST_NOSUID;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3764
	if (vf & VFS_NOTRUNC)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3765
		stf |= ST_NOTRUNC;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3766
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3767
	return (stf);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3768
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3769
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3770
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3771
 * Use old-style function prototype for vfsstray() so
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3772
 * that we can use it anywhere in the vfsops structure.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3773
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3774
int vfsstray();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3775
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3776
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3777
 * Entries for (illegal) fstype 0.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3778
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3779
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3780
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3781
vfsstray_sync(struct vfs *vfsp, short arg, struct cred *cr)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3782
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3783
	cmn_err(CE_PANIC, "stray vfs operation");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3784
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3785
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3786
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3787
vfsops_t vfs_strayops = {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3788
	vfsstray,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3789
	vfsstray,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3790
	vfsstray,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3791
	vfsstray,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3792
	vfsstray_sync,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3793
	vfsstray,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3794
	vfsstray,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3795
	vfsstray
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3796
};
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3797
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3798
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3799
 * Entries for (illegal) fstype 0.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3800
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3801
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3802
vfsstray(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3803
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3804
	cmn_err(CE_PANIC, "stray vfs operation");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3805
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3806
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3807
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3808
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3809
 * Support for dealing with forced UFS unmount and its interaction with
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3810
 * LOFS. Could be used by any filesystem.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3811
 * See bug 1203132.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3812
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3813
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3814
vfs_EIO(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3815
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3816
	return (EIO);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3817
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3818
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3819
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3820
 * We've gotta define the op for sync separately, since the compiler gets
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3821
 * confused if we mix and match ANSI and normal style prototypes when
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3822
 * a "short" argument is present and spits out a warning.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3823
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3824
/*ARGSUSED*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3825
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3826
vfs_EIO_sync(struct vfs *vfsp, short arg, struct cred *cr)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3827
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3828
	return (EIO);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3829
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3830
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3831
vfs_t EIO_vfs;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3832
vfsops_t *EIO_vfsops;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3833
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3834
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3835
 * Called from startup() to initialize all loaded vfs's
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3836
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3837
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3838
vfsinit(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3839
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3840
	struct vfssw *vswp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3841
	int error;
1520
2fb01d86c1c1 6391295 fop_create() panic when running svvs over ZFS
rsb
parents: 1488
diff changeset
  3842
	extern int vopstats_enabled;
1488
196daa2cf3db PSARC/2006/034 fsstat
rsb
parents: 994
diff changeset
  3843
	extern void vopstats_startup();
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3844
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3845
	static const fs_operation_def_t EIO_vfsops_template[] = {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3846
		VFSNAME_MOUNT,		vfs_EIO,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3847
		VFSNAME_UNMOUNT,	vfs_EIO,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3848
		VFSNAME_ROOT,		vfs_EIO,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3849
		VFSNAME_STATVFS,	vfs_EIO,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3850
		VFSNAME_SYNC, (fs_generic_func_p) vfs_EIO_sync,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3851
		VFSNAME_VGET,		vfs_EIO,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3852
		VFSNAME_MOUNTROOT,	vfs_EIO,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3853
		VFSNAME_FREEVFS,	vfs_EIO,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3854
		VFSNAME_VNSTATE,	vfs_EIO,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3855
		NULL, NULL
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3856
	};
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3857
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3858
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3859
	/* Initialize the vnode cache (file systems may use it during init). */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3860
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3861
	vn_create_cache();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3862
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3863
	/* Setup event monitor framework */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3864
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3865
	fem_init();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3866
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3867
	/* Initialize the dummy stray file system type. */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3868
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3869
	vfssw[0].vsw_vfsops = vfs_strayops;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3870
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3871
	/* Initialize the dummy EIO file system. */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3872
	error = vfs_makefsops(EIO_vfsops_template, &EIO_vfsops);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3873
	if (error != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3874
		cmn_err(CE_WARN, "vfsinit: bad EIO vfs ops template");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3875
		/* Shouldn't happen, but not bad enough to panic */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3876
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3877
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3878
	VFS_INIT(&EIO_vfs, EIO_vfsops, (caddr_t)NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3879
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3880
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3881
	 * Default EIO_vfs.vfs_flag to VFS_UNMOUNTED so a lookup
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3882
	 * on this vfs can immediately notice it's invalid.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3883
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3884
	EIO_vfs.vfs_flag |= VFS_UNMOUNTED;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3885
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3886
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3887
	 * Call the init routines of non-loadable filesystems only.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3888
	 * Filesystems which are loaded as separate modules will be
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3889
	 * initialized by the module loading code instead.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3890
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3891
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3892
	for (vswp = &vfssw[1]; vswp < &vfssw[nfstype]; vswp++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3893
		RLOCK_VFSSW();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3894
		if (vswp->vsw_init != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3895
			(*vswp->vsw_init)(vswp - vfssw, vswp->vsw_name);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3896
		RUNLOCK_VFSSW();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3897
	}
1488
196daa2cf3db PSARC/2006/034 fsstat
rsb
parents: 994
diff changeset
  3898
196daa2cf3db PSARC/2006/034 fsstat
rsb
parents: 994
diff changeset
  3899
	vopstats_startup();
1520
2fb01d86c1c1 6391295 fop_create() panic when running svvs over ZFS
rsb
parents: 1488
diff changeset
  3900
2fb01d86c1c1 6391295 fop_create() panic when running svvs over ZFS
rsb
parents: 1488
diff changeset
  3901
	if (vopstats_enabled) {
2fb01d86c1c1 6391295 fop_create() panic when running svvs over ZFS
rsb
parents: 1488
diff changeset
  3902
		/* EIO_vfs can collect stats, but we don't retrieve them */
2fb01d86c1c1 6391295 fop_create() panic when running svvs over ZFS
rsb
parents: 1488
diff changeset
  3903
		initialize_vopstats(&EIO_vfs.vfs_vopstats);
2fb01d86c1c1 6391295 fop_create() panic when running svvs over ZFS
rsb
parents: 1488
diff changeset
  3904
		EIO_vfs.vfs_fstypevsp = NULL;
2fb01d86c1c1 6391295 fop_create() panic when running svvs over ZFS
rsb
parents: 1488
diff changeset
  3905
		EIO_vfs.vfs_vskap = NULL;
2fb01d86c1c1 6391295 fop_create() panic when running svvs over ZFS
rsb
parents: 1488
diff changeset
  3906
		EIO_vfs.vfs_flag |= VFS_STATS;
2fb01d86c1c1 6391295 fop_create() panic when running svvs over ZFS
rsb
parents: 1488
diff changeset
  3907
	}
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3908
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3909
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3910
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3911
 * Increments the vfs reference count by one atomically.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3912
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3913
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3914
vfs_hold(vfs_t *vfsp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3915
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3916
	atomic_add_32(&vfsp->vfs_count, 1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3917
	ASSERT(vfsp->vfs_count != 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3918
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3919
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3920
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3921
 * Decrements the vfs reference count by one atomically. When
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3922
 * vfs reference count becomes zero, it calls the file system
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3923
 * specific vfs_freevfs() to free up the resources.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3924
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3925
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3926
vfs_rele(vfs_t *vfsp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3927
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3928
	ASSERT(vfsp->vfs_count != 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3929
	if (atomic_add_32_nv(&vfsp->vfs_count, -1) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3930
		VFS_FREEVFS(vfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3931
		if (vfsp->vfs_zone)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3932
			zone_rele(vfsp->vfs_zone);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3933
		vfs_freemnttab(vfsp);
1925
91047fd43318 PSARC 2006/270 vfs_femhead change to vfs_implp
rsb
parents: 1678
diff changeset
  3934
		if (vfsp->vfs_implp)
91047fd43318 PSARC 2006/270 vfs_femhead change to vfs_implp
rsb
parents: 1678
diff changeset
  3935
			vfsimpl_teardown(vfsp);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3936
		sema_destroy(&vfsp->vfs_reflock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3937
		kmem_free(vfsp, sizeof (*vfsp));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3938
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3939
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3940
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3941
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3942
 * Generic operations vector support.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3943
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3944
 * This is used to build operations vectors for both the vfs and vnode.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3945
 * It's normally called only when a file system is loaded.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3946
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3947
 * There are many possible algorithms for this, including the following:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3948
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3949
 *   (1) scan the list of known operations; for each, see if the file system
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3950
 *       includes an entry for it, and fill it in as appropriate.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3951
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3952
 *   (2) set up defaults for all known operations.  scan the list of ops
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3953
 *       supplied by the file system; for each which is both supplied and
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3954
 *       known, fill it in.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3955
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3956
 *   (3) sort the lists of known ops & supplied ops; scan the list, filling
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3957
 *       in entries as we go.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3958
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3959
 * we choose (1) for simplicity, and because performance isn't critical here.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3960
 * note that (2) could be sped up using a precomputed hash table on known ops.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3961
 * (3) could be faster than either, but only if the lists were very large or
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3962
 * supplied in sorted order.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3963
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3964
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3965
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3966
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3967
fs_build_vector(void *vector, int *unused_ops,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3968
    const fs_operation_trans_def_t *translation,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3969
    const fs_operation_def_t *operations)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3970
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3971
	int i, num_trans, num_ops, used;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3972
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3973
	/* Count the number of translations and the number of supplied */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3974
	/* operations. */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3975
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3976
	{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3977
		const fs_operation_trans_def_t *p;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3978
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3979
		for (num_trans = 0, p = translation;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3980
		    p->name != NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3981
		    num_trans++, p++)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3982
			;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3983
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3984
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3985
	{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3986
		const fs_operation_def_t *p;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3987
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3988
		for (num_ops = 0, p = operations;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3989
		    p->name != NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3990
		    num_ops++, p++)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3991
			;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3992
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3993
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3994
	/* Walk through each operation known to our caller.  There will be */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3995
	/* one entry in the supplied "translation table" for each. */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3996
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3997
	used = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3998
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3999
	for (i = 0; i < num_trans; i++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4000
		int j, found;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4001
		char *curname;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4002
		fs_generic_func_p result;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4003
		fs_generic_func_p *location;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4004
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4005
		curname = translation[i].name;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4006
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4007
		/* Look for a matching operation in the list supplied by the */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4008
		/* file system. */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4009
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4010
		found = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4011
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4012
		for (j = 0; j < num_ops; j++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4013
			if (strcmp(operations[j].name, curname) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4014
				used++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4015
				found = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4016
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4017
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4018
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4019
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4020
		/* If the file system is using a "placeholder" for default */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4021
		/* or error functions, grab the appropriate function out of */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4022
		/* the translation table.  If the file system didn't supply */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4023
		/* this operation at all, use the default function. */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4024
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4025
		if (found) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4026
			result = operations[j].func;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4027
			if (result == fs_default) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4028
				result = translation[i].defaultFunc;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4029
			} else if (result == fs_error) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4030
				result = translation[i].errorFunc;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4031
			} else if (result == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4032
				/* Null values are PROHIBITED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4033
				return (EINVAL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4034
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4035
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4036
			result = translation[i].defaultFunc;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4037
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4038
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4039
		/* Now store the function into the operations vector. */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4040
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4041
		location = (fs_generic_func_p *)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4042
		    (((char *)vector) + translation[i].offset);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4043
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4044
		*location = result;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4045
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4046
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4047
	*unused_ops = num_ops - used;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4048
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4049
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4050
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4051
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4052
/* Placeholder functions, should never be called. */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4053
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4054
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4055
fs_error(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4056
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4057
	cmn_err(CE_PANIC, "fs_error called");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4058
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4059
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4060
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4061
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4062
fs_default(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4063
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4064
	cmn_err(CE_PANIC, "fs_default called");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4065
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4066
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4067
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4068
#ifdef __sparc
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4069
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4070
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4071
 * Part of the implementation of booting off a mirrored root
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4072
 * involves a change of dev_t for the root device.  To
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4073
 * accomplish this, first remove the existing hash table
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4074
 * entry for the root device, convert to the new dev_t,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4075
 * then re-insert in the hash table at the head of the list.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4076
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4077
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4078
vfs_root_redev(vfs_t *vfsp, dev_t ndev, int fstype)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4079
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4080
	vfs_list_lock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4081
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4082
	vfs_hash_remove(vfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4083
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4084
	vfsp->vfs_dev = ndev;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4085
	vfs_make_fsid(&vfsp->vfs_fsid, ndev, fstype);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4086
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4087
	vfs_hash_add(vfsp, 1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4088
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4089
	vfs_list_unlock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4090
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4091
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4092
#else /* x86 NEWBOOT */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4093
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4094
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4095
rootconf()
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4096
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4097
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4098
	struct vfssw *vsw;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4099
	extern void pm_init();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4100
	char *fstyp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4101
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4102
	fstyp = getrootfs();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4103
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4104
	if (error = clboot_rootconf())
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4105
		return (error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4106
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4107
	if (modload("fs", fstyp) == -1)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4108
		cmn_err(CE_PANIC, "Cannot _init %s module\n", fstyp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4109
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4110
	RLOCK_VFSSW();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4111
	vsw = vfs_getvfsswbyname(fstyp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4112
	RUNLOCK_VFSSW();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4113
	VFS_INIT(rootvfs, &vsw->vsw_vfsops, 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4114
	VFS_HOLD(rootvfs);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4115
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4116
	/* always mount readonly first */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4117
	rootvfs->vfs_flag |= VFS_RDONLY;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4118
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4119
	pm_init();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4120
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4121
	if (netboot)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4122
		(void) strplumb();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4123
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4124
	error = VFS_MOUNTROOT(rootvfs, ROOT_INIT);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4125
	vfs_unrefvfssw(vsw);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4126
	rootdev = rootvfs->vfs_dev;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4127
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4128
	if (error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4129
		cmn_err(CE_PANIC, "cannot mount root path %s", svm_bootpath);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4130
	return (error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4131
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4132
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4133
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4134
 * XXX this is called by nfs only and should probably be removed
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4135
 * If booted with ASKNAME, prompt on the console for a filesystem
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4136
 * name and return it.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4137
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4138
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4139
getfsname(char *askfor, char *name, size_t namelen)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4140
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4141
	if (boothowto & RB_ASKNAME) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4142
		printf("%s name: ", askfor);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4143
		console_gets(name, namelen);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4144
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4145
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4146
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4147
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4148
 * If server_path exists, then we are booting a diskless
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4149
 * client. Otherwise, we default to ufs. Zfs should perhaps be
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4150
 * another property.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4151
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4152
static char *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4153
getrootfs(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4154
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4155
	extern char *strplumb_get_netdev_path(void);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4156
	char *propstr = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4157
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4158
	/* check fstype property; it should be nfsdyn for diskless */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4159
	if (ddi_prop_lookup_string(DDI_DEV_T_ANY, ddi_root_node(),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4160
	    DDI_PROP_DONTPASS, "fstype", &propstr)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4161
	    == DDI_SUCCESS) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4162
		(void) strncpy(rootfs.bo_fstype, propstr, BO_MAXFSNAME);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4163
		ddi_prop_free(propstr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4164
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4165
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4166
	if (strncmp(rootfs.bo_fstype, "nfs", 3) != 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4167
		return (rootfs.bo_fstype);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4168
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4169
	++netboot;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4170
	/* check if path to network interface is specified in bootpath */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4171
	if (ddi_prop_lookup_string(DDI_DEV_T_ANY, ddi_root_node(),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4172
	    DDI_PROP_DONTPASS, "bootpath", &propstr)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4173
	    == DDI_SUCCESS) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4174
		(void) strncpy(rootfs.bo_name, propstr, BO_MAXOBJNAME);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4175
		ddi_prop_free(propstr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4176
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4177
		/* attempt to determine netdev_path via boot_mac address */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4178
		netdev_path = strplumb_get_netdev_path();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4179
		if (netdev_path == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4180
			cmn_err(CE_PANIC,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4181
			    "Cannot find boot network interface\n");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4182
		(void) strncpy(rootfs.bo_name, netdev_path, BO_MAXOBJNAME);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4183
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4184
	return ("nfs");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4185
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4186
#endif