usr/src/uts/common/fs/vfs.c
author Yuri Pankov <yuri.pankov@nexenta.com>
Fri, 21 Sep 2012 06:38:43 +0400
changeset 13832 8e4bcbc31a4a
parent 13178 5f70b43d6386
permissions -rw-r--r--
1126 date(1)'s usage message doesn't mention -R 1788 "WARNING: Cannot lookup root device: /devices" is useless when rootfs is zfs 1828 powerd's "Able to open /dev/srn" notice is useless 2547 Minor updates to README 2678 zfs manpage mis-identifies checksum default value 2811 missing implementation: zfs send -r 3199 Update copyright years in usr/src/prototypes/ Reviewed by: Joshua M. Clulow <[email protected]> Reviewed by: Garrett D'Amore <[email protected]> Approved by: Dan McDonald <[email protected]>
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
/*
12633
9f2cda0ed938 PSARC 2010/144 lofi(7D) in non global zones
John Levon <john.levon@sun.com>
parents: 11173
diff changeset
    22
 * Copyright (c) 1988, 2010, Oracle and/or its affiliates. All rights reserved.
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    23
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    24
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    25
/*	Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T	*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    26
/*	  All Rights Reserved  	*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    27
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    28
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    29
 * University Copyright- Copyright (c) 1982, 1986, 1988
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    30
 * The Regents of the University of California
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    31
 * All Rights Reserved
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    32
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    33
 * University Acknowledgment- Portions of this document are derived from
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    34
 * software developed by the University of California, Berkeley, and its
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    35
 * contributors.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    36
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    37
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    38
#include <sys/types.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    39
#include <sys/t_lock.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    40
#include <sys/param.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    41
#include <sys/errno.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    42
#include <sys/user.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    43
#include <sys/fstyp.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    44
#include <sys/kmem.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    45
#include <sys/systm.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    46
#include <sys/proc.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    47
#include <sys/mount.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    48
#include <sys/vfs.h>
3898
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 3446
diff changeset
    49
#include <sys/vfs_opreg.h>
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    50
#include <sys/fem.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    51
#include <sys/mntent.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    52
#include <sys/stat.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    53
#include <sys/statvfs.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    54
#include <sys/statfs.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    55
#include <sys/cred.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    56
#include <sys/vnode.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    57
#include <sys/rwstlock.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    58
#include <sys/dnlc.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    59
#include <sys/file.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    60
#include <sys/time.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    61
#include <sys/atomic.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    62
#include <sys/cmn_err.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    63
#include <sys/buf.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    64
#include <sys/swap.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    65
#include <sys/debug.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    66
#include <sys/vnode.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    67
#include <sys/modctl.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    68
#include <sys/ddi.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    69
#include <sys/pathname.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    70
#include <sys/bootconf.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    71
#include <sys/dumphdr.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    72
#include <sys/dc_ki.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    73
#include <sys/poll.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    74
#include <sys/sunddi.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    75
#include <sys/sysmacros.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    76
#include <sys/zone.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    77
#include <sys/policy.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    78
#include <sys/ctfs.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    79
#include <sys/objfs.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    80
#include <sys/console.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    81
#include <sys/reboot.h>
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
    82
#include <sys/attr.h>
10922
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 10910
diff changeset
    83
#include <sys/zio.h>
6423
437422a29d3a PSARC 2006/370 ZFS Boot Support
gw25295
parents: 6318
diff changeset
    84
#include <sys/spa.h>
6734
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
    85
#include <sys/lofi.h>
8194
f204d5cda6c1 PSARC 2008/427 iSCSI Boot
Jack Meng <Jack.Meng@Sun.COM>
parents: 8081
diff changeset
    86
#include <sys/bootprops.h>
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    87
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    88
#include <vm/page.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    89
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    90
#include <fs/fs_subr.h>
1520
2fb01d86c1c1 6391295 fop_create() panic when running svvs over ZFS
rsb
parents: 1488
diff changeset
    91
/* Private interfaces to create vopstats-related data structures */
2fb01d86c1c1 6391295 fop_create() panic when running svvs over ZFS
rsb
parents: 1488
diff changeset
    92
extern void		initialize_vopstats(vopstats_t *);
2fb01d86c1c1 6391295 fop_create() panic when running svvs over ZFS
rsb
parents: 1488
diff changeset
    93
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
    94
extern vsk_anchor_t	*get_vskstat_anchor(struct vfs *);
2fb01d86c1c1 6391295 fop_create() panic when running svvs over ZFS
rsb
parents: 1488
diff changeset
    95
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    96
static void vfs_clearmntopt_nolock(mntopts_t *, const char *, int);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    97
static void vfs_setmntopt_nolock(mntopts_t *, const char *,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    98
    const char *, int, int);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    99
static int  vfs_optionisset_nolock(const mntopts_t *, const char *, char **);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   100
static void vfs_freemnttab(struct vfs *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   101
static void vfs_freeopt(mntopt_t *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   102
static void vfs_swapopttbl_nolock(mntopts_t *, mntopts_t *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   103
static void vfs_swapopttbl(mntopts_t *, mntopts_t *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   104
static void vfs_copyopttbl_extend(const mntopts_t *, mntopts_t *, int);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   105
static void vfs_createopttbl_extend(mntopts_t *, const char *,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   106
    const mntopts_t *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   107
static char **vfs_copycancelopt_extend(char **const, int);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   108
static void vfs_freecancelopt(char **);
5084
7d838c5c0eed PSARC 2006/260 Solaris on Xen
johnlev
parents: 4863
diff changeset
   109
static void getrootfs(char **, char **);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   110
static int getmacpath(dev_info_t *, void *);
4863
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
   111
static void vfs_mnttabvp_setup(void);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   112
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   113
struct ipmnt {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   114
	struct ipmnt	*mip_next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   115
	dev_t		mip_dev;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   116
	struct vfs	*mip_vfsp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   117
};
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   118
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   119
static kmutex_t		vfs_miplist_mutex;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   120
static struct ipmnt	*vfs_miplist = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   121
static struct ipmnt	*vfs_miplist_end = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   122
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   123
static kmem_cache_t *vfs_cache;	/* Pointer to VFS kmem cache */
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   124
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   125
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   126
 * VFS global data.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   127
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   128
vnode_t *rootdir;		/* pointer to root inode vnode. */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   129
vnode_t *devicesdir;		/* pointer to inode of devices root */
2621
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   130
vnode_t	*devdir;		/* pointer to inode of dev root */
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   131
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   132
char *server_rootpath;		/* root path for diskless clients */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   133
char *server_hostname;		/* hostname of diskless server */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   134
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   135
static struct vfs root;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   136
static struct vfs devices;
2621
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   137
static struct vfs dev;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   138
struct vfs *rootvfs = &root;	/* pointer to root vfs; head of VFS list. */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   139
rvfs_t *rvfs_list;		/* array of vfs ptrs for vfs hash list */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   140
int vfshsz = 512;		/* # of heads/locks in vfs hash arrays */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   141
				/* must be power of 2!	*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   142
timespec_t vfs_mnttab_ctime;	/* mnttab created time */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   143
timespec_t vfs_mnttab_mtime;	/* mnttab last modified time */
4813
8eaf4b355227 backout 6367770/6588702/6588839: needs work
dm120769
parents: 4766
diff changeset
   144
char *vfs_dummyfstype = "\0";
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   145
struct pollhead vfs_pollhd;	/* for mnttab pollers */
4863
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
   146
struct vnode *vfs_mntdummyvp;	/* to fake mnttab read/write for file events */
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
   147
int	mntfstype;		/* will be set once mnt fs is mounted */
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   148
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   149
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   150
 * Table for generic options recognized in the VFS layer and acted
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   151
 * on at this level before parsing file system specific options.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   152
 * The nosuid option is stronger than any of the devices and setuid
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   153
 * options, so those are canceled when nosuid is seen.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   154
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   155
 * All options which are added here need to be added to the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   156
 * list of standard options in usr/src/cmd/fs.d/fslib.c as well.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   157
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   158
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   159
 * VFS Mount options table
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   160
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   161
static char *ro_cancel[] = { MNTOPT_RW, NULL };
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   162
static char *rw_cancel[] = { MNTOPT_RO, NULL };
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   163
static char *suid_cancel[] = { MNTOPT_NOSUID, NULL };
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   164
static char *nosuid_cancel[] = { MNTOPT_SUID, MNTOPT_DEVICES, MNTOPT_NODEVICES,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   165
    MNTOPT_NOSETUID, MNTOPT_SETUID, NULL };
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   166
static char *devices_cancel[] = { MNTOPT_NODEVICES, NULL };
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   167
static char *nodevices_cancel[] = { MNTOPT_DEVICES, NULL };
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   168
static char *setuid_cancel[] = { MNTOPT_NOSETUID, NULL };
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   169
static char *nosetuid_cancel[] = { MNTOPT_SETUID, NULL };
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   170
static char *nbmand_cancel[] = { MNTOPT_NONBMAND, NULL };
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   171
static char *nonbmand_cancel[] = { MNTOPT_NBMAND, NULL };
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   172
static char *exec_cancel[] = { MNTOPT_NOEXEC, NULL };
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   173
static char *noexec_cancel[] = { MNTOPT_EXEC, NULL };
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   174
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   175
static const mntopt_t mntopts[] = {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   176
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   177
 *	option name		cancel options		default arg	flags
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   178
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   179
	{ MNTOPT_REMOUNT,	NULL,			NULL,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   180
		MO_NODISPLAY, (void *)0 },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   181
	{ MNTOPT_RO,		ro_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_RW,		rw_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_SUID,		suid_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_NOSUID,	nosuid_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_DEVICES,	devices_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_NODEVICES,	nodevices_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_SETUID,	setuid_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_NOSETUID,	nosetuid_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_NBMAND,	nbmand_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
	{ MNTOPT_NONBMAND,	nonbmand_cancel,	NULL,		0,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   200
		(void *)0 },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   201
	{ MNTOPT_EXEC,		exec_cancel,		NULL,		0,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   202
		(void *)0 },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   203
	{ MNTOPT_NOEXEC,	noexec_cancel,		NULL,		0,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   204
		(void *)0 },
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
const mntopts_t vfs_mntopts = {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   208
	sizeof (mntopts) / sizeof (mntopt_t),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   209
	(mntopt_t *)&mntopts[0]
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   210
};
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   211
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   212
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   213
 * File system operation dispatch functions.
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_mount(vfs_t *vfsp, vnode_t *mvp, struct mounta *uap, 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_mount)(vfsp, mvp, uap, 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_unmount(vfs_t *vfsp, int flag, cred_t *cr)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   224
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   225
	return (*(vfsp)->vfs_op->vfs_unmount)(vfsp, flag, cr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   226
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   227
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   228
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   229
fsop_root(vfs_t *vfsp, vnode_t **vpp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   230
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   231
	refstr_t *mntpt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   232
	int ret = (*(vfsp)->vfs_op->vfs_root)(vfsp, vpp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   233
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   234
	 * Make sure this root has a path.  With lofs, it is possible to have
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   235
	 * a NULL mountpoint.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   236
	 */
254
349581d9fc98 6175313 io provider exposes our reluctance to set vnode paths
eschrock
parents: 0
diff changeset
   237
	if (ret == 0 && vfsp->vfs_mntpt != NULL && (*vpp)->v_path == NULL) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   238
		mntpt = vfs_getmntpoint(vfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   239
		vn_setpath_str(*vpp, refstr_value(mntpt),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   240
		    strlen(refstr_value(mntpt)));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   241
		refstr_rele(mntpt);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   242
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   243
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   244
	return (ret);
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_statfs(vfs_t *vfsp, statvfs64_t *sp)
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_statvfs)(vfsp, sp);
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_sync(vfs_t *vfsp, short flag, cred_t *cr)
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_sync)(vfsp, flag, cr);
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_vget(vfs_t *vfsp, vnode_t **vpp, fid_t *fidp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   261
{
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   262
	/*
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   263
	 * In order to handle system attribute fids in a manner
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   264
	 * transparent to the underlying fs, we embed the fid for
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   265
	 * the sysattr parent object in the sysattr fid and tack on
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   266
	 * some extra bytes that only the sysattr layer knows about.
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   267
	 *
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   268
	 * This guarantees that sysattr fids are larger than other fids
7757
bf4a45ecb669 PSARC/2008/588 VFSFT_SYSATTR_VIEWS
Janice Chang <Janice.Chang@Sun.COM>
parents: 7439
diff changeset
   269
	 * for this vfs. If the vfs supports the sysattr view interface
bf4a45ecb669 PSARC/2008/588 VFSFT_SYSATTR_VIEWS
Janice Chang <Janice.Chang@Sun.COM>
parents: 7439
diff changeset
   270
	 * (as indicated by VFSFT_SYSATTR_VIEWS), we cannot have a size
bf4a45ecb669 PSARC/2008/588 VFSFT_SYSATTR_VIEWS
Janice Chang <Janice.Chang@Sun.COM>
parents: 7439
diff changeset
   271
	 * collision with XATTR_FIDSZ.
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   272
	 */
7757
bf4a45ecb669 PSARC/2008/588 VFSFT_SYSATTR_VIEWS
Janice Chang <Janice.Chang@Sun.COM>
parents: 7439
diff changeset
   273
	if (vfs_has_feature(vfsp, VFSFT_SYSATTR_VIEWS) &&
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   274
	    fidp->fid_len == XATTR_FIDSZ)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   275
		return (xattr_dir_vget(vfsp, vpp, fidp));
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   276
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   277
	return (*(vfsp)->vfs_op->vfs_vget)(vfsp, vpp, fidp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   278
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   279
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   280
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   281
fsop_mountroot(vfs_t *vfsp, enum whymountroot reason)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   282
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   283
	return (*(vfsp)->vfs_op->vfs_mountroot)(vfsp, reason);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   284
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   285
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   286
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   287
fsop_freefs(vfs_t *vfsp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   288
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   289
	(*(vfsp)->vfs_op->vfs_freevfs)(vfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   290
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   291
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   292
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   293
fsop_vnstate(vfs_t *vfsp, vnode_t *vp, vntrans_t nstate)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   294
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   295
	return ((*(vfsp)->vfs_op->vfs_vnstate)(vfsp, vp, nstate));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   296
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   297
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   298
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   299
fsop_sync_by_kind(int fstype, short flag, cred_t *cr)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   300
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   301
	ASSERT((fstype >= 0) && (fstype < nfstype));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   302
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   303
	if (ALLOCATED_VFSSW(&vfssw[fstype]) && VFS_INSTALLED(&vfssw[fstype]))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   304
		return (*vfssw[fstype].vsw_vfsops.vfs_sync) (NULL, flag, cr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   305
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   306
		return (ENOTSUP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   307
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   308
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   309
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   310
 * File system initialization.  vfs_setfsops() must be called from a file
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   311
 * system's init routine.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   312
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   313
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   314
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   315
fs_copyfsops(const fs_operation_def_t *template, vfsops_t *actual,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   316
    int *unused_ops)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   317
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   318
	static const fs_operation_trans_def_t vfs_ops_table[] = {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   319
		VFSNAME_MOUNT, offsetof(vfsops_t, vfs_mount),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   320
			fs_nosys, fs_nosys,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   321
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   322
		VFSNAME_UNMOUNT, offsetof(vfsops_t, vfs_unmount),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   323
			fs_nosys, fs_nosys,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   324
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   325
		VFSNAME_ROOT, offsetof(vfsops_t, vfs_root),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   326
			fs_nosys, fs_nosys,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   327
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   328
		VFSNAME_STATVFS, offsetof(vfsops_t, vfs_statvfs),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   329
			fs_nosys, fs_nosys,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   330
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   331
		VFSNAME_SYNC, offsetof(vfsops_t, vfs_sync),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   332
			(fs_generic_func_p) fs_sync,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   333
			(fs_generic_func_p) fs_sync,	/* No errors allowed */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   334
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   335
		VFSNAME_VGET, offsetof(vfsops_t, vfs_vget),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   336
			fs_nosys, fs_nosys,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   337
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   338
		VFSNAME_MOUNTROOT, offsetof(vfsops_t, vfs_mountroot),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   339
			fs_nosys, fs_nosys,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   340
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   341
		VFSNAME_FREEVFS, offsetof(vfsops_t, vfs_freevfs),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   342
			(fs_generic_func_p)fs_freevfs,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   343
			(fs_generic_func_p)fs_freevfs,	/* Shouldn't fail */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   344
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   345
		VFSNAME_VNSTATE, offsetof(vfsops_t, vfs_vnstate),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   346
			(fs_generic_func_p)fs_nosys,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   347
			(fs_generic_func_p)fs_nosys,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   348
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   349
		NULL, 0, NULL, NULL
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   350
	};
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   351
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   352
	return (fs_build_vector(actual, unused_ops, vfs_ops_table, template));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   353
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   354
6423
437422a29d3a PSARC 2006/370 ZFS Boot Support
gw25295
parents: 6318
diff changeset
   355
void
437422a29d3a PSARC 2006/370 ZFS Boot Support
gw25295
parents: 6318
diff changeset
   356
zfs_boot_init() {
437422a29d3a PSARC 2006/370 ZFS Boot Support
gw25295
parents: 6318
diff changeset
   357
437422a29d3a PSARC 2006/370 ZFS Boot Support
gw25295
parents: 6318
diff changeset
   358
	if (strcmp(rootfs.bo_fstype, MNTTYPE_ZFS) == 0)
437422a29d3a PSARC 2006/370 ZFS Boot Support
gw25295
parents: 6318
diff changeset
   359
		spa_boot_init();
437422a29d3a PSARC 2006/370 ZFS Boot Support
gw25295
parents: 6318
diff changeset
   360
}
437422a29d3a PSARC 2006/370 ZFS Boot Support
gw25295
parents: 6318
diff changeset
   361
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   362
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   363
vfs_setfsops(int fstype, const fs_operation_def_t *template, vfsops_t **actual)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   364
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   365
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   366
	int unused_ops;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   367
3904
73066af3aa6a 6539420 Grab a mop! vfsinit() is leaking
rsb
parents: 3898
diff changeset
   368
	/*
73066af3aa6a 6539420 Grab a mop! vfsinit() is leaking
rsb
parents: 3898
diff changeset
   369
	 * Verify that fstype refers to a valid fs.  Note that
73066af3aa6a 6539420 Grab a mop! vfsinit() is leaking
rsb
parents: 3898
diff changeset
   370
	 * 0 is valid since it's used to set "stray" ops.
73066af3aa6a 6539420 Grab a mop! vfsinit() is leaking
rsb
parents: 3898
diff changeset
   371
	 */
73066af3aa6a 6539420 Grab a mop! vfsinit() is leaking
rsb
parents: 3898
diff changeset
   372
	if ((fstype < 0) || (fstype >= nfstype))
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   373
		return (EINVAL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   374
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   375
	if (!ALLOCATED_VFSSW(&vfssw[fstype]))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   376
		return (EINVAL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   377
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   378
	/* Set up the operations vector. */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   379
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   380
	error = fs_copyfsops(template, &vfssw[fstype].vsw_vfsops, &unused_ops);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   381
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   382
	if (error != 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   383
		return (error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   384
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   385
	vfssw[fstype].vsw_flag |= VSW_INSTALLED;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   386
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   387
	if (actual != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   388
		*actual = &vfssw[fstype].vsw_vfsops;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   389
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   390
#if DEBUG
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   391
	if (unused_ops != 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   392
		cmn_err(CE_WARN, "vfs_setfsops: %s: %d operations supplied "
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   393
		    "but not used", vfssw[fstype].vsw_name, unused_ops);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   394
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   395
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   396
	return (0);
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
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   400
vfs_makefsops(const fs_operation_def_t *template, vfsops_t **actual)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   401
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   402
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   403
	int unused_ops;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   404
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   405
	*actual = (vfsops_t *)kmem_alloc(sizeof (vfsops_t), KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   406
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   407
	error = fs_copyfsops(template, *actual, &unused_ops);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   408
	if (error != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   409
		kmem_free(*actual, sizeof (vfsops_t));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   410
		*actual = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   411
		return (error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   412
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   413
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   414
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   415
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   416
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   417
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   418
 * Free a vfsops structure created as a result of vfs_makefsops().
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   419
 * NOTE: For a vfsops structure initialized by vfs_setfsops(), use
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   420
 * vfs_freevfsops_by_type().
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   421
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   422
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   423
vfs_freevfsops(vfsops_t *vfsops)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   424
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   425
	kmem_free(vfsops, sizeof (vfsops_t));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   426
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   427
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   428
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   429
 * Since the vfsops structure is part of the vfssw table and wasn't
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   430
 * really allocated, we're not really freeing anything.  We keep
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   431
 * the name for consistency with vfs_freevfsops().  We do, however,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   432
 * need to take care of a little bookkeeping.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   433
 * NOTE: For a vfsops structure created by vfs_setfsops(), use
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   434
 * vfs_freevfsops_by_type().
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   435
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   436
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   437
vfs_freevfsops_by_type(int fstype)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   438
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   439
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   440
	/* Verify that fstype refers to a loaded fs (and not fsid 0). */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   441
	if ((fstype <= 0) || (fstype >= nfstype))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   442
		return (EINVAL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   443
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   444
	WLOCK_VFSSW();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   445
	if ((vfssw[fstype].vsw_flag & VSW_INSTALLED) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   446
		WUNLOCK_VFSSW();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   447
		return (EINVAL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   448
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   449
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   450
	vfssw[fstype].vsw_flag &= ~VSW_INSTALLED;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   451
	WUNLOCK_VFSSW();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   452
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   453
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   454
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   455
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   456
/* Support routines used to reference vfs_op */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   457
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   458
/* Set the operations vector for a vfs */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   459
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   460
vfs_setops(vfs_t *vfsp, vfsops_t *vfsops)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   461
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   462
	vfsops_t	*op;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   463
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   464
	ASSERT(vfsp != NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   465
	ASSERT(vfsops != NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   466
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   467
	op = vfsp->vfs_op;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   468
	membar_consumer();
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   469
	if (vfsp->vfs_femhead == NULL &&
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   470
	    casptr(&vfsp->vfs_op, op, vfsops) == op) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   471
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   472
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   473
	fsem_setvfsops(vfsp, vfsops);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   474
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   475
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   476
/* Retrieve the operations vector for a vfs */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   477
vfsops_t *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   478
vfs_getops(vfs_t *vfsp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   479
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   480
	vfsops_t	*op;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   481
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   482
	ASSERT(vfsp != NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   483
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   484
	op = vfsp->vfs_op;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   485
	membar_consumer();
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   486
	if (vfsp->vfs_femhead == NULL && op == vfsp->vfs_op) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   487
		return (op);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   488
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   489
		return (fsem_getvfsops(vfsp));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   490
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   491
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   492
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   493
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   494
 * Returns non-zero (1) if the vfsops matches that of the vfs.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   495
 * Returns zero (0) if not.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   496
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   497
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   498
vfs_matchops(vfs_t *vfsp, vfsops_t *vfsops)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   499
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   500
	return (vfs_getops(vfsp) == vfsops);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   501
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   502
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   503
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   504
 * Returns non-zero (1) if the file system has installed a non-default,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   505
 * non-error vfs_sync routine.  Returns zero (0) otherwise.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   506
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   507
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   508
vfs_can_sync(vfs_t *vfsp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   509
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   510
	/* vfs_sync() routine is not the default/error function */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   511
	return (vfs_getops(vfsp)->vfs_sync != fs_sync);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   512
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   513
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   514
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   515
 * Initialize a vfs structure.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   516
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   517
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   518
vfs_init(vfs_t *vfsp, vfsops_t *op, void *data)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   519
{
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   520
	/* Other initialization has been moved to vfs_alloc() */
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   521
	vfsp->vfs_count = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   522
	vfsp->vfs_next = vfsp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   523
	vfsp->vfs_prev = vfsp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   524
	vfsp->vfs_zone_next = vfsp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   525
	vfsp->vfs_zone_prev = vfsp;
6734
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
   526
	vfsp->vfs_lofi_minor = 0;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   527
	sema_init(&vfsp->vfs_reflock, 1, NULL, SEMA_DEFAULT, NULL);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   528
	vfsimpl_setup(vfsp);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   529
	vfsp->vfs_data = (data);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   530
	vfs_setops((vfsp), (op));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   531
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   532
1925
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
 * Allocate and initialize the vfs implementation private data
91047fd43318 PSARC 2006/270 vfs_femhead change to vfs_implp
rsb
parents: 1678
diff changeset
   535
 * structure, vfs_impl_t.
91047fd43318 PSARC 2006/270 vfs_femhead change to vfs_implp
rsb
parents: 1678
diff changeset
   536
 */
91047fd43318 PSARC 2006/270 vfs_femhead change to vfs_implp
rsb
parents: 1678
diff changeset
   537
void
91047fd43318 PSARC 2006/270 vfs_femhead change to vfs_implp
rsb
parents: 1678
diff changeset
   538
vfsimpl_setup(vfs_t *vfsp)
91047fd43318 PSARC 2006/270 vfs_femhead change to vfs_implp
rsb
parents: 1678
diff changeset
   539
{
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   540
	int i;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   541
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   542
	if (vfsp->vfs_implp != NULL) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   543
		return;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   544
	}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   545
1925
91047fd43318 PSARC 2006/270 vfs_femhead change to vfs_implp
rsb
parents: 1678
diff changeset
   546
	vfsp->vfs_implp = kmem_alloc(sizeof (vfs_impl_t), KM_SLEEP);
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   547
	/* Note that these are #define'd in vfs.h */
1925
91047fd43318 PSARC 2006/270 vfs_femhead change to vfs_implp
rsb
parents: 1678
diff changeset
   548
	vfsp->vfs_vskap = NULL;
91047fd43318 PSARC 2006/270 vfs_femhead change to vfs_implp
rsb
parents: 1678
diff changeset
   549
	vfsp->vfs_fstypevsp = NULL;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   550
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   551
	/* Set size of counted array, then zero the array */
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   552
	vfsp->vfs_featureset[0] = VFS_FEATURE_MAXSZ - 1;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   553
	for (i = 1; i <  VFS_FEATURE_MAXSZ; i++) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   554
		vfsp->vfs_featureset[i] = 0;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
   555
	}
1925
91047fd43318 PSARC 2006/270 vfs_femhead change to vfs_implp
rsb
parents: 1678
diff changeset
   556
}
91047fd43318 PSARC 2006/270 vfs_femhead change to vfs_implp
rsb
parents: 1678
diff changeset
   557
91047fd43318 PSARC 2006/270 vfs_femhead change to vfs_implp
rsb
parents: 1678
diff changeset
   558
/*
91047fd43318 PSARC 2006/270 vfs_femhead change to vfs_implp
rsb
parents: 1678
diff changeset
   559
 * 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
   560
 * 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
   561
 * would not contain this implementation private data structure.
91047fd43318 PSARC 2006/270 vfs_femhead change to vfs_implp
rsb
parents: 1678
diff changeset
   562
 */
91047fd43318 PSARC 2006/270 vfs_femhead change to vfs_implp
rsb
parents: 1678
diff changeset
   563
void
91047fd43318 PSARC 2006/270 vfs_femhead change to vfs_implp
rsb
parents: 1678
diff changeset
   564
vfsimpl_teardown(vfs_t *vfsp)
91047fd43318 PSARC 2006/270 vfs_femhead change to vfs_implp
rsb
parents: 1678
diff changeset
   565
{
91047fd43318 PSARC 2006/270 vfs_femhead change to vfs_implp
rsb
parents: 1678
diff changeset
   566
	vfs_impl_t	*vip = vfsp->vfs_implp;
91047fd43318 PSARC 2006/270 vfs_femhead change to vfs_implp
rsb
parents: 1678
diff changeset
   567
91047fd43318 PSARC 2006/270 vfs_femhead change to vfs_implp
rsb
parents: 1678
diff changeset
   568
	if (vip == NULL)
91047fd43318 PSARC 2006/270 vfs_femhead change to vfs_implp
rsb
parents: 1678
diff changeset
   569
		return;
91047fd43318 PSARC 2006/270 vfs_femhead change to vfs_implp
rsb
parents: 1678
diff changeset
   570
91047fd43318 PSARC 2006/270 vfs_femhead change to vfs_implp
rsb
parents: 1678
diff changeset
   571
	kmem_free(vfsp->vfs_implp, sizeof (vfs_impl_t));
91047fd43318 PSARC 2006/270 vfs_femhead change to vfs_implp
rsb
parents: 1678
diff changeset
   572
	vfsp->vfs_implp = NULL;
91047fd43318 PSARC 2006/270 vfs_femhead change to vfs_implp
rsb
parents: 1678
diff changeset
   573
}
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   574
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   575
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   576
 * VFS system calls: mount, umount, syssync, statfs, fstatfs, statvfs,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   577
 * fstatvfs, and sysfs moved to common/syscall.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   578
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   579
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   580
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   581
 * Update every mounted file system.  We call the vfs_sync operation of
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   582
 * each file system type, passing it a NULL vfsp to indicate that all
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   583
 * mounted file systems of that type should be updated.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   584
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   585
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   586
vfs_sync(int flag)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   587
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   588
	struct vfssw *vswp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   589
	RLOCK_VFSSW();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   590
	for (vswp = &vfssw[1]; vswp < &vfssw[nfstype]; vswp++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   591
		if (ALLOCATED_VFSSW(vswp) && VFS_INSTALLED(vswp)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   592
			vfs_refvfssw(vswp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   593
			RUNLOCK_VFSSW();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   594
			(void) (*vswp->vsw_vfsops.vfs_sync)(NULL, flag,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   595
			    CRED());
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   596
			vfs_unrefvfssw(vswp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   597
			RLOCK_VFSSW();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   598
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   599
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   600
	RUNLOCK_VFSSW();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   601
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   602
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   603
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   604
sync(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   605
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   606
	vfs_sync(0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   607
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   608
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   609
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   610
 * External routines.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   611
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   612
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   613
krwlock_t vfssw_lock;	/* lock accesses to vfssw */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   614
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   615
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   616
 * Lock for accessing the vfs linked list.  Initialized in vfs_mountroot(),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   617
 * but otherwise should be accessed only via vfs_list_lock() and
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   618
 * vfs_list_unlock().  Also used to protect the timestamp for mods to the list.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   619
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   620
static krwlock_t vfslist;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   621
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   622
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   623
 * Mount devfs on /devices. This is done right after root is mounted
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   624
 * to provide device access support for the system
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   625
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   626
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   627
vfs_mountdevices(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   628
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   629
	struct vfssw *vsw;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   630
	struct vnode *mvp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   631
	struct mounta mounta = {	/* fake mounta for devfs_mount() */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   632
		NULL,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   633
		NULL,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   634
		MS_SYSSPACE,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   635
		NULL,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   636
		NULL,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   637
		0,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   638
		NULL,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   639
		0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   640
	};
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   641
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   642
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   643
	 * _init devfs module to fill in the vfssw
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   644
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   645
	if (modload("fs", "devfs") == -1)
3446
5903aece022d PSARC 2006/469 EOF and removal of eeprom -I
mrj
parents: 2621
diff changeset
   646
		panic("Cannot _init devfs module");
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   647
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   648
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   649
	 * Hold vfs
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   650
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   651
	RLOCK_VFSSW();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   652
	vsw = vfs_getvfsswbyname("devfs");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   653
	VFS_INIT(&devices, &vsw->vsw_vfsops, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   654
	VFS_HOLD(&devices);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   655
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   656
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   657
	 * Locate mount point
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   658
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   659
	if (lookupname("/devices", UIO_SYSSPACE, FOLLOW, NULLVPP, &mvp))
3446
5903aece022d PSARC 2006/469 EOF and removal of eeprom -I
mrj
parents: 2621
diff changeset
   660
		panic("Cannot find /devices");
0
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
	 * Perform the mount of /devices
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   664
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   665
	if (VFS_MOUNT(&devices, mvp, &mounta, CRED()))
3446
5903aece022d PSARC 2006/469 EOF and removal of eeprom -I
mrj
parents: 2621
diff changeset
   666
		panic("Cannot mount /devices");
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   667
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   668
	RUNLOCK_VFSSW();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   669
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   670
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   671
	 * Set appropriate members and add to vfs list for mnttab display
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   672
	 */
12906
3ca11e9f39b7 6950914 remount can change mount point to "unspecified_mountpoint", causing panics
Robert Harris <Robert.Harris@Sun.COM>
parents: 12633
diff changeset
   673
	vfs_setresource(&devices, "/devices", 0);
3ca11e9f39b7 6950914 remount can change mount point to "unspecified_mountpoint", causing panics
Robert Harris <Robert.Harris@Sun.COM>
parents: 12633
diff changeset
   674
	vfs_setmntpoint(&devices, "/devices", 0);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   675
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   676
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   677
	 * Hold the root of /devices so it won't go away
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   678
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   679
	if (VFS_ROOT(&devices, &devicesdir))
3446
5903aece022d PSARC 2006/469 EOF and removal of eeprom -I
mrj
parents: 2621
diff changeset
   680
		panic("vfs_mountdevices: not devices root");
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   681
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   682
	if (vfs_lock(&devices) != 0) {
2621
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   683
		VN_RELE(devicesdir);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   684
		cmn_err(CE_NOTE, "Cannot acquire vfs_lock of /devices");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   685
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   686
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   687
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   688
	if (vn_vfswlock(mvp) != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   689
		vfs_unlock(&devices);
2621
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   690
		VN_RELE(devicesdir);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   691
		cmn_err(CE_NOTE, "Cannot acquire vfswlock of /devices");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   692
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   693
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   694
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   695
	vfs_add(mvp, &devices, 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   696
	vn_vfsunlock(mvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   697
	vfs_unlock(&devices);
2621
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   698
	VN_RELE(devicesdir);
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   699
}
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
 * mount the first instance of /dev  to root and remain mounted
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
static void
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   705
vfs_mountdev1(void)
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   706
{
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   707
	struct vfssw *vsw;
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   708
	struct vnode *mvp;
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   709
	struct mounta mounta = {	/* fake mounta for sdev_mount() */
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   710
		NULL,
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   711
		NULL,
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   712
		MS_SYSSPACE | MS_OVERLAY,
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   713
		NULL,
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   714
		NULL,
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   715
		0,
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   716
		NULL,
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   717
		0
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   718
	};
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   719
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
	 * _init dev module to fill in the 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
	if (modload("fs", "dev") == -1)
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   724
		cmn_err(CE_PANIC, "Cannot _init dev module\n");
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
	/*
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   727
	 * Hold vfs
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
	RLOCK_VFSSW();
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   730
	vsw = vfs_getvfsswbyname("dev");
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   731
	VFS_INIT(&dev, &vsw->vsw_vfsops, NULL);
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   732
	VFS_HOLD(&dev);
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   733
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
	 * Locate mount point
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   736
	 */
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   737
	if (lookupname("/dev", UIO_SYSSPACE, FOLLOW, NULLVPP, &mvp))
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   738
		cmn_err(CE_PANIC, "Cannot find /dev\n");
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
	 * Perform the mount of /dev
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   742
	 */
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   743
	if (VFS_MOUNT(&dev, mvp, &mounta, CRED()))
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   744
		cmn_err(CE_PANIC, "Cannot mount /dev 1\n");
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   745
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   746
	RUNLOCK_VFSSW();
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
	/*
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   749
	 * Set appropriate members and add to vfs list for mnttab display
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   750
	 */
12906
3ca11e9f39b7 6950914 remount can change mount point to "unspecified_mountpoint", causing panics
Robert Harris <Robert.Harris@Sun.COM>
parents: 12633
diff changeset
   751
	vfs_setresource(&dev, "/dev", 0);
3ca11e9f39b7 6950914 remount can change mount point to "unspecified_mountpoint", causing panics
Robert Harris <Robert.Harris@Sun.COM>
parents: 12633
diff changeset
   752
	vfs_setmntpoint(&dev, "/dev", 0);
2621
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   753
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   754
	/*
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   755
	 * Hold the root of /dev so it won't go away
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   756
	 */
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   757
	if (VFS_ROOT(&dev, &devdir))
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   758
		cmn_err(CE_PANIC, "vfs_mountdev1: not dev root");
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   759
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   760
	if (vfs_lock(&dev) != 0) {
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   761
		VN_RELE(devdir);
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   762
		cmn_err(CE_NOTE, "Cannot acquire vfs_lock of /dev");
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   763
		return;
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   764
	}
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   765
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   766
	if (vn_vfswlock(mvp) != 0) {
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   767
		vfs_unlock(&dev);
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   768
		VN_RELE(devdir);
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   769
		cmn_err(CE_NOTE, "Cannot acquire vfswlock of /dev");
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   770
		return;
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   771
	}
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   772
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   773
	vfs_add(mvp, &dev, 0);
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   774
	vn_vfsunlock(mvp);
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   775
	vfs_unlock(&dev);
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   776
	VN_RELE(devdir);
0
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
 * Mount required filesystem. This is done right after root is mounted.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   781
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   782
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   783
vfs_mountfs(char *module, char *spec, char *path)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   784
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   785
	struct vnode *mvp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   786
	struct mounta mounta;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   787
	vfs_t *vfsp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   788
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   789
	mounta.flags = MS_SYSSPACE | MS_DATA;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   790
	mounta.fstype = module;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   791
	mounta.spec = spec;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   792
	mounta.dir = path;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   793
	if (lookupname(path, UIO_SYSSPACE, FOLLOW, NULLVPP, &mvp)) {
3446
5903aece022d PSARC 2006/469 EOF and removal of eeprom -I
mrj
parents: 2621
diff changeset
   794
		cmn_err(CE_WARN, "Cannot find %s", path);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   795
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   796
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   797
	if (domount(NULL, &mounta, mvp, CRED(), &vfsp))
3446
5903aece022d PSARC 2006/469 EOF and removal of eeprom -I
mrj
parents: 2621
diff changeset
   798
		cmn_err(CE_WARN, "Cannot mount %s", path);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   799
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   800
		VFS_RELE(vfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   801
	VN_RELE(mvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   802
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   803
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   804
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   805
 * vfs_mountroot is called by main() to mount the root filesystem.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   806
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   807
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   808
vfs_mountroot(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   809
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   810
	struct vnode	*rvp = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   811
	char		*path;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   812
	size_t		plen;
1488
196daa2cf3db PSARC/2006/034 fsstat
rsb
parents: 994
diff changeset
   813
	struct vfssw	*vswp;
11173
87f3734e64df 6881015 ZFS write activity prevents other threads from running in a timely manner
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents: 11005
diff changeset
   814
	proc_t		*p;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   815
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   816
	rw_init(&vfssw_lock, NULL, RW_DEFAULT, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   817
	rw_init(&vfslist, NULL, RW_DEFAULT, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   818
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   819
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   820
	 * Alloc the vfs hash bucket array and locks
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   821
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   822
	rvfs_list = kmem_zalloc(vfshsz * sizeof (rvfs_t), KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   823
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   824
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   825
	 * Call machine-dependent routine "rootconf" to choose a root
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   826
	 * file system type.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   827
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   828
	if (rootconf())
3446
5903aece022d PSARC 2006/469 EOF and removal of eeprom -I
mrj
parents: 2621
diff changeset
   829
		panic("vfs_mountroot: cannot mount root");
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   830
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   831
	 * Get vnode for '/'.  Set up rootdir, u.u_rdir and u.u_cdir
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   832
	 * to point to it.  These are used by lookuppn() so that it
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   833
	 * knows where to start from ('/' or '.').
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   834
	 */
12906
3ca11e9f39b7 6950914 remount can change mount point to "unspecified_mountpoint", causing panics
Robert Harris <Robert.Harris@Sun.COM>
parents: 12633
diff changeset
   835
	vfs_setmntpoint(rootvfs, "/", 0);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   836
	if (VFS_ROOT(rootvfs, &rootdir))
3446
5903aece022d PSARC 2006/469 EOF and removal of eeprom -I
mrj
parents: 2621
diff changeset
   837
		panic("vfs_mountroot: no root vnode");
11173
87f3734e64df 6881015 ZFS write activity prevents other threads from running in a timely manner
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents: 11005
diff changeset
   838
87f3734e64df 6881015 ZFS write activity prevents other threads from running in a timely manner
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents: 11005
diff changeset
   839
	/*
87f3734e64df 6881015 ZFS write activity prevents other threads from running in a timely manner
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents: 11005
diff changeset
   840
	 * At this point, the process tree consists of p0 and possibly some
87f3734e64df 6881015 ZFS write activity prevents other threads from running in a timely manner
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents: 11005
diff changeset
   841
	 * direct children of p0.  (i.e. there are no grandchildren)
87f3734e64df 6881015 ZFS write activity prevents other threads from running in a timely manner
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents: 11005
diff changeset
   842
	 *
87f3734e64df 6881015 ZFS write activity prevents other threads from running in a timely manner
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents: 11005
diff changeset
   843
	 * Walk through them all, setting their current directory.
87f3734e64df 6881015 ZFS write activity prevents other threads from running in a timely manner
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents: 11005
diff changeset
   844
	 */
87f3734e64df 6881015 ZFS write activity prevents other threads from running in a timely manner
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents: 11005
diff changeset
   845
	mutex_enter(&pidlock);
87f3734e64df 6881015 ZFS write activity prevents other threads from running in a timely manner
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents: 11005
diff changeset
   846
	for (p = practive; p != NULL; p = p->p_next) {
87f3734e64df 6881015 ZFS write activity prevents other threads from running in a timely manner
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents: 11005
diff changeset
   847
		ASSERT(p == &p0 || p->p_parent == &p0);
87f3734e64df 6881015 ZFS write activity prevents other threads from running in a timely manner
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents: 11005
diff changeset
   848
87f3734e64df 6881015 ZFS write activity prevents other threads from running in a timely manner
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents: 11005
diff changeset
   849
		PTOU(p)->u_cdir = rootdir;
87f3734e64df 6881015 ZFS write activity prevents other threads from running in a timely manner
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents: 11005
diff changeset
   850
		VN_HOLD(PTOU(p)->u_cdir);
87f3734e64df 6881015 ZFS write activity prevents other threads from running in a timely manner
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents: 11005
diff changeset
   851
		PTOU(p)->u_rdir = NULL;
87f3734e64df 6881015 ZFS write activity prevents other threads from running in a timely manner
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents: 11005
diff changeset
   852
	}
87f3734e64df 6881015 ZFS write activity prevents other threads from running in a timely manner
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents: 11005
diff changeset
   853
	mutex_exit(&pidlock);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   854
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   855
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   856
	 * Setup the global zone's rootvp, now that it exists.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   857
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   858
	global_zone->zone_rootvp = rootdir;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   859
	VN_HOLD(global_zone->zone_rootvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   860
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   861
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   862
	 * Notify the module code that it can begin using the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   863
	 * root filesystem instead of the boot program's services.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   864
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   865
	modrootloaded = 1;
6423
437422a29d3a PSARC 2006/370 ZFS Boot Support
gw25295
parents: 6318
diff changeset
   866
437422a29d3a PSARC 2006/370 ZFS Boot Support
gw25295
parents: 6318
diff changeset
   867
	/*
437422a29d3a PSARC 2006/370 ZFS Boot Support
gw25295
parents: 6318
diff changeset
   868
	 * Special handling for a ZFS root file system.
437422a29d3a PSARC 2006/370 ZFS Boot Support
gw25295
parents: 6318
diff changeset
   869
	 */
437422a29d3a PSARC 2006/370 ZFS Boot Support
gw25295
parents: 6318
diff changeset
   870
	zfs_boot_init();
437422a29d3a PSARC 2006/370 ZFS Boot Support
gw25295
parents: 6318
diff changeset
   871
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   872
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   873
	 * Set up mnttab information for root
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   874
	 */
12906
3ca11e9f39b7 6950914 remount can change mount point to "unspecified_mountpoint", causing panics
Robert Harris <Robert.Harris@Sun.COM>
parents: 12633
diff changeset
   875
	vfs_setresource(rootvfs, rootfs.bo_name, 0);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   876
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   877
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   878
	 * Notify cluster software that the root filesystem is available.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   879
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   880
	clboot_mountroot();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   881
1488
196daa2cf3db PSARC/2006/034 fsstat
rsb
parents: 994
diff changeset
   882
	/* Now that we're all done with the root FS, set up its vopstats */
196daa2cf3db PSARC/2006/034 fsstat
rsb
parents: 994
diff changeset
   883
	if ((vswp = vfs_getvfsswbyvfsops(vfs_getops(rootvfs))) != NULL) {
196daa2cf3db PSARC/2006/034 fsstat
rsb
parents: 994
diff changeset
   884
		/* Set flag for statistics collection */
196daa2cf3db PSARC/2006/034 fsstat
rsb
parents: 994
diff changeset
   885
		if (vswp->vsw_flag & VSW_STATS) {
1520
2fb01d86c1c1 6391295 fop_create() panic when running svvs over ZFS
rsb
parents: 1488
diff changeset
   886
			initialize_vopstats(&rootvfs->vfs_vopstats);
1488
196daa2cf3db PSARC/2006/034 fsstat
rsb
parents: 994
diff changeset
   887
			rootvfs->vfs_flag |= VFS_STATS;
1520
2fb01d86c1c1 6391295 fop_create() panic when running svvs over ZFS
rsb
parents: 1488
diff changeset
   888
			rootvfs->vfs_fstypevsp =
2fb01d86c1c1 6391295 fop_create() panic when running svvs over ZFS
rsb
parents: 1488
diff changeset
   889
			    get_fstype_vopstats(rootvfs, vswp);
2fb01d86c1c1 6391295 fop_create() panic when running svvs over ZFS
rsb
parents: 1488
diff changeset
   890
			rootvfs->vfs_vskap = get_vskstat_anchor(rootvfs);
1488
196daa2cf3db PSARC/2006/034 fsstat
rsb
parents: 994
diff changeset
   891
		}
196daa2cf3db PSARC/2006/034 fsstat
rsb
parents: 994
diff changeset
   892
		vfs_unrefvfssw(vswp);
196daa2cf3db PSARC/2006/034 fsstat
rsb
parents: 994
diff changeset
   893
	}
196daa2cf3db PSARC/2006/034 fsstat
rsb
parents: 994
diff changeset
   894
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   895
	/*
2621
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   896
	 * Mount /devices, /dev instance 1, /system/contract, /etc/mnttab,
3957
86c9dda5df37 PSARC/2007/052 In-kernel Sharetab
th199096
parents: 3912
diff changeset
   897
	 * /etc/svc/volatile, /etc/dfs/sharetab, /system/object, and /proc.
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   898
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   899
	vfs_mountdevices();
2621
4ea88858d952 PSARC/2003/246 Filesystem Driven Device Naming
llai1
parents: 1925
diff changeset
   900
	vfs_mountdev1();
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   901
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   902
	vfs_mountfs("ctfs", "ctfs", CTFS_ROOT);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   903
	vfs_mountfs("proc", "/proc", "/proc");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   904
	vfs_mountfs("mntfs", "/etc/mnttab", "/etc/mnttab");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   905
	vfs_mountfs("tmpfs", "/etc/svc/volatile", "/etc/svc/volatile");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   906
	vfs_mountfs("objfs", "objfs", OBJFS_ROOT);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   907
3957
86c9dda5df37 PSARC/2007/052 In-kernel Sharetab
th199096
parents: 3912
diff changeset
   908
	if (getzoneid() == GLOBAL_ZONEID) {
86c9dda5df37 PSARC/2007/052 In-kernel Sharetab
th199096
parents: 3912
diff changeset
   909
		vfs_mountfs("sharefs", "sharefs", "/etc/dfs/sharetab");
86c9dda5df37 PSARC/2007/052 In-kernel Sharetab
th199096
parents: 3912
diff changeset
   910
	}
86c9dda5df37 PSARC/2007/052 In-kernel Sharetab
th199096
parents: 3912
diff changeset
   911
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   912
#ifdef __sparc
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   913
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   914
	 * This bit of magic can go away when we convert sparc to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   915
	 * the new boot architecture based on ramdisk.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   916
	 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   917
	 * Booting off a mirrored root volume:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   918
	 * At this point, we have booted and mounted root on a
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   919
	 * single component of the mirror.  Complete the boot
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   920
	 * by configuring SVM and converting the root to the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   921
	 * dev_t of the mirrored root device.  This dev_t conversion
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   922
	 * only works because the underlying device doesn't change.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   923
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   924
	if (root_is_svm) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   925
		if (svm_rootconf()) {
3446
5903aece022d PSARC 2006/469 EOF and removal of eeprom -I
mrj
parents: 2621
diff changeset
   926
			panic("vfs_mountroot: cannot remount root");
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   927
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   928
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   929
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   930
		 * mnttab should reflect the new root device
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   931
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   932
		vfs_lock_wait(rootvfs);
12906
3ca11e9f39b7 6950914 remount can change mount point to "unspecified_mountpoint", causing panics
Robert Harris <Robert.Harris@Sun.COM>
parents: 12633
diff changeset
   933
		vfs_setresource(rootvfs, rootfs.bo_name, 0);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   934
		vfs_unlock(rootvfs);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   935
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   936
#endif /* __sparc */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   937
13832
8e4bcbc31a4a 1126 date(1)'s usage message doesn't mention -R
Yuri Pankov <yuri.pankov@nexenta.com>
parents: 13178
diff changeset
   938
	if (strcmp(rootfs.bo_fstype, "zfs") != 0) {
8e4bcbc31a4a 1126 date(1)'s usage message doesn't mention -R
Yuri Pankov <yuri.pankov@nexenta.com>
parents: 13178
diff changeset
   939
		/*
8e4bcbc31a4a 1126 date(1)'s usage message doesn't mention -R
Yuri Pankov <yuri.pankov@nexenta.com>
parents: 13178
diff changeset
   940
		 * Look up the root device via devfs so that a dv_node is
8e4bcbc31a4a 1126 date(1)'s usage message doesn't mention -R
Yuri Pankov <yuri.pankov@nexenta.com>
parents: 13178
diff changeset
   941
		 * created for it. The vnode is never VN_RELE()ed.
8e4bcbc31a4a 1126 date(1)'s usage message doesn't mention -R
Yuri Pankov <yuri.pankov@nexenta.com>
parents: 13178
diff changeset
   942
		 * We allocate more than MAXPATHLEN so that the
8e4bcbc31a4a 1126 date(1)'s usage message doesn't mention -R
Yuri Pankov <yuri.pankov@nexenta.com>
parents: 13178
diff changeset
   943
		 * buffer passed to i_ddi_prompath_to_devfspath() is
8e4bcbc31a4a 1126 date(1)'s usage message doesn't mention -R
Yuri Pankov <yuri.pankov@nexenta.com>
parents: 13178
diff changeset
   944
		 * exactly MAXPATHLEN (the function expects a buffer
8e4bcbc31a4a 1126 date(1)'s usage message doesn't mention -R
Yuri Pankov <yuri.pankov@nexenta.com>
parents: 13178
diff changeset
   945
		 * of that length).
8e4bcbc31a4a 1126 date(1)'s usage message doesn't mention -R
Yuri Pankov <yuri.pankov@nexenta.com>
parents: 13178
diff changeset
   946
		 */
8e4bcbc31a4a 1126 date(1)'s usage message doesn't mention -R
Yuri Pankov <yuri.pankov@nexenta.com>
parents: 13178
diff changeset
   947
		plen = strlen("/devices");
8e4bcbc31a4a 1126 date(1)'s usage message doesn't mention -R
Yuri Pankov <yuri.pankov@nexenta.com>
parents: 13178
diff changeset
   948
		path = kmem_alloc(plen + MAXPATHLEN, KM_SLEEP);
8e4bcbc31a4a 1126 date(1)'s usage message doesn't mention -R
Yuri Pankov <yuri.pankov@nexenta.com>
parents: 13178
diff changeset
   949
		(void) strcpy(path, "/devices");
8e4bcbc31a4a 1126 date(1)'s usage message doesn't mention -R
Yuri Pankov <yuri.pankov@nexenta.com>
parents: 13178
diff changeset
   950
8e4bcbc31a4a 1126 date(1)'s usage message doesn't mention -R
Yuri Pankov <yuri.pankov@nexenta.com>
parents: 13178
diff changeset
   951
		if (i_ddi_prompath_to_devfspath(rootfs.bo_name, path + plen)
8e4bcbc31a4a 1126 date(1)'s usage message doesn't mention -R
Yuri Pankov <yuri.pankov@nexenta.com>
parents: 13178
diff changeset
   952
		    != DDI_SUCCESS ||
8e4bcbc31a4a 1126 date(1)'s usage message doesn't mention -R
Yuri Pankov <yuri.pankov@nexenta.com>
parents: 13178
diff changeset
   953
		    lookupname(path, UIO_SYSSPACE, FOLLOW, NULLVPP, &rvp)) {
8e4bcbc31a4a 1126 date(1)'s usage message doesn't mention -R
Yuri Pankov <yuri.pankov@nexenta.com>
parents: 13178
diff changeset
   954
8e4bcbc31a4a 1126 date(1)'s usage message doesn't mention -R
Yuri Pankov <yuri.pankov@nexenta.com>
parents: 13178
diff changeset
   955
			/* NUL terminate in case "path" has garbage */
8e4bcbc31a4a 1126 date(1)'s usage message doesn't mention -R
Yuri Pankov <yuri.pankov@nexenta.com>
parents: 13178
diff changeset
   956
			path[plen + MAXPATHLEN - 1] = '\0';
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   957
#ifdef	DEBUG
13832
8e4bcbc31a4a 1126 date(1)'s usage message doesn't mention -R
Yuri Pankov <yuri.pankov@nexenta.com>
parents: 13178
diff changeset
   958
			cmn_err(CE_WARN, "!Cannot lookup root device: %s",
8e4bcbc31a4a 1126 date(1)'s usage message doesn't mention -R
Yuri Pankov <yuri.pankov@nexenta.com>
parents: 13178
diff changeset
   959
			    path);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   960
#endif
13832
8e4bcbc31a4a 1126 date(1)'s usage message doesn't mention -R
Yuri Pankov <yuri.pankov@nexenta.com>
parents: 13178
diff changeset
   961
		}
8e4bcbc31a4a 1126 date(1)'s usage message doesn't mention -R
Yuri Pankov <yuri.pankov@nexenta.com>
parents: 13178
diff changeset
   962
		kmem_free(path, plen + MAXPATHLEN);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   963
	}
13832
8e4bcbc31a4a 1126 date(1)'s usage message doesn't mention -R
Yuri Pankov <yuri.pankov@nexenta.com>
parents: 13178
diff changeset
   964
4863
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
   965
	vfs_mnttabvp_setup();
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   966
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   967
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   968
/*
6734
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
   969
 * Check to see if our "block device" is actually a file.  If so,
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
   970
 * automatically add a lofi device, and keep track of this fact.
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
   971
 */
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
   972
static int
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
   973
lofi_add(const char *fsname, struct vfs *vfsp,
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
   974
    mntopts_t *mntopts, struct mounta *uap)
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
   975
{
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
   976
	int fromspace = (uap->flags & MS_SYSSPACE) ?
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
   977
	    UIO_SYSSPACE : UIO_USERSPACE;
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
   978
	struct lofi_ioctl *li = NULL;
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
   979
	struct vnode *vp = NULL;
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
   980
	struct pathname	pn = { NULL };
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
   981
	ldi_ident_t ldi_id;
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
   982
	ldi_handle_t ldi_hdl;
6855
18f1316f1bed PSARC 2008/366 VSW_CANLOFI
johnlev
parents: 6770
diff changeset
   983
	vfssw_t *vfssw;
6734
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
   984
	int minor;
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
   985
	int err = 0;
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
   986
12633
9f2cda0ed938 PSARC 2010/144 lofi(7D) in non global zones
John Levon <john.levon@sun.com>
parents: 11173
diff changeset
   987
	if ((vfssw = vfs_getvfssw(fsname)) == NULL)
6734
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
   988
		return (0);
6855
18f1316f1bed PSARC 2008/366 VSW_CANLOFI
johnlev
parents: 6770
diff changeset
   989
18f1316f1bed PSARC 2008/366 VSW_CANLOFI
johnlev
parents: 6770
diff changeset
   990
	if (!(vfssw->vsw_flag & VSW_CANLOFI)) {
18f1316f1bed PSARC 2008/366 VSW_CANLOFI
johnlev
parents: 6770
diff changeset
   991
		vfs_unrefvfssw(vfssw);
6734
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
   992
		return (0);
6855
18f1316f1bed PSARC 2008/366 VSW_CANLOFI
johnlev
parents: 6770
diff changeset
   993
	}
18f1316f1bed PSARC 2008/366 VSW_CANLOFI
johnlev
parents: 6770
diff changeset
   994
18f1316f1bed PSARC 2008/366 VSW_CANLOFI
johnlev
parents: 6770
diff changeset
   995
	vfs_unrefvfssw(vfssw);
18f1316f1bed PSARC 2008/366 VSW_CANLOFI
johnlev
parents: 6770
diff changeset
   996
	vfssw = NULL;
6734
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
   997
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
   998
	if (pn_get(uap->spec, fromspace, &pn) != 0)
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
   999
		return (0);
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1000
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1001
	if (lookupname(uap->spec, fromspace, FOLLOW, NULL, &vp) != 0)
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1002
		goto out;
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1003
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1004
	if (vp->v_type != VREG)
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1005
		goto out;
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1006
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1007
	/* OK, this is a lofi mount. */
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1008
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1009
	if ((uap->flags & (MS_REMOUNT|MS_GLOBAL)) ||
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1010
	    vfs_optionisset_nolock(mntopts, MNTOPT_SUID, NULL) ||
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1011
	    vfs_optionisset_nolock(mntopts, MNTOPT_SETUID, NULL) ||
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1012
	    vfs_optionisset_nolock(mntopts, MNTOPT_DEVICES, NULL)) {
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1013
		err = EINVAL;
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1014
		goto out;
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1015
	}
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1016
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1017
	ldi_id = ldi_ident_from_anon();
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1018
	li = kmem_zalloc(sizeof (*li), KM_SLEEP);
8081
cb8ad0d5637f 6743213 lofi ioctl filename should be MAXPATHLEN
Dina K Nimeh <Dina.Nimeh@Sun.Com>
parents: 7757
diff changeset
  1019
	(void) strlcpy(li->li_filename, pn.pn_path, MAXPATHLEN);
6734
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1020
12633
9f2cda0ed938 PSARC 2010/144 lofi(7D) in non global zones
John Levon <john.levon@sun.com>
parents: 11173
diff changeset
  1021
	err = ldi_open_by_name("/dev/lofictl", FREAD | FWRITE, kcred,
9f2cda0ed938 PSARC 2010/144 lofi(7D) in non global zones
John Levon <john.levon@sun.com>
parents: 11173
diff changeset
  1022
	    &ldi_hdl, ldi_id);
6734
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1023
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1024
	if (err)
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1025
		goto out2;
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1026
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1027
	err = ldi_ioctl(ldi_hdl, LOFI_MAP_FILE, (intptr_t)li,
12633
9f2cda0ed938 PSARC 2010/144 lofi(7D) in non global zones
John Levon <john.levon@sun.com>
parents: 11173
diff changeset
  1028
	    FREAD | FWRITE | FKIOCTL, kcred, &minor);
9f2cda0ed938 PSARC 2010/144 lofi(7D) in non global zones
John Levon <john.levon@sun.com>
parents: 11173
diff changeset
  1029
9f2cda0ed938 PSARC 2010/144 lofi(7D) in non global zones
John Levon <john.levon@sun.com>
parents: 11173
diff changeset
  1030
	(void) ldi_close(ldi_hdl, FREAD | FWRITE, kcred);
6734
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1031
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1032
	if (!err)
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1033
		vfsp->vfs_lofi_minor = minor;
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1034
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1035
out2:
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1036
	ldi_ident_release(ldi_id);
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1037
out:
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1038
	if (li != NULL)
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1039
		kmem_free(li, sizeof (*li));
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1040
	if (vp != NULL)
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1041
		VN_RELE(vp);
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1042
	pn_free(&pn);
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1043
	return (err);
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1044
}
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1045
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1046
static void
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1047
lofi_remove(struct vfs *vfsp)
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1048
{
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1049
	struct lofi_ioctl *li = NULL;
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1050
	ldi_ident_t ldi_id;
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1051
	ldi_handle_t ldi_hdl;
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1052
	int err;
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1053
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1054
	if (vfsp->vfs_lofi_minor == 0)
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1055
		return;
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1056
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1057
	ldi_id = ldi_ident_from_anon();
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1058
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1059
	li = kmem_zalloc(sizeof (*li), KM_SLEEP);
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1060
	li->li_minor = vfsp->vfs_lofi_minor;
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1061
	li->li_cleanup = B_TRUE;
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1062
12633
9f2cda0ed938 PSARC 2010/144 lofi(7D) in non global zones
John Levon <john.levon@sun.com>
parents: 11173
diff changeset
  1063
	err = ldi_open_by_name("/dev/lofictl", FREAD | FWRITE, kcred,
9f2cda0ed938 PSARC 2010/144 lofi(7D) in non global zones
John Levon <john.levon@sun.com>
parents: 11173
diff changeset
  1064
	    &ldi_hdl, ldi_id);
6734
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1065
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1066
	if (err)
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1067
		goto out;
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1068
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1069
	err = ldi_ioctl(ldi_hdl, LOFI_UNMAP_FILE_MINOR, (intptr_t)li,
12633
9f2cda0ed938 PSARC 2010/144 lofi(7D) in non global zones
John Levon <john.levon@sun.com>
parents: 11173
diff changeset
  1070
	    FREAD | FWRITE | FKIOCTL, kcred, NULL);
9f2cda0ed938 PSARC 2010/144 lofi(7D) in non global zones
John Levon <john.levon@sun.com>
parents: 11173
diff changeset
  1071
9f2cda0ed938 PSARC 2010/144 lofi(7D) in non global zones
John Levon <john.levon@sun.com>
parents: 11173
diff changeset
  1072
	(void) ldi_close(ldi_hdl, FREAD | FWRITE, kcred);
6734
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1073
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1074
	if (!err)
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1075
		vfsp->vfs_lofi_minor = 0;
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1076
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1077
out:
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1078
	ldi_ident_release(ldi_id);
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1079
	if (li != NULL)
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1080
		kmem_free(li, sizeof (*li));
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1081
}
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1082
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1083
/*
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1084
 * Common mount code.  Called from the system call entry point, from autofs,
5302
eec6aeacde6e PSARC 2007/416 NFSv4 Mirror-mounts
th199096
parents: 5084
diff changeset
  1085
 * nfsv4 trigger mounts, and from pxfs.
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1086
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1087
 * Takes the effective file system type, mount arguments, the mount point
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1088
 * vnode, flags specifying whether the mount is a remount and whether it
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1089
 * should be entered into the vfs list, and credentials.  Fills in its vfspp
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1090
 * parameter with the mounted file system instance's vfs.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1091
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1092
 * Note that the effective file system type is specified as a string.  It may
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1093
 * be null, in which case it's determined from the mount arguments, and may
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1094
 * differ from the type specified in the mount arguments; this is a hook to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1095
 * allow interposition when instantiating file system instances.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1096
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1097
 * The caller is responsible for releasing its own hold on the mount point
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1098
 * vp (this routine does its own hold when necessary).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1099
 * Also note that for remounts, the mount point vp should be the vnode for
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1100
 * the root of the file system rather than the vnode that the file system
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1101
 * is mounted on top of.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1102
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1103
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1104
domount(char *fsname, struct mounta *uap, vnode_t *vp, struct cred *credp,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1105
	struct vfs **vfspp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1106
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1107
	struct vfssw	*vswp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1108
	vfsops_t	*vfsops;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1109
	struct vfs	*vfsp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1110
	struct vnode	*bvp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1111
	dev_t		bdev = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1112
	mntopts_t	mnt_mntopts;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1113
	int		error = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1114
	int		copyout_error = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1115
	int		ovflags;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1116
	char		*opts = uap->optptr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1117
	char		*inargs = opts;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1118
	int		optlen = uap->optlen;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1119
	int		remount;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1120
	int		rdonly;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1121
	int		nbmand = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1122
	int		delmip = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1123
	int		addmip = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1124
	int		splice = ((uap->flags & MS_NOSPLICE) == 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1125
	int		fromspace = (uap->flags & MS_SYSSPACE) ?
3912
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3904
diff changeset
  1126
	    UIO_SYSSPACE : UIO_USERSPACE;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1127
	char		*resource = NULL, *mountpt = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1128
	refstr_t	*oldresource, *oldmntpt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1129
	struct pathname	pn, rpn;
1520
2fb01d86c1c1 6391295 fop_create() panic when running svvs over ZFS
rsb
parents: 1488
diff changeset
  1130
	vsk_anchor_t	*vskap;
6734
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1131
	char fstname[FSTYPSZ];
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1132
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1133
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1134
	 * The v_flag value for the mount point vp is permanently set
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1135
	 * to VVFSLOCK so that no one bypasses the vn_vfs*locks routine
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1136
	 * for mount point locking.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1137
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1138
	mutex_enter(&vp->v_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1139
	vp->v_flag |= VVFSLOCK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1140
	mutex_exit(&vp->v_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1141
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1142
	mnt_mntopts.mo_count = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1143
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1144
	 * Find the ops vector to use to invoke the file system-specific mount
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1145
	 * method.  If the fsname argument is non-NULL, use it directly.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1146
	 * Otherwise, dig the file system type information out of the mount
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1147
	 * arguments.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1148
	 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1149
	 * A side effect is to hold the vfssw entry.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1150
	 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1151
	 * Mount arguments can be specified in several ways, which are
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1152
	 * distinguished by flag bit settings.  The preferred way is to set
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1153
	 * MS_OPTIONSTR, indicating an 8 argument mount with the file system
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1154
	 * type supplied as a character string and the last two arguments
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1155
	 * being a pointer to a character buffer and the size of the buffer.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1156
	 * On entry, the buffer holds a null terminated list of options; on
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1157
	 * return, the string is the list of options the file system
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1158
	 * recognized. If MS_DATA is set arguments five and six point to a
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1159
	 * block of binary data which the file system interprets.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1160
	 * A further wrinkle is that some callers don't set MS_FSS and MS_DATA
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1161
	 * consistently with these conventions.  To handle them, we check to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1162
	 * see whether the pointer to the file system name has a numeric value
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1163
	 * less than 256.  If so, we treat it as an index.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1164
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1165
	if (fsname != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1166
		if ((vswp = vfs_getvfssw(fsname)) == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1167
			return (EINVAL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1168
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1169
	} else if (uap->flags & (MS_OPTIONSTR | MS_DATA | MS_FSS)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1170
		size_t n;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1171
		uint_t fstype;
6734
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1172
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1173
		fsname = fstname;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1174
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1175
		if ((fstype = (uintptr_t)uap->fstype) < 256) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1176
			RLOCK_VFSSW();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1177
			if (fstype == 0 || fstype >= nfstype ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1178
			    !ALLOCATED_VFSSW(&vfssw[fstype])) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1179
				RUNLOCK_VFSSW();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1180
				return (EINVAL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1181
			}
6734
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1182
			(void) strcpy(fsname, vfssw[fstype].vsw_name);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1183
			RUNLOCK_VFSSW();
6734
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1184
			if ((vswp = vfs_getvfssw(fsname)) == NULL)
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1185
				return (EINVAL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1186
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1187
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1188
			 * Handle either kernel or user address space.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1189
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1190
			if (uap->flags & MS_SYSSPACE) {
6734
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1191
				error = copystr(uap->fstype, fsname,
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1192
				    FSTYPSZ, &n);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1193
			} else {
6734
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1194
				error = copyinstr(uap->fstype, fsname,
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1195
				    FSTYPSZ, &n);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1196
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1197
			if (error) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1198
				if (error == ENAMETOOLONG)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1199
					return (EINVAL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1200
				return (error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1201
			}
6734
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1202
			if ((vswp = vfs_getvfssw(fsname)) == NULL)
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1203
				return (EINVAL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1204
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1205
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1206
		if ((vswp = vfs_getvfsswbyvfsops(vfs_getops(rootvfs))) == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1207
			return (EINVAL);
12633
9f2cda0ed938 PSARC 2010/144 lofi(7D) in non global zones
John Levon <john.levon@sun.com>
parents: 11173
diff changeset
  1208
		fsname = vswp->vsw_name;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1209
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1210
	if (!VFS_INSTALLED(vswp))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1211
		return (EINVAL);
12633
9f2cda0ed938 PSARC 2010/144 lofi(7D) in non global zones
John Levon <john.levon@sun.com>
parents: 11173
diff changeset
  1212
9f2cda0ed938 PSARC 2010/144 lofi(7D) in non global zones
John Levon <john.levon@sun.com>
parents: 11173
diff changeset
  1213
	if ((error = secpolicy_fs_allowed_mount(fsname)) != 0)  {
9f2cda0ed938 PSARC 2010/144 lofi(7D) in non global zones
John Levon <john.levon@sun.com>
parents: 11173
diff changeset
  1214
		vfs_unrefvfssw(vswp);
9f2cda0ed938 PSARC 2010/144 lofi(7D) in non global zones
John Levon <john.levon@sun.com>
parents: 11173
diff changeset
  1215
		return (error);
9f2cda0ed938 PSARC 2010/144 lofi(7D) in non global zones
John Levon <john.levon@sun.com>
parents: 11173
diff changeset
  1216
	}
9f2cda0ed938 PSARC 2010/144 lofi(7D) in non global zones
John Levon <john.levon@sun.com>
parents: 11173
diff changeset
  1217
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1218
	vfsops = &vswp->vsw_vfsops;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1219
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1220
	vfs_copyopttbl(&vswp->vsw_optproto, &mnt_mntopts);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1221
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1222
	 * Fetch mount options and parse them for generic vfs options
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1223
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1224
	if (uap->flags & MS_OPTIONSTR) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1225
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1226
		 * Limit the buffer size
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1227
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1228
		if (optlen < 0 || optlen > MAX_MNTOPT_STR) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1229
			error = EINVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1230
			goto errout;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1231
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1232
		if ((uap->flags & MS_SYSSPACE) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1233
			inargs = kmem_alloc(MAX_MNTOPT_STR, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1234
			inargs[0] = '\0';
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1235
			if (optlen) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1236
				error = copyinstr(opts, inargs, (size_t)optlen,
3912
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3904
diff changeset
  1237
				    NULL);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1238
				if (error) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1239
					goto errout;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1240
				}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1241
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1242
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1243
		vfs_parsemntopts(&mnt_mntopts, inargs, 0);
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
	 * Flag bits override the options string.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1247
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1248
	if (uap->flags & MS_REMOUNT)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1249
		vfs_setmntopt_nolock(&mnt_mntopts, MNTOPT_REMOUNT, NULL, 0, 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1250
	if (uap->flags & MS_RDONLY)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1251
		vfs_setmntopt_nolock(&mnt_mntopts, MNTOPT_RO, NULL, 0, 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1252
	if (uap->flags & MS_NOSUID)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1253
		vfs_setmntopt_nolock(&mnt_mntopts, MNTOPT_NOSUID, NULL, 0, 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1254
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1255
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1256
	 * Check if this is a remount; must be set in the option string and
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1257
	 * the file system must support a remount option.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1258
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1259
	if (remount = vfs_optionisset_nolock(&mnt_mntopts,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1260
	    MNTOPT_REMOUNT, NULL)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1261
		if (!(vswp->vsw_flag & VSW_CANREMOUNT)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1262
			error = ENOTSUP;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1263
			goto errout;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1264
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1265
		uap->flags |= MS_REMOUNT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1266
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1267
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1268
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1269
	 * uap->flags and vfs_optionisset() should agree.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1270
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1271
	if (rdonly = vfs_optionisset_nolock(&mnt_mntopts, MNTOPT_RO, NULL)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1272
		uap->flags |= MS_RDONLY;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1273
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1274
	if (vfs_optionisset_nolock(&mnt_mntopts, MNTOPT_NOSUID, NULL)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1275
		uap->flags |= MS_NOSUID;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1276
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1277
	nbmand = vfs_optionisset_nolock(&mnt_mntopts, MNTOPT_NBMAND, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1278
	ASSERT(splice || !remount);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1279
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1280
	 * If we are splicing the fs into the namespace,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1281
	 * perform mount point checks.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1282
	 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1283
	 * We want to resolve the path for the mount point to eliminate
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1284
	 * '.' and ".." and symlinks in mount points; we can't do the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1285
	 * same for the resource string, since it would turn
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1286
	 * "/dev/dsk/c0t0d0s0" into "/devices/pci@...".  We need to do
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1287
	 * this before grabbing vn_vfswlock(), because otherwise we
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1288
	 * would deadlock with lookuppn().
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1289
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1290
	if (splice) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1291
		ASSERT(vp->v_count > 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1292
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1293
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1294
		 * Pick up mount point and device from appropriate space.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1295
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1296
		if (pn_get(uap->spec, fromspace, &pn) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1297
			resource = kmem_alloc(pn.pn_pathlen + 1,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1298
			    KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1299
			(void) strcpy(resource, pn.pn_path);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1300
			pn_free(&pn);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1301
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1302
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1303
		 * Do a lookupname prior to taking the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1304
		 * writelock. Mark this as completed if
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1305
		 * successful for later cleanup and addition to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1306
		 * the mount in progress table.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1307
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1308
		if ((uap->flags & MS_GLOBAL) == 0 &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1309
		    lookupname(uap->spec, fromspace,
3912
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3904
diff changeset
  1310
		    FOLLOW, NULL, &bvp) == 0) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1311
			addmip = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1312
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1313
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1314
		if ((error = pn_get(uap->dir, fromspace, &pn)) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1315
			pathname_t *pnp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1316
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1317
			if (*pn.pn_path != '/') {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1318
				error = EINVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1319
				pn_free(&pn);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1320
				goto errout;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1321
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1322
			pn_alloc(&rpn);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1323
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1324
			 * Kludge to prevent autofs from deadlocking with
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1325
			 * itself when it calls domount().
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1326
			 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1327
			 * If autofs is calling, it is because it is doing
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1328
			 * (autofs) mounts in the process of an NFS mount.  A
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1329
			 * lookuppn() here would cause us to block waiting for
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1330
			 * said NFS mount to complete, which can't since this
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1331
			 * is the thread that was supposed to doing it.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1332
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1333
			if (fromspace == UIO_USERSPACE) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1334
				if ((error = lookuppn(&pn, &rpn, FOLLOW, NULL,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1335
				    NULL)) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1336
					pnp = &rpn;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1337
				} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1338
					/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1339
					 * The file disappeared or otherwise
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1340
					 * became inaccessible since we opened
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1341
					 * it; might as well fail the mount
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1342
					 * since the mount point is no longer
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1343
					 * accessible.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1344
					 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1345
					pn_free(&rpn);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1346
					pn_free(&pn);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1347
					goto errout;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1348
				}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1349
			} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1350
				pnp = &pn;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1351
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1352
			mountpt = kmem_alloc(pnp->pn_pathlen + 1, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1353
			(void) strcpy(mountpt, pnp->pn_path);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1354
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1355
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1356
			 * If the addition of the zone's rootpath
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1357
			 * would push us over a total path length
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1358
			 * of MAXPATHLEN, we fail the mount with
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1359
			 * ENAMETOOLONG, which is what we would have
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1360
			 * gotten if we were trying to perform the same
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1361
			 * mount in the global zone.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1362
			 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1363
			 * strlen() doesn't count the trailing
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1364
			 * '\0', but zone_rootpathlen counts both a
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1365
			 * trailing '/' and the terminating '\0'.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1366
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1367
			if ((curproc->p_zone->zone_rootpathlen - 1 +
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1368
			    strlen(mountpt)) > MAXPATHLEN ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1369
			    (resource != NULL &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1370
			    (curproc->p_zone->zone_rootpathlen - 1 +
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1371
			    strlen(resource)) > MAXPATHLEN)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1372
				error = ENAMETOOLONG;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1373
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1374
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1375
			pn_free(&rpn);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1376
			pn_free(&pn);
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 (error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1380
			goto errout;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1381
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1382
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1383
		 * Prevent path name resolution from proceeding past
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1384
		 * the mount point.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1385
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1386
		if (vn_vfswlock(vp) != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1387
			error = EBUSY;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1388
			goto errout;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1389
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1390
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1391
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1392
		 * Verify that it's legitimate to establish a mount on
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1393
		 * the prospective mount point.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1394
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1395
		if (vn_mountedvfs(vp) != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1396
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1397
			 * The mount point lock was obtained after some
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1398
			 * other thread raced through and established a mount.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1399
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1400
			vn_vfsunlock(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1401
			error = EBUSY;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1402
			goto errout;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1403
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1404
		if (vp->v_flag & VNOMOUNT) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1405
			vn_vfsunlock(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1406
			error = EINVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1407
			goto errout;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1408
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1409
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1410
	if ((uap->flags & (MS_DATA | MS_OPTIONSTR)) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1411
		uap->dataptr = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1412
		uap->datalen = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1413
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1414
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1415
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1416
	 * If this is a remount, we don't want to create a new VFS.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1417
	 * Instead, we pass the existing one with a remount flag.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1418
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1419
	if (remount) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1420
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1421
		 * Confirm that the mount point is the root vnode of the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1422
		 * file system that is being remounted.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1423
		 * This can happen if the user specifies a different
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1424
		 * mount point directory pathname in the (re)mount command.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1425
		 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1426
		 * Code below can only be reached if splice is true, so it's
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1427
		 * safe to do vn_vfsunlock() here.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1428
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1429
		if ((vp->v_flag & VROOT) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1430
			vn_vfsunlock(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1431
			error = ENOENT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1432
			goto errout;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1433
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1434
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1435
		 * Disallow making file systems read-only unless file system
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1436
		 * explicitly allows it in its vfssw.  Ignore other flags.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1437
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1438
		if (rdonly && vn_is_readonly(vp) == 0 &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1439
		    (vswp->vsw_flag & VSW_CANRWRO) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1440
			vn_vfsunlock(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1441
			error = EINVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1442
			goto errout;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1443
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1444
		/*
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  1445
		 * Disallow changing the NBMAND disposition of the file
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  1446
		 * system on remounts.
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1447
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1448
		if ((nbmand && ((vp->v_vfsp->vfs_flag & VFS_NBMAND) == 0)) ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1449
		    (!nbmand && (vp->v_vfsp->vfs_flag & VFS_NBMAND))) {
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  1450
			vn_vfsunlock(vp);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  1451
			error = EINVAL;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  1452
			goto errout;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1453
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1454
		vfsp = vp->v_vfsp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1455
		ovflags = vfsp->vfs_flag;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1456
		vfsp->vfs_flag |= VFS_REMOUNT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1457
		vfsp->vfs_flag &= ~VFS_RDONLY;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1458
	} else {
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  1459
		vfsp = vfs_alloc(KM_SLEEP);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1460
		VFS_INIT(vfsp, vfsops, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1461
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1462
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1463
	VFS_HOLD(vfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1464
6734
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1465
	if ((error = lofi_add(fsname, vfsp, &mnt_mntopts, uap)) != 0) {
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1466
		if (!remount) {
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1467
			if (splice)
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1468
				vn_vfsunlock(vp);
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1469
			vfs_free(vfsp);
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1470
		} else {
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1471
			vn_vfsunlock(vp);
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1472
			VFS_RELE(vfsp);
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1473
		}
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1474
		goto errout;
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1475
	}
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1476
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1477
	/*
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1478
	 * PRIV_SYS_MOUNT doesn't mean you can become root.
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1479
	 */
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1480
	if (vfsp->vfs_lofi_minor != 0) {
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1481
		uap->flags |= MS_NOSUID;
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1482
		vfs_setmntopt_nolock(&mnt_mntopts, MNTOPT_NOSUID, NULL, 0, 0);
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1483
	}
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1484
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1485
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1486
	 * The vfs_reflock is not used anymore the code below explicitly
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1487
	 * holds it preventing others accesing it directly.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1488
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1489
	if ((sema_tryp(&vfsp->vfs_reflock) == 0) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1490
	    !(vfsp->vfs_flag & VFS_REMOUNT))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1491
		cmn_err(CE_WARN,
3446
5903aece022d PSARC 2006/469 EOF and removal of eeprom -I
mrj
parents: 2621
diff changeset
  1492
		    "mount type %s couldn't get vfs_reflock", vswp->vsw_name);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1493
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1494
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1495
	 * Lock the vfs. If this is a remount we want to avoid spurious umount
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1496
	 * failures that happen as a side-effect of fsflush() and other mount
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1497
	 * and unmount operations that might be going on simultaneously and
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1498
	 * may have locked the vfs currently. To not return EBUSY immediately
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1499
	 * here we use vfs_lock_wait() instead vfs_lock() for the remount case.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1500
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1501
	if (!remount) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1502
		if (error = vfs_lock(vfsp)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1503
			vfsp->vfs_flag = ovflags;
6734
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1504
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1505
			lofi_remove(vfsp);
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1506
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1507
			if (splice)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1508
				vn_vfsunlock(vp);
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  1509
			vfs_free(vfsp);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1510
			goto errout;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1511
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1512
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1513
		vfs_lock_wait(vfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1514
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1515
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1516
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1517
	 * Add device to mount in progress table, global mounts require special
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1518
	 * handling. It is possible that we have already done the lookupname
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1519
	 * 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
  1520
	 * since we cannot do a lookupname after taking the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1521
	 * wlock above. This case is for a non-spliced, non-global filesystem.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1522
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1523
	if (!addmip) {
3912
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3904
diff changeset
  1524
		if ((uap->flags & MS_GLOBAL) == 0 &&
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3904
diff changeset
  1525
		    lookupname(uap->spec, fromspace, FOLLOW, NULL, &bvp) == 0) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1526
			addmip = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1527
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1528
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1529
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1530
	if (addmip) {
6734
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1531
		vnode_t *lvp = NULL;
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1532
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1533
		error = vfs_get_lofi(vfsp, &lvp);
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1534
		if (error > 0) {
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1535
			lofi_remove(vfsp);
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1536
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1537
			if (splice)
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1538
				vn_vfsunlock(vp);
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1539
			vfs_unlock(vfsp);
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1540
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1541
			if (remount) {
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1542
				VFS_RELE(vfsp);
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1543
			} else {
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1544
				vfs_free(vfsp);
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1545
			}
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1546
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1547
			goto errout;
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1548
		} else if (error == -1) {
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1549
			bdev = bvp->v_rdev;
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1550
			VN_RELE(bvp);
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1551
		} else {
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1552
			bdev = lvp->v_rdev;
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1553
			VN_RELE(lvp);
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1554
			VN_RELE(bvp);
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1555
		}
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1556
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1557
		vfs_addmip(bdev, vfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1558
		addmip = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1559
		delmip = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1560
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1561
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1562
	 * Invalidate cached entry for the mount point.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1563
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1564
	if (splice)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1565
		dnlc_purge_vp(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1566
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1567
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1568
	 * If have an option string but the filesystem doesn't supply a
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1569
	 * prototype options table, create a table with the global
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1570
	 * options and sufficient room to accept all the options in the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1571
	 * string.  Then parse the passed in option string
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1572
	 * accepting all the options in the string.  This gives us an
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1573
	 * option table with all the proper cancel properties for the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1574
	 * global options.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1575
	 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1576
	 * Filesystems that supply a prototype options table are handled
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1577
	 * earlier in this function.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1578
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1579
	if (uap->flags & MS_OPTIONSTR) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1580
		if (!(vswp->vsw_flag & VSW_HASPROTO)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1581
			mntopts_t tmp_mntopts;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1582
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1583
			tmp_mntopts.mo_count = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1584
			vfs_createopttbl_extend(&tmp_mntopts, inargs,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1585
			    &mnt_mntopts);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1586
			vfs_parsemntopts(&tmp_mntopts, inargs, 1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1587
			vfs_swapopttbl_nolock(&mnt_mntopts, &tmp_mntopts);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1588
			vfs_freeopttbl(&tmp_mntopts);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1589
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1590
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1591
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1592
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1593
	 * Serialize with zone creations.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1594
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1595
	mount_in_progress();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1596
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1597
	 * Instantiate (or reinstantiate) the file system.  If appropriate,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1598
	 * splice it into the file system name space.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1599
	 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1600
	 * We want VFS_MOUNT() to be able to override the vfs_resource
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1601
	 * string if necessary (ie, mntfs), and also for a remount to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1602
	 * change the same (necessary when remounting '/' during boot).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1603
	 * So we set up vfs_mntpt and vfs_resource to what we think they
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1604
	 * should be, then hand off control to VFS_MOUNT() which can
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1605
	 * override this.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1606
	 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1607
	 * For safety's sake, when changing vfs_resource or vfs_mntpt of
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1608
	 * a vfs which is on the vfs list (i.e. during a remount), we must
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1609
	 * never set those fields to NULL. Several bits of code make
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1610
	 * assumptions that the fields are always valid.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1611
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1612
	vfs_swapopttbl(&mnt_mntopts, &vfsp->vfs_mntopts);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1613
	if (remount) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1614
		if ((oldresource = vfsp->vfs_resource) != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1615
			refstr_hold(oldresource);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1616
		if ((oldmntpt = vfsp->vfs_mntpt) != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1617
			refstr_hold(oldmntpt);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1618
	}
12906
3ca11e9f39b7 6950914 remount can change mount point to "unspecified_mountpoint", causing panics
Robert Harris <Robert.Harris@Sun.COM>
parents: 12633
diff changeset
  1619
	vfs_setresource(vfsp, resource, 0);
3ca11e9f39b7 6950914 remount can change mount point to "unspecified_mountpoint", causing panics
Robert Harris <Robert.Harris@Sun.COM>
parents: 12633
diff changeset
  1620
	vfs_setmntpoint(vfsp, mountpt, 0);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1621
4863
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  1622
	/*
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  1623
	 * going to mount on this vnode, so notify.
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  1624
	 */
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  1625
	vnevent_mountedover(vp, NULL);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1626
	error = VFS_MOUNT(vfsp, vp, uap, credp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1627
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1628
	if (uap->flags & MS_RDONLY)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1629
		vfs_setmntopt(vfsp, MNTOPT_RO, NULL, 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1630
	if (uap->flags & MS_NOSUID)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1631
		vfs_setmntopt(vfsp, MNTOPT_NOSUID, NULL, 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1632
	if (uap->flags & MS_GLOBAL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1633
		vfs_setmntopt(vfsp, MNTOPT_GLOBAL, NULL, 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1634
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1635
	if (error) {
6734
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1636
		lofi_remove(vfsp);
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1637
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1638
		if (remount) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1639
			/* put back pre-remount options */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1640
			vfs_swapopttbl(&mnt_mntopts, &vfsp->vfs_mntopts);
12906
3ca11e9f39b7 6950914 remount can change mount point to "unspecified_mountpoint", causing panics
Robert Harris <Robert.Harris@Sun.COM>
parents: 12633
diff changeset
  1641
			vfs_setmntpoint(vfsp, refstr_value(oldmntpt),
3ca11e9f39b7 6950914 remount can change mount point to "unspecified_mountpoint", causing panics
Robert Harris <Robert.Harris@Sun.COM>
parents: 12633
diff changeset
  1642
			    VFSSP_VERBATIM);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1643
			if (oldmntpt)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1644
				refstr_rele(oldmntpt);
12906
3ca11e9f39b7 6950914 remount can change mount point to "unspecified_mountpoint", causing panics
Robert Harris <Robert.Harris@Sun.COM>
parents: 12633
diff changeset
  1645
			vfs_setresource(vfsp, refstr_value(oldresource),
3ca11e9f39b7 6950914 remount can change mount point to "unspecified_mountpoint", causing panics
Robert Harris <Robert.Harris@Sun.COM>
parents: 12633
diff changeset
  1646
			    VFSSP_VERBATIM);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1647
			if (oldresource)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1648
				refstr_rele(oldresource);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1649
			vfsp->vfs_flag = ovflags;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1650
			vfs_unlock(vfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1651
			VFS_RELE(vfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1652
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1653
			vfs_unlock(vfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1654
			vfs_freemnttab(vfsp);
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  1655
			vfs_free(vfsp);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1656
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1657
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1658
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1659
		 * Set the mount time to now
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1660
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1661
		vfsp->vfs_mtime = ddi_get_time();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1662
		if (remount) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1663
			vfsp->vfs_flag &= ~VFS_REMOUNT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1664
			if (oldresource)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1665
				refstr_rele(oldresource);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1666
			if (oldmntpt)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1667
				refstr_rele(oldmntpt);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1668
		} else if (splice) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1669
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1670
			 * Link vfsp into the name space at the mount
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1671
			 * point. Vfs_add() is responsible for
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1672
			 * holding the mount point which will be
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1673
			 * released when vfs_remove() is called.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1674
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1675
			vfs_add(vp, vfsp, uap->flags);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1676
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1677
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1678
			 * Hold the reference to file system which is
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1679
			 * not linked into the name space.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1680
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1681
			vfsp->vfs_zone = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1682
			VFS_HOLD(vfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1683
			vfsp->vfs_vnodecovered = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1684
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1685
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1686
		 * Set flags for global options encountered
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1687
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1688
		if (vfs_optionisset(vfsp, MNTOPT_RO, NULL))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1689
			vfsp->vfs_flag |= VFS_RDONLY;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1690
		else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1691
			vfsp->vfs_flag &= ~VFS_RDONLY;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1692
		if (vfs_optionisset(vfsp, MNTOPT_NOSUID, NULL)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1693
			vfsp->vfs_flag |= (VFS_NOSETUID|VFS_NODEVICES);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1694
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1695
			if (vfs_optionisset(vfsp, MNTOPT_NODEVICES, NULL))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1696
				vfsp->vfs_flag |= VFS_NODEVICES;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1697
			else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1698
				vfsp->vfs_flag &= ~VFS_NODEVICES;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1699
			if (vfs_optionisset(vfsp, MNTOPT_NOSETUID, NULL))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1700
				vfsp->vfs_flag |= VFS_NOSETUID;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1701
			else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1702
				vfsp->vfs_flag &= ~VFS_NOSETUID;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1703
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1704
		if (vfs_optionisset(vfsp, MNTOPT_NBMAND, NULL))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1705
			vfsp->vfs_flag |= VFS_NBMAND;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1706
		else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1707
			vfsp->vfs_flag &= ~VFS_NBMAND;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1708
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1709
		if (vfs_optionisset(vfsp, MNTOPT_XATTR, NULL))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1710
			vfsp->vfs_flag |= VFS_XATTR;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1711
		else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1712
			vfsp->vfs_flag &= ~VFS_XATTR;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1713
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1714
		if (vfs_optionisset(vfsp, MNTOPT_NOEXEC, NULL))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1715
			vfsp->vfs_flag |= VFS_NOEXEC;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1716
		else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1717
			vfsp->vfs_flag &= ~VFS_NOEXEC;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1718
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1719
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1720
		 * Now construct the output option string of options
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1721
		 * we recognized.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1722
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1723
		if (uap->flags & MS_OPTIONSTR) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1724
			vfs_list_read_lock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1725
			copyout_error = vfs_buildoptionstr(
3912
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3904
diff changeset
  1726
			    &vfsp->vfs_mntopts, inargs, optlen);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1727
			vfs_list_unlock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1728
			if (copyout_error == 0 &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1729
			    (uap->flags & MS_SYSSPACE) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1730
				copyout_error = copyoutstr(inargs, opts,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1731
				    optlen, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1732
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1733
		}
1488
196daa2cf3db PSARC/2006/034 fsstat
rsb
parents: 994
diff changeset
  1734
1520
2fb01d86c1c1 6391295 fop_create() panic when running svvs over ZFS
rsb
parents: 1488
diff changeset
  1735
		/*
2fb01d86c1c1 6391295 fop_create() panic when running svvs over ZFS
rsb
parents: 1488
diff changeset
  1736
		 * 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
  1737
		 * 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
  1738
		 * 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
  1739
		 * have the VFS_STATS flag set.
cd336ddf9a1c 6397933 fs node paniced while mounting global filesystem (/global/.devices/node@x)
rsb
parents: 1520
diff changeset
  1740
		 * 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
  1741
		 * 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
  1742
		 * 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
  1743
		 * 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
  1744
		 * 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
  1745
		 * properly initialized.
1520
2fb01d86c1c1 6391295 fop_create() panic when running svvs over ZFS
rsb
parents: 1488
diff changeset
  1746
		 */
1678
cd336ddf9a1c 6397933 fs node paniced while mounting global filesystem (/global/.devices/node@x)
rsb
parents: 1520
diff changeset
  1747
		if (!remount && (vswp->vsw_flag & VSW_STATS) && splice) {
1520
2fb01d86c1c1 6391295 fop_create() panic when running svvs over ZFS
rsb
parents: 1488
diff changeset
  1748
			initialize_vopstats(&vfsp->vfs_vopstats);
2fb01d86c1c1 6391295 fop_create() panic when running svvs over ZFS
rsb
parents: 1488
diff changeset
  1749
			/*
2fb01d86c1c1 6391295 fop_create() panic when running svvs over ZFS
rsb
parents: 1488
diff changeset
  1750
			 * 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
  1751
			 * 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
  1752
			 * in teardown_vopstats() so we can't have garbage.
2fb01d86c1c1 6391295 fop_create() panic when running svvs over ZFS
rsb
parents: 1488
diff changeset
  1753
			 */
2fb01d86c1c1 6391295 fop_create() panic when running svvs over ZFS
rsb
parents: 1488
diff changeset
  1754
			vfsp->vfs_vskap = NULL;
1488
196daa2cf3db PSARC/2006/034 fsstat
rsb
parents: 994
diff changeset
  1755
			vfsp->vfs_flag |= VFS_STATS;
1520
2fb01d86c1c1 6391295 fop_create() panic when running svvs over ZFS
rsb
parents: 1488
diff changeset
  1756
			vfsp->vfs_fstypevsp = get_fstype_vopstats(vfsp, vswp);
1488
196daa2cf3db PSARC/2006/034 fsstat
rsb
parents: 994
diff changeset
  1757
		}
196daa2cf3db PSARC/2006/034 fsstat
rsb
parents: 994
diff changeset
  1758
4321
a8930ec16e52 PSARC 2007/064 Unified POSIX and Windows Credentials for Solaris
casper
parents: 3957
diff changeset
  1759
		if (vswp->vsw_flag & VSW_XID)
a8930ec16e52 PSARC 2007/064 Unified POSIX and Windows Credentials for Solaris
casper
parents: 3957
diff changeset
  1760
			vfsp->vfs_flag |= VFS_XID;
a8930ec16e52 PSARC 2007/064 Unified POSIX and Windows Credentials for Solaris
casper
parents: 3957
diff changeset
  1761
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1762
		vfs_unlock(vfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1763
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1764
	mount_completed();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1765
	if (splice)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1766
		vn_vfsunlock(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1767
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1768
	if ((error == 0) && (copyout_error == 0)) {
1520
2fb01d86c1c1 6391295 fop_create() panic when running svvs over ZFS
rsb
parents: 1488
diff changeset
  1769
		if (!remount) {
2fb01d86c1c1 6391295 fop_create() panic when running svvs over ZFS
rsb
parents: 1488
diff changeset
  1770
			/*
2fb01d86c1c1 6391295 fop_create() panic when running svvs over ZFS
rsb
parents: 1488
diff changeset
  1771
			 * Don't call get_vskstat_anchor() while holding
2fb01d86c1c1 6391295 fop_create() panic when running svvs over ZFS
rsb
parents: 1488
diff changeset
  1772
			 * locks since it allocates memory and calls
2fb01d86c1c1 6391295 fop_create() panic when running svvs over ZFS
rsb
parents: 1488
diff changeset
  1773
			 * VFS_STATVFS().  For NFS, the latter can generate
2fb01d86c1c1 6391295 fop_create() panic when running svvs over ZFS
rsb
parents: 1488
diff changeset
  1774
			 * an over-the-wire call.
2fb01d86c1c1 6391295 fop_create() panic when running svvs over ZFS
rsb
parents: 1488
diff changeset
  1775
			 */
2fb01d86c1c1 6391295 fop_create() panic when running svvs over ZFS
rsb
parents: 1488
diff changeset
  1776
			vskap = get_vskstat_anchor(vfsp);
2fb01d86c1c1 6391295 fop_create() panic when running svvs over ZFS
rsb
parents: 1488
diff changeset
  1777
			/* 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
  1778
			if (vskap != NULL) {
2fb01d86c1c1 6391295 fop_create() panic when running svvs over ZFS
rsb
parents: 1488
diff changeset
  1779
				vfs_lock_wait(vfsp);
2fb01d86c1c1 6391295 fop_create() panic when running svvs over ZFS
rsb
parents: 1488
diff changeset
  1780
				if (vfsp->vfs_flag & VFS_STATS) {
2fb01d86c1c1 6391295 fop_create() panic when running svvs over ZFS
rsb
parents: 1488
diff changeset
  1781
					vfsp->vfs_vskap = vskap;
2fb01d86c1c1 6391295 fop_create() panic when running svvs over ZFS
rsb
parents: 1488
diff changeset
  1782
				}
2fb01d86c1c1 6391295 fop_create() panic when running svvs over ZFS
rsb
parents: 1488
diff changeset
  1783
				vfs_unlock(vfsp);
2fb01d86c1c1 6391295 fop_create() panic when running svvs over ZFS
rsb
parents: 1488
diff changeset
  1784
			}
2fb01d86c1c1 6391295 fop_create() panic when running svvs over ZFS
rsb
parents: 1488
diff changeset
  1785
		}
1488
196daa2cf3db PSARC/2006/034 fsstat
rsb
parents: 994
diff changeset
  1786
		/* Return vfsp to caller. */
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1787
		*vfspp = vfsp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1788
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1789
errout:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1790
	vfs_freeopttbl(&mnt_mntopts);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1791
	if (resource != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1792
		kmem_free(resource, strlen(resource) + 1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1793
	if (mountpt != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1794
		kmem_free(mountpt, strlen(mountpt) + 1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1795
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1796
	 * It is possible we errored prior to adding to mount in progress
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1797
	 * table. Must free vnode we acquired with successful lookupname.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1798
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1799
	if (addmip)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1800
		VN_RELE(bvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1801
	if (delmip)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1802
		vfs_delmip(vfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1803
	ASSERT(vswp != NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1804
	vfs_unrefvfssw(vswp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1805
	if (inargs != opts)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1806
		kmem_free(inargs, MAX_MNTOPT_STR);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1807
	if (copyout_error) {
6734
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  1808
		lofi_remove(vfsp);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1809
		VFS_RELE(vfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1810
		error = copyout_error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1811
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1812
	return (error);
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
12906
3ca11e9f39b7 6950914 remount can change mount point to "unspecified_mountpoint", causing panics
Robert Harris <Robert.Harris@Sun.COM>
parents: 12633
diff changeset
  1816
vfs_setpath(
3ca11e9f39b7 6950914 remount can change mount point to "unspecified_mountpoint", causing panics
Robert Harris <Robert.Harris@Sun.COM>
parents: 12633
diff changeset
  1817
    struct vfs *vfsp,		/* vfs being updated */
3ca11e9f39b7 6950914 remount can change mount point to "unspecified_mountpoint", causing panics
Robert Harris <Robert.Harris@Sun.COM>
parents: 12633
diff changeset
  1818
    refstr_t **refp,		/* Ref-count string to contain the new path */
3ca11e9f39b7 6950914 remount can change mount point to "unspecified_mountpoint", causing panics
Robert Harris <Robert.Harris@Sun.COM>
parents: 12633
diff changeset
  1819
    const char *newpath,	/* Path to add to refp (above) */
3ca11e9f39b7 6950914 remount can change mount point to "unspecified_mountpoint", causing panics
Robert Harris <Robert.Harris@Sun.COM>
parents: 12633
diff changeset
  1820
    uint32_t flag)		/* flag */
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1821
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1822
	size_t len;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1823
	refstr_t *ref;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1824
	zone_t *zone = curproc->p_zone;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1825
	char *sp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1826
	int have_list_lock = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1827
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1828
	ASSERT(!VFS_ON_LIST(vfsp) || vfs_lock_held(vfsp));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1829
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1830
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1831
	 * New path must be less than MAXPATHLEN because mntfs
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1832
	 * will only display up to MAXPATHLEN bytes. This is currently
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1833
	 * safe, because domount() uses pn_get(), and other callers
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1834
	 * similarly cap the size to fewer than MAXPATHLEN bytes.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1835
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1836
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1837
	ASSERT(strlen(newpath) < MAXPATHLEN);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1838
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1839
	/* mntfs requires consistency while vfs list lock is held */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1840
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1841
	if (VFS_ON_LIST(vfsp)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1842
		have_list_lock = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1843
		vfs_list_lock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1844
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1845
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1846
	if (*refp != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1847
		refstr_rele(*refp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1848
12906
3ca11e9f39b7 6950914 remount can change mount point to "unspecified_mountpoint", causing panics
Robert Harris <Robert.Harris@Sun.COM>
parents: 12633
diff changeset
  1849
	/*
3ca11e9f39b7 6950914 remount can change mount point to "unspecified_mountpoint", causing panics
Robert Harris <Robert.Harris@Sun.COM>
parents: 12633
diff changeset
  1850
	 * If we are in a non-global zone then we prefix the supplied path,
3ca11e9f39b7 6950914 remount can change mount point to "unspecified_mountpoint", causing panics
Robert Harris <Robert.Harris@Sun.COM>
parents: 12633
diff changeset
  1851
	 * newpath, with the zone's root path, with two exceptions. The first
3ca11e9f39b7 6950914 remount can change mount point to "unspecified_mountpoint", causing panics
Robert Harris <Robert.Harris@Sun.COM>
parents: 12633
diff changeset
  1852
	 * is where we have been explicitly directed to avoid doing so; this
3ca11e9f39b7 6950914 remount can change mount point to "unspecified_mountpoint", causing panics
Robert Harris <Robert.Harris@Sun.COM>
parents: 12633
diff changeset
  1853
	 * will be the case following a failed remount, where the path supplied
3ca11e9f39b7 6950914 remount can change mount point to "unspecified_mountpoint", causing panics
Robert Harris <Robert.Harris@Sun.COM>
parents: 12633
diff changeset
  1854
	 * will be a saved version which must now be restored. The second
3ca11e9f39b7 6950914 remount can change mount point to "unspecified_mountpoint", causing panics
Robert Harris <Robert.Harris@Sun.COM>
parents: 12633
diff changeset
  1855
	 * exception is where newpath is not a pathname but a descriptive name,
3ca11e9f39b7 6950914 remount can change mount point to "unspecified_mountpoint", causing panics
Robert Harris <Robert.Harris@Sun.COM>
parents: 12633
diff changeset
  1856
	 * e.g. "procfs".
3ca11e9f39b7 6950914 remount can change mount point to "unspecified_mountpoint", causing panics
Robert Harris <Robert.Harris@Sun.COM>
parents: 12633
diff changeset
  1857
	 */
3ca11e9f39b7 6950914 remount can change mount point to "unspecified_mountpoint", causing panics
Robert Harris <Robert.Harris@Sun.COM>
parents: 12633
diff changeset
  1858
	if (zone == global_zone || (flag & VFSSP_VERBATIM) || *newpath != '/') {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1859
		ref = refstr_alloc(newpath);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1860
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1861
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1862
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1863
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1864
	 * Truncate the trailing '/' in the zoneroot, and merge
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1865
	 * in the zone's rootpath with the "newpath" (resource
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1866
	 * or mountpoint) passed in.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1867
	 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1868
	 * The size of the required buffer is thus the size of
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1869
	 * the buffer required for the passed-in newpath
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1870
	 * (strlen(newpath) + 1), plus the size of the buffer
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1871
	 * required to hold zone_rootpath (zone_rootpathlen)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1872
	 * minus one for one of the now-superfluous NUL
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1873
	 * terminations, minus one for the trailing '/'.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1874
	 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1875
	 * That gives us:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1876
	 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1877
	 * (strlen(newpath) + 1) + zone_rootpathlen - 1 - 1
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1878
	 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1879
	 * Which is what we have below.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1880
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1881
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1882
	len = strlen(newpath) + zone->zone_rootpathlen - 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1883
	sp = kmem_alloc(len, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1884
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1885
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1886
	 * Copy everything including the trailing slash, which
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1887
	 * we then overwrite with the NUL character.
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
	(void) strcpy(sp, zone->zone_rootpath);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1891
	sp[zone->zone_rootpathlen - 2] = '\0';
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1892
	(void) strcat(sp, newpath);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1893
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1894
	ref = refstr_alloc(sp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1895
	kmem_free(sp, len);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1896
out:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1897
	*refp = ref;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1898
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1899
	if (have_list_lock) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1900
		vfs_mnttab_modtimeupd();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1901
		vfs_list_unlock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1902
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1903
}
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
 * Record a mounted resource name in a vfs structure.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1907
 * If vfsp is already mounted, caller must hold the vfs lock.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1908
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1909
void
12906
3ca11e9f39b7 6950914 remount can change mount point to "unspecified_mountpoint", causing panics
Robert Harris <Robert.Harris@Sun.COM>
parents: 12633
diff changeset
  1910
vfs_setresource(struct vfs *vfsp, const char *resource, uint32_t flag)
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1911
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1912
	if (resource == NULL || resource[0] == '\0')
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1913
		resource = VFS_NORESOURCE;
12906
3ca11e9f39b7 6950914 remount can change mount point to "unspecified_mountpoint", causing panics
Robert Harris <Robert.Harris@Sun.COM>
parents: 12633
diff changeset
  1914
	vfs_setpath(vfsp, &vfsp->vfs_resource, resource, flag);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1915
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1916
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1917
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1918
 * Record a mount point name in a vfs structure.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1919
 * If vfsp is already mounted, caller must hold the vfs lock.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1920
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1921
void
12906
3ca11e9f39b7 6950914 remount can change mount point to "unspecified_mountpoint", causing panics
Robert Harris <Robert.Harris@Sun.COM>
parents: 12633
diff changeset
  1922
vfs_setmntpoint(struct vfs *vfsp, const char *mntpt, uint32_t flag)
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1923
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1924
	if (mntpt == NULL || mntpt[0] == '\0')
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1925
		mntpt = VFS_NOMNTPT;
12906
3ca11e9f39b7 6950914 remount can change mount point to "unspecified_mountpoint", causing panics
Robert Harris <Robert.Harris@Sun.COM>
parents: 12633
diff changeset
  1926
	vfs_setpath(vfsp, &vfsp->vfs_mntpt, mntpt, flag);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1927
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1928
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1929
/* Returns the vfs_resource. Caller must call refstr_rele() when finished. */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1930
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1931
refstr_t *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1932
vfs_getresource(const struct vfs *vfsp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1933
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1934
	refstr_t *resource;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1935
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1936
	vfs_list_read_lock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1937
	resource = vfsp->vfs_resource;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1938
	refstr_hold(resource);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1939
	vfs_list_unlock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1940
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1941
	return (resource);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1942
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1943
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1944
/* Returns the vfs_mntpt. Caller must call refstr_rele() when finished. */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1945
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1946
refstr_t *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1947
vfs_getmntpoint(const struct vfs *vfsp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1948
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1949
	refstr_t *mntpt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1950
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1951
	vfs_list_read_lock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1952
	mntpt = vfsp->vfs_mntpt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1953
	refstr_hold(mntpt);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1954
	vfs_list_unlock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1955
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1956
	return (mntpt);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1957
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1958
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1959
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1960
 * Create an empty options table with enough empty slots to hold all
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1961
 * The options in the options string passed as an argument.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1962
 * Potentially prepend another options table.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1963
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1964
 * Note: caller is responsible for locking the vfs list, if needed,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1965
 *       to protect mops.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1966
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1967
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1968
vfs_createopttbl_extend(mntopts_t *mops, const char *opts,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1969
    const mntopts_t *mtmpl)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1970
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1971
	const char *s = opts;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1972
	uint_t count;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1973
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1974
	if (opts == NULL || *opts == '\0') {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1975
		count = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1976
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1977
		count = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1978
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1979
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1980
		 * Count number of options in the string
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1981
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1982
		for (s = strchr(s, ','); s != NULL; s = strchr(s, ',')) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1983
			count++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1984
			s++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1985
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1986
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1987
	vfs_copyopttbl_extend(mtmpl, mops, count);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1988
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1989
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1990
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1991
 * Create an empty options table with enough empty slots to hold all
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1992
 * The options in the options string passed as an argument.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1993
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1994
 * This function is *not* for general use by filesystems.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1995
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1996
 * Note: caller is responsible for locking the vfs list, if needed,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1997
 *       to protect mops.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1998
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1999
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2000
vfs_createopttbl(mntopts_t *mops, const char *opts)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2001
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2002
	vfs_createopttbl_extend(mops, opts, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2003
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2004
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2005
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2006
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2007
 * Swap two mount options tables
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2008
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2009
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2010
vfs_swapopttbl_nolock(mntopts_t *optbl1, mntopts_t *optbl2)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2011
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2012
	uint_t tmpcnt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2013
	mntopt_t *tmplist;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2014
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2015
	tmpcnt = optbl2->mo_count;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2016
	tmplist = optbl2->mo_list;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2017
	optbl2->mo_count = optbl1->mo_count;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2018
	optbl2->mo_list = optbl1->mo_list;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2019
	optbl1->mo_count = tmpcnt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2020
	optbl1->mo_list = tmplist;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2021
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2022
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2023
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2024
vfs_swapopttbl(mntopts_t *optbl1, mntopts_t *optbl2)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2025
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2026
	vfs_list_lock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2027
	vfs_swapopttbl_nolock(optbl1, optbl2);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2028
	vfs_mnttab_modtimeupd();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2029
	vfs_list_unlock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2030
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2031
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2032
static char **
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2033
vfs_copycancelopt_extend(char **const moc, int extend)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2034
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2035
	int i = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2036
	int j;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2037
	char **result;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2038
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2039
	if (moc != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2040
		for (; moc[i] != NULL; i++)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2041
			/* count number of options to cancel */;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2042
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2043
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2044
	if (i + extend == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2045
		return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2046
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2047
	result = kmem_alloc((i + extend + 1) * sizeof (char *), KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2048
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2049
	for (j = 0; j < i; j++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2050
		result[j] = kmem_alloc(strlen(moc[j]) + 1, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2051
		(void) strcpy(result[j], moc[j]);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2052
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2053
	for (; j <= i + extend; j++)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2054
		result[j] = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2055
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2056
	return (result);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2057
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2058
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2059
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2060
vfs_copyopt(const mntopt_t *s, mntopt_t *d)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2061
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2062
	char *sp, *dp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2063
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2064
	d->mo_flags = s->mo_flags;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2065
	d->mo_data = s->mo_data;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2066
	sp = s->mo_name;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2067
	if (sp != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2068
		dp = kmem_alloc(strlen(sp) + 1, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2069
		(void) strcpy(dp, sp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2070
		d->mo_name = dp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2071
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2072
		d->mo_name = NULL; /* should never happen */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2073
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2074
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2075
	d->mo_cancel = vfs_copycancelopt_extend(s->mo_cancel, 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2076
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2077
	sp = s->mo_arg;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2078
	if (sp != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2079
		dp = kmem_alloc(strlen(sp) + 1, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2080
		(void) strcpy(dp, sp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2081
		d->mo_arg = dp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2082
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2083
		d->mo_arg = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2084
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2085
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2086
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2087
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2088
 * Copy a mount options table, possibly allocating some spare
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2089
 * slots at the end.  It is permissible to copy_extend the NULL table.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2090
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2091
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2092
vfs_copyopttbl_extend(const mntopts_t *smo, mntopts_t *dmo, int extra)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2093
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2094
	uint_t i, count;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2095
	mntopt_t *motbl;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2096
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2097
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2098
	 * Clear out any existing stuff in the options table being initialized
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2099
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2100
	vfs_freeopttbl(dmo);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2101
	count = (smo == NULL) ? 0 : smo->mo_count;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2102
	if ((count + extra) == 0)	/* nothing to do */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2103
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2104
	dmo->mo_count = count + extra;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2105
	motbl = kmem_zalloc((count + extra) * sizeof (mntopt_t), KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2106
	dmo->mo_list = motbl;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2107
	for (i = 0; i < count; i++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2108
		vfs_copyopt(&smo->mo_list[i], &motbl[i]);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2109
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2110
	for (i = count; i < count + extra; i++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2111
		motbl[i].mo_flags = MO_EMPTY;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2112
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2113
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2114
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2115
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2116
 * Copy a mount options table.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2117
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2118
 * This function is *not* for general use by filesystems.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2119
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2120
 * Note: caller is responsible for locking the vfs list, if needed,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2121
 *       to protect smo and dmo.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2122
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2123
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2124
vfs_copyopttbl(const mntopts_t *smo, mntopts_t *dmo)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2125
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2126
	vfs_copyopttbl_extend(smo, dmo, 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2127
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2128
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2129
static char **
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2130
vfs_mergecancelopts(const mntopt_t *mop1, const mntopt_t *mop2)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2131
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2132
	int c1 = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2133
	int c2 = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2134
	char **result;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2135
	char **sp1, **sp2, **dp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2136
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2137
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2138
	 * First we count both lists of cancel options.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2139
	 * If either is NULL or has no elements, we return a copy of
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2140
	 * the other.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2141
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2142
	if (mop1->mo_cancel != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2143
		for (; mop1->mo_cancel[c1] != NULL; c1++)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2144
			/* count cancel options in mop1 */;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2145
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2146
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2147
	if (c1 == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2148
		return (vfs_copycancelopt_extend(mop2->mo_cancel, 0));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2149
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2150
	if (mop2->mo_cancel != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2151
		for (; mop2->mo_cancel[c2] != NULL; c2++)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2152
			/* count cancel options in mop2 */;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2153
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2154
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2155
	result = vfs_copycancelopt_extend(mop1->mo_cancel, c2);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2156
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2157
	if (c2 == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2158
		return (result);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2159
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2160
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2161
	 * When we get here, we've got two sets of cancel options;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2162
	 * we need to merge the two sets.  We know that the result
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2163
	 * array has "c1+c2+1" entries and in the end we might shrink
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2164
	 * it.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2165
	 * Result now has a copy of the c1 entries from mop1; we'll
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2166
	 * now lookup all the entries of mop2 in mop1 and copy it if
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2167
	 * it is unique.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2168
	 * This operation is O(n^2) but it's only called once per
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2169
	 * filesystem per duplicate option.  This is a situation
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2170
	 * which doesn't arise with the filesystems in ON and
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2171
	 * n is generally 1.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2172
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2173
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2174
	dp = &result[c1];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2175
	for (sp2 = mop2->mo_cancel; *sp2 != NULL; sp2++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2176
		for (sp1 = mop1->mo_cancel; *sp1 != NULL; sp1++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2177
			if (strcmp(*sp1, *sp2) == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2178
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2179
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2180
		if (*sp1 == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2181
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2182
			 * Option *sp2 not found in mop1, so copy it.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2183
			 * The calls to vfs_copycancelopt_extend()
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2184
			 * guarantee that there's enough room.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2185
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2186
			*dp = kmem_alloc(strlen(*sp2) + 1, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2187
			(void) strcpy(*dp++, *sp2);
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
	if (dp != &result[c1+c2]) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2191
		size_t bytes = (dp - result + 1) * sizeof (char *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2192
		char **nres = kmem_alloc(bytes, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2193
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2194
		bcopy(result, nres, bytes);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2195
		kmem_free(result, (c1 + c2 + 1) * sizeof (char *));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2196
		result = nres;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2197
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2198
	return (result);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2199
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2200
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2201
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2202
 * Merge two mount option tables (outer and inner) into one.  This is very
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2203
 * similar to "merging" global variables and automatic variables in C.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2204
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2205
 * This isn't (and doesn't have to be) fast.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2206
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2207
 * This function is *not* for general use by filesystems.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2208
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2209
 * Note: caller is responsible for locking the vfs list, if needed,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2210
 *       to protect omo, imo & dmo.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2211
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2212
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2213
vfs_mergeopttbl(const mntopts_t *omo, const mntopts_t *imo, mntopts_t *dmo)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2214
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2215
	uint_t i, count;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2216
	mntopt_t *mop, *motbl;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2217
	uint_t freeidx;
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
	 * First determine how much space we need to allocate.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2221
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2222
	count = omo->mo_count;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2223
	for (i = 0; i < imo->mo_count; i++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2224
		if (imo->mo_list[i].mo_flags & MO_EMPTY)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2225
			continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2226
		if (vfs_hasopt(omo, imo->mo_list[i].mo_name) == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2227
			count++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2228
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2229
	ASSERT(count >= omo->mo_count &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2230
	    count <= omo->mo_count + imo->mo_count);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2231
	motbl = kmem_alloc(count * sizeof (mntopt_t), KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2232
	for (i = 0; i < omo->mo_count; i++)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2233
		vfs_copyopt(&omo->mo_list[i], &motbl[i]);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2234
	freeidx = omo->mo_count;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2235
	for (i = 0; i < imo->mo_count; i++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2236
		if (imo->mo_list[i].mo_flags & MO_EMPTY)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2237
			continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2238
		if ((mop = vfs_hasopt(omo, imo->mo_list[i].mo_name)) != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2239
			char **newcanp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2240
			uint_t index = mop - omo->mo_list;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2241
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2242
			newcanp = vfs_mergecancelopts(mop, &motbl[index]);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2243
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2244
			vfs_freeopt(&motbl[index]);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2245
			vfs_copyopt(&imo->mo_list[i], &motbl[index]);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2246
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2247
			vfs_freecancelopt(motbl[index].mo_cancel);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2248
			motbl[index].mo_cancel = newcanp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2249
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2250
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2251
			 * If it's a new option, just copy it over to the first
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2252
			 * free location.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2253
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2254
			vfs_copyopt(&imo->mo_list[i], &motbl[freeidx++]);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2255
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2256
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2257
	dmo->mo_count = count;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2258
	dmo->mo_list = motbl;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2259
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2260
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2261
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2262
 * Functions to set and clear mount options in a mount options table.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2263
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2264
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2265
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2266
 * Clear a mount option, if it exists.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2267
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2268
 * The update_mnttab arg indicates whether mops is part of a vfs that is on
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2269
 * the vfs list.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2270
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2271
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2272
vfs_clearmntopt_nolock(mntopts_t *mops, const char *opt, int update_mnttab)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2273
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2274
	struct mntopt *mop;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2275
	uint_t i, count;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2276
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2277
	ASSERT(!update_mnttab || RW_WRITE_HELD(&vfslist));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2278
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2279
	count = mops->mo_count;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2280
	for (i = 0; i < count; i++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2281
		mop = &mops->mo_list[i];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2282
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2283
		if (mop->mo_flags & MO_EMPTY)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2284
			continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2285
		if (strcmp(opt, mop->mo_name))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2286
			continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2287
		mop->mo_flags &= ~MO_SET;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2288
		if (mop->mo_arg != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2289
			kmem_free(mop->mo_arg, strlen(mop->mo_arg) + 1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2290
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2291
		mop->mo_arg = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2292
		if (update_mnttab)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2293
			vfs_mnttab_modtimeupd();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2294
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2295
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2296
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2297
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2298
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2299
vfs_clearmntopt(struct vfs *vfsp, const char *opt)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2300
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2301
	int gotlock = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2302
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2303
	if (VFS_ON_LIST(vfsp)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2304
		gotlock = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2305
		vfs_list_lock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2306
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2307
	vfs_clearmntopt_nolock(&vfsp->vfs_mntopts, opt, gotlock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2308
	if (gotlock)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2309
		vfs_list_unlock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2310
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2311
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2312
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2313
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2314
 * 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
  2315
 * ignored.  If the option has MO_IGNORE set, it is still set unless the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2316
 * VFS_NOFORCEOPT bit is set in the flags.  Also, VFS_DISPLAY/VFS_NODISPLAY flag
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2317
 * bits can be used to toggle the MO_NODISPLAY bit for the option.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2318
 * If the VFS_CREATEOPT flag bit is set then the first option slot with
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2319
 * MO_EMPTY set is created as the option passed in.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2320
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2321
 * The update_mnttab arg indicates whether mops is part of a vfs that is on
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2322
 * the vfs list.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2323
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2324
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2325
vfs_setmntopt_nolock(mntopts_t *mops, const char *opt,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2326
    const char *arg, int flags, int update_mnttab)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2327
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2328
	mntopt_t *mop;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2329
	uint_t i, count;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2330
	char *sp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2331
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2332
	ASSERT(!update_mnttab || RW_WRITE_HELD(&vfslist));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2333
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2334
	if (flags & VFS_CREATEOPT) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2335
		if (vfs_hasopt(mops, opt) != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2336
			flags &= ~VFS_CREATEOPT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2337
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2338
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2339
	count = mops->mo_count;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2340
	for (i = 0; i < count; i++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2341
		mop = &mops->mo_list[i];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2342
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2343
		if (mop->mo_flags & MO_EMPTY) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2344
			if ((flags & VFS_CREATEOPT) == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2345
				continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2346
			sp = kmem_alloc(strlen(opt) + 1, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2347
			(void) strcpy(sp, opt);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2348
			mop->mo_name = sp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2349
			if (arg != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2350
				mop->mo_flags = MO_HASVALUE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2351
			else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2352
				mop->mo_flags = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2353
		} else if (strcmp(opt, mop->mo_name)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2354
			continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2355
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2356
		if ((mop->mo_flags & MO_IGNORE) && (flags & VFS_NOFORCEOPT))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2357
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2358
		if (arg != NULL && (mop->mo_flags & MO_HASVALUE) != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2359
			sp = kmem_alloc(strlen(arg) + 1, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2360
			(void) strcpy(sp, arg);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2361
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2362
			sp = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2363
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2364
		if (mop->mo_arg != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2365
			kmem_free(mop->mo_arg, strlen(mop->mo_arg) + 1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2366
		mop->mo_arg = sp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2367
		if (flags & VFS_DISPLAY)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2368
			mop->mo_flags &= ~MO_NODISPLAY;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2369
		if (flags & VFS_NODISPLAY)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2370
			mop->mo_flags |= MO_NODISPLAY;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2371
		mop->mo_flags |= MO_SET;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2372
		if (mop->mo_cancel != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2373
			char **cp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2374
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2375
			for (cp = mop->mo_cancel; *cp != NULL; cp++)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2376
				vfs_clearmntopt_nolock(mops, *cp, 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2377
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2378
		if (update_mnttab)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2379
			vfs_mnttab_modtimeupd();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2380
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2381
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2382
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2383
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2384
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2385
vfs_setmntopt(struct vfs *vfsp, const char *opt, const char *arg, int flags)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2386
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2387
	int gotlock = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2388
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2389
	if (VFS_ON_LIST(vfsp)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2390
		gotlock = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2391
		vfs_list_lock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2392
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2393
	vfs_setmntopt_nolock(&vfsp->vfs_mntopts, opt, arg, flags, gotlock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2394
	if (gotlock)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2395
		vfs_list_unlock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2396
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2397
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2398
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2399
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2400
 * Add a "tag" option to a mounted file system's options list.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2401
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2402
 * Note: caller is responsible for locking the vfs list, if needed,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2403
 *       to protect mops.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2404
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2405
static mntopt_t *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2406
vfs_addtag(mntopts_t *mops, const char *tag)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2407
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2408
	uint_t count;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2409
	mntopt_t *mop, *motbl;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2410
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2411
	count = mops->mo_count + 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2412
	motbl = kmem_zalloc(count * sizeof (mntopt_t), KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2413
	if (mops->mo_count) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2414
		size_t len = (count - 1) * sizeof (mntopt_t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2415
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2416
		bcopy(mops->mo_list, motbl, len);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2417
		kmem_free(mops->mo_list, len);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2418
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2419
	mops->mo_count = count;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2420
	mops->mo_list = motbl;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2421
	mop = &motbl[count - 1];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2422
	mop->mo_flags = MO_TAG;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2423
	mop->mo_name = kmem_alloc(strlen(tag) + 1, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2424
	(void) strcpy(mop->mo_name, tag);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2425
	return (mop);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2426
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2427
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2428
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2429
 * Allow users to set arbitrary "tags" in a vfs's mount options.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2430
 * Broader use within the kernel is discouraged.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2431
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2432
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2433
vfs_settag(uint_t major, uint_t minor, const char *mntpt, const char *tag,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2434
    cred_t *cr)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2435
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2436
	vfs_t *vfsp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2437
	mntopts_t *mops;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2438
	mntopt_t *mop;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2439
	int found = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2440
	dev_t dev = makedevice(major, minor);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2441
	int err = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2442
	char *buf = kmem_alloc(MAX_MNTOPT_STR, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2443
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2444
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2445
	 * Find the desired mounted file system
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2446
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2447
	vfs_list_lock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2448
	vfsp = rootvfs;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2449
	do {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2450
		if (vfsp->vfs_dev == dev &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2451
		    strcmp(mntpt, refstr_value(vfsp->vfs_mntpt)) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2452
			found = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2453
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2454
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2455
		vfsp = vfsp->vfs_next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2456
	} while (vfsp != rootvfs);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2457
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2458
	if (!found) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2459
		err = EINVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2460
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2461
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2462
	err = secpolicy_fs_config(cr, vfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2463
	if (err != 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2464
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2465
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2466
	mops = &vfsp->vfs_mntopts;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2467
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2468
	 * Add tag if it doesn't already exist
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2469
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2470
	if ((mop = vfs_hasopt(mops, tag)) == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2471
		int len;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2472
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2473
		(void) vfs_buildoptionstr(mops, buf, MAX_MNTOPT_STR);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2474
		len = strlen(buf);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2475
		if (len + strlen(tag) + 2 > MAX_MNTOPT_STR) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2476
			err = ENAMETOOLONG;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2477
			goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2478
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2479
		mop = vfs_addtag(mops, tag);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2480
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2481
	if ((mop->mo_flags & MO_TAG) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2482
		err = EINVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2483
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2484
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2485
	vfs_setmntopt_nolock(mops, tag, NULL, 0, 1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2486
out:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2487
	vfs_list_unlock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2488
	kmem_free(buf, MAX_MNTOPT_STR);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2489
	return (err);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2490
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2491
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2492
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2493
 * Allow users to remove arbitrary "tags" in a vfs's mount options.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2494
 * Broader use within the kernel is discouraged.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2495
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2496
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2497
vfs_clrtag(uint_t major, uint_t minor, const char *mntpt, const char *tag,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2498
    cred_t *cr)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2499
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2500
	vfs_t *vfsp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2501
	mntopt_t *mop;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2502
	int found = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2503
	dev_t dev = makedevice(major, minor);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2504
	int err = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2505
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2506
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2507
	 * Find the desired mounted file system
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2508
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2509
	vfs_list_lock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2510
	vfsp = rootvfs;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2511
	do {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2512
		if (vfsp->vfs_dev == dev &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2513
		    strcmp(mntpt, refstr_value(vfsp->vfs_mntpt)) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2514
			found = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2515
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2516
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2517
		vfsp = vfsp->vfs_next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2518
	} while (vfsp != rootvfs);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2519
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2520
	if (!found) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2521
		err = EINVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2522
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2523
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2524
	err = secpolicy_fs_config(cr, vfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2525
	if (err != 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2526
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2527
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2528
	if ((mop = vfs_hasopt(&vfsp->vfs_mntopts, tag)) == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2529
		err = EINVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2530
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2531
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2532
	if ((mop->mo_flags & MO_TAG) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2533
		err = EINVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2534
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2535
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2536
	vfs_clearmntopt_nolock(&vfsp->vfs_mntopts, tag, 1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2537
out:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2538
	vfs_list_unlock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2539
	return (err);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2540
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2541
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2542
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2543
 * Function to parse an option string and fill in a mount options table.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2544
 * Unknown options are silently ignored.  The input option string is modified
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2545
 * by replacing separators with nulls.  If the create flag is set, options
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2546
 * not found in the table are just added on the fly.  The table must have
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2547
 * an option slot marked MO_EMPTY to add an option on the fly.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2548
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2549
 * This function is *not* for general use by filesystems.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2550
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2551
 * Note: caller is responsible for locking the vfs list, if needed,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2552
 *       to protect mops..
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2553
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2554
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2555
vfs_parsemntopts(mntopts_t *mops, char *osp, int create)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2556
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2557
	char *s = osp, *p, *nextop, *valp, *cp, *ep;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2558
	int setflg = VFS_NOFORCEOPT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2559
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2560
	if (osp == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2561
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2562
	while (*s != '\0') {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2563
		p = strchr(s, ',');	/* find next option */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2564
		if (p == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2565
			cp = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2566
			p = s + strlen(s);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2567
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2568
			cp = p;		/* save location of comma */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2569
			*p++ = '\0';	/* mark end and point to next option */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2570
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2571
		nextop = p;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2572
		p = strchr(s, '=');	/* look for value */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2573
		if (p == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2574
			valp = NULL;	/* no value supplied */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2575
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2576
			ep = p;		/* save location of equals */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2577
			*p++ = '\0';	/* end option and point to value */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2578
			valp = p;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2579
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2580
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2581
		 * set option into options table
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2582
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2583
		if (create)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2584
			setflg |= VFS_CREATEOPT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2585
		vfs_setmntopt_nolock(mops, s, valp, setflg, 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2586
		if (cp != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2587
			*cp = ',';	/* restore the comma */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2588
		if (valp != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2589
			*ep = '=';	/* restore the equals */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2590
		s = nextop;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2591
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2592
}
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
 * Function to inquire if an option exists in a mount options table.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2596
 * Returns a pointer to the option if it exists, else NULL.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2597
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2598
 * This function is *not* for general use by filesystems.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2599
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2600
 * Note: caller is responsible for locking the vfs list, if needed,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2601
 *       to protect mops.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2602
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2603
struct mntopt *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2604
vfs_hasopt(const mntopts_t *mops, const char *opt)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2605
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2606
	struct mntopt *mop;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2607
	uint_t i, count;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2608
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2609
	count = mops->mo_count;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2610
	for (i = 0; i < count; i++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2611
		mop = &mops->mo_list[i];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2612
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2613
		if (mop->mo_flags & MO_EMPTY)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2614
			continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2615
		if (strcmp(opt, mop->mo_name) == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2616
			return (mop);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2617
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2618
	return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2619
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2620
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2621
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2622
 * Function to inquire if an option is set in a mount options table.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2623
 * Returns non-zero if set and fills in the arg pointer with a pointer to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2624
 * the argument string or NULL if there is no argument string.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2625
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2626
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2627
vfs_optionisset_nolock(const mntopts_t *mops, const char *opt, char **argp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2628
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2629
	struct mntopt *mop;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2630
	uint_t i, count;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2631
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2632
	count = mops->mo_count;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2633
	for (i = 0; i < count; i++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2634
		mop = &mops->mo_list[i];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2635
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2636
		if (mop->mo_flags & MO_EMPTY)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2637
			continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2638
		if (strcmp(opt, mop->mo_name))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2639
			continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2640
		if ((mop->mo_flags & MO_SET) == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2641
			return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2642
		if (argp != NULL && (mop->mo_flags & MO_HASVALUE) != 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2643
			*argp = mop->mo_arg;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2644
		return (1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2645
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2646
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2647
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2648
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2649
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2650
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2651
vfs_optionisset(const struct vfs *vfsp, const char *opt, char **argp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2652
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2653
	int ret;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2654
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2655
	vfs_list_read_lock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2656
	ret = vfs_optionisset_nolock(&vfsp->vfs_mntopts, opt, argp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2657
	vfs_list_unlock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2658
	return (ret);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2659
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2660
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2661
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2662
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2663
 * Construct a comma separated string of the options set in the given
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2664
 * mount table, return the string in the given buffer.  Return non-zero if
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2665
 * the buffer would overflow.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2666
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2667
 * This function is *not* for general use by filesystems.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2668
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2669
 * Note: caller is responsible for locking the vfs list, if needed,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2670
 *       to protect mp.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2671
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2672
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2673
vfs_buildoptionstr(const mntopts_t *mp, char *buf, int len)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2674
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2675
	char *cp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2676
	uint_t i;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2677
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2678
	buf[0] = '\0';
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2679
	cp = buf;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2680
	for (i = 0; i < mp->mo_count; i++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2681
		struct mntopt *mop;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2682
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2683
		mop = &mp->mo_list[i];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2684
		if (mop->mo_flags & MO_SET) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2685
			int optlen, comma = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2686
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2687
			if (buf[0] != '\0')
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2688
				comma = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2689
			optlen = strlen(mop->mo_name);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2690
			if (strlen(buf) + comma + optlen + 1 > len)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2691
				goto err;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2692
			if (comma)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2693
				*cp++ = ',';
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2694
			(void) strcpy(cp, mop->mo_name);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2695
			cp += optlen;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2696
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2697
			 * Append option value if there is one
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2698
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2699
			if (mop->mo_arg != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2700
				int arglen;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2701
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2702
				arglen = strlen(mop->mo_arg);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2703
				if (strlen(buf) + arglen + 2 > len)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2704
					goto err;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2705
				*cp++ = '=';
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2706
				(void) strcpy(cp, mop->mo_arg);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2707
				cp += arglen;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2708
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2709
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2710
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2711
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2712
err:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2713
	return (EOVERFLOW);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2714
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2715
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2716
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2717
vfs_freecancelopt(char **moc)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2718
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2719
	if (moc != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2720
		int ccnt = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2721
		char **cp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2722
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2723
		for (cp = moc; *cp != NULL; cp++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2724
			kmem_free(*cp, strlen(*cp) + 1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2725
			ccnt++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2726
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2727
		kmem_free(moc, (ccnt + 1) * sizeof (char *));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2728
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2729
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2730
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2731
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2732
vfs_freeopt(mntopt_t *mop)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2733
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2734
	if (mop->mo_name != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2735
		kmem_free(mop->mo_name, strlen(mop->mo_name) + 1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2736
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2737
	vfs_freecancelopt(mop->mo_cancel);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2738
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2739
	if (mop->mo_arg != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2740
		kmem_free(mop->mo_arg, strlen(mop->mo_arg) + 1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2741
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2742
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2743
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2744
 * Free a mount options table
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2745
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2746
 * This function is *not* for general use by filesystems.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2747
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2748
 * Note: caller is responsible for locking the vfs list, if needed,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2749
 *       to protect mp.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2750
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2751
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2752
vfs_freeopttbl(mntopts_t *mp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2753
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2754
	uint_t i, count;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2755
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2756
	count = mp->mo_count;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2757
	for (i = 0; i < count; i++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2758
		vfs_freeopt(&mp->mo_list[i]);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2759
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2760
	if (count) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2761
		kmem_free(mp->mo_list, sizeof (mntopt_t) * count);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2762
		mp->mo_count = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2763
		mp->mo_list = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2764
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2765
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2766
4863
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2767
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2768
/* ARGSUSED */
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2769
static int
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2770
vfs_mntdummyread(vnode_t *vp, uio_t *uio, int ioflag, cred_t *cred,
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2771
	caller_context_t *ct)
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2772
{
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2773
	return (0);
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2774
}
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2775
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2776
/* ARGSUSED */
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2777
static int
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2778
vfs_mntdummywrite(vnode_t *vp, uio_t *uio, int ioflag, cred_t *cred,
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2779
	caller_context_t *ct)
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2780
{
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2781
	return (0);
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2782
}
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2783
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2784
/*
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2785
 * The dummy vnode is currently used only by file events notification
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2786
 * module which is just interested in the timestamps.
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2787
 */
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2788
/* ARGSUSED */
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2789
static int
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  2790
vfs_mntdummygetattr(vnode_t *vp, vattr_t *vap, int flags, cred_t *cr,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  2791
    caller_context_t *ct)
4863
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2792
{
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2793
	bzero(vap, sizeof (vattr_t));
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2794
	vap->va_type = VREG;
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2795
	vap->va_nlink = 1;
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2796
	vap->va_ctime = vfs_mnttab_ctime;
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2797
	/*
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2798
	 * it is ok to just copy mtime as the time will be monotonically
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2799
	 * increasing.
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2800
	 */
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2801
	vap->va_mtime = vfs_mnttab_mtime;
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2802
	vap->va_atime = vap->va_mtime;
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2803
	return (0);
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2804
}
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2805
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2806
static void
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2807
vfs_mnttabvp_setup(void)
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2808
{
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2809
	vnode_t *tvp;
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2810
	vnodeops_t *vfs_mntdummyvnops;
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2811
	const fs_operation_def_t mnt_dummyvnodeops_template[] = {
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2812
		VOPNAME_READ, 		{ .vop_read = vfs_mntdummyread },
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2813
		VOPNAME_WRITE, 		{ .vop_write = vfs_mntdummywrite },
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2814
		VOPNAME_GETATTR,	{ .vop_getattr = vfs_mntdummygetattr },
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2815
		VOPNAME_VNEVENT,	{ .vop_vnevent = fs_vnevent_support },
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2816
		NULL,			NULL
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2817
	};
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2818
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2819
	if (vn_make_ops("mnttab", mnt_dummyvnodeops_template,
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2820
	    &vfs_mntdummyvnops) != 0) {
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2821
		cmn_err(CE_WARN, "vfs_mnttabvp_setup: vn_make_ops failed");
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2822
		/* Shouldn't happen, but not bad enough to panic */
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2823
		return;
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2824
	}
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2825
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2826
	/*
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2827
	 * A global dummy vnode is allocated to represent mntfs files.
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2828
	 * The mntfs file (/etc/mnttab) can be monitored for file events
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2829
	 * and receive an event when mnttab changes. Dummy VOP calls
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2830
	 * will be made on this vnode. The file events notification module
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2831
	 * intercepts this vnode and delivers relevant events.
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2832
	 */
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2833
	tvp = vn_alloc(KM_SLEEP);
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2834
	tvp->v_flag = VNOMOUNT|VNOMAP|VNOSWAP|VNOCACHE;
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2835
	vn_setops(tvp, vfs_mntdummyvnops);
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2836
	tvp->v_type = VREG;
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2837
	/*
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2838
	 * The mnt dummy ops do not reference v_data.
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2839
	 * No other module intercepting this vnode should either.
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2840
	 * Just set it to point to itself.
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2841
	 */
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2842
	tvp->v_data = (caddr_t)tvp;
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2843
	tvp->v_vfsp = rootvfs;
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2844
	vfs_mntdummyvp = tvp;
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2845
}
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2846
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2847
/*
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2848
 * performs fake read/write ops
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2849
 */
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2850
static void
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2851
vfs_mnttab_rwop(int rw)
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2852
{
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2853
	struct uio	uio;
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2854
	struct iovec	iov;
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2855
	char	buf[1];
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2856
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2857
	if (vfs_mntdummyvp == NULL)
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2858
		return;
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2859
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2860
	bzero(&uio, sizeof (uio));
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2861
	bzero(&iov, sizeof (iov));
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2862
	iov.iov_base = buf;
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2863
	iov.iov_len = 0;
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2864
	uio.uio_iov = &iov;
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2865
	uio.uio_iovcnt = 1;
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2866
	uio.uio_loffset = 0;
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2867
	uio.uio_segflg = UIO_SYSSPACE;
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2868
	uio.uio_resid = 0;
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2869
	if (rw) {
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2870
		(void) VOP_WRITE(vfs_mntdummyvp, &uio, 0, kcred, NULL);
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2871
	} else {
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2872
		(void) VOP_READ(vfs_mntdummyvp, &uio, 0, kcred, NULL);
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2873
	}
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2874
}
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2875
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2876
/*
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2877
 * Generate a write operation.
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2878
 */
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2879
void
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2880
vfs_mnttab_writeop(void)
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2881
{
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2882
	vfs_mnttab_rwop(1);
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2883
}
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2884
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2885
/*
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2886
 * Generate a read operation.
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2887
 */
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2888
void
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2889
vfs_mnttab_readop(void)
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2890
{
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2891
	vfs_mnttab_rwop(0);
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2892
}
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  2893
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2894
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2895
 * Free any mnttab information recorded in the vfs struct.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2896
 * The vfs must not be on the vfs list.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2897
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2898
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2899
vfs_freemnttab(struct vfs *vfsp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2900
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2901
	ASSERT(!VFS_ON_LIST(vfsp));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2902
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2903
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2904
	 * Free device and mount point information
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2905
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2906
	if (vfsp->vfs_mntpt != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2907
		refstr_rele(vfsp->vfs_mntpt);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2908
		vfsp->vfs_mntpt = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2909
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2910
	if (vfsp->vfs_resource != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2911
		refstr_rele(vfsp->vfs_resource);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2912
		vfsp->vfs_resource = NULL;
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
	 * Now free mount options information
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2916
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2917
	vfs_freeopttbl(&vfsp->vfs_mntopts);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2918
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2919
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2920
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2921
 * Return the last mnttab modification time
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2922
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2923
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2924
vfs_mnttab_modtime(timespec_t *ts)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2925
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2926
	ASSERT(RW_LOCK_HELD(&vfslist));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2927
	*ts = vfs_mnttab_mtime;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2928
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2929
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2930
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2931
 * See if mnttab is changed
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2932
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2933
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2934
vfs_mnttab_poll(timespec_t *old, struct pollhead **phpp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2935
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2936
	int changed;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2937
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2938
	*phpp = (struct pollhead *)NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2939
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2940
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2941
	 * Note: don't grab vfs list lock before accessing vfs_mnttab_mtime.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2942
	 * Can lead to deadlock against vfs_mnttab_modtimeupd(). It is safe
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2943
	 * to not grab the vfs list lock because tv_sec is monotonically
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2944
	 * increasing.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2945
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2946
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2947
	changed = (old->tv_nsec != vfs_mnttab_mtime.tv_nsec) ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2948
	    (old->tv_sec != vfs_mnttab_mtime.tv_sec);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2949
	if (!changed) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2950
		*phpp = &vfs_pollhd;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2951
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2952
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2953
10910
951a65b3846b PSARC/2009/566 Provide minor private interface modifications to support mntfs
Robert Harris <Robert.Harris@Sun.COM>
parents: 10822
diff changeset
  2954
/* Provide a unique and monotonically-increasing timestamp. */
951a65b3846b PSARC/2009/566 Provide minor private interface modifications to support mntfs
Robert Harris <Robert.Harris@Sun.COM>
parents: 10822
diff changeset
  2955
void
951a65b3846b PSARC/2009/566 Provide minor private interface modifications to support mntfs
Robert Harris <Robert.Harris@Sun.COM>
parents: 10822
diff changeset
  2956
vfs_mono_time(timespec_t *ts)
951a65b3846b PSARC/2009/566 Provide minor private interface modifications to support mntfs
Robert Harris <Robert.Harris@Sun.COM>
parents: 10822
diff changeset
  2957
{
951a65b3846b PSARC/2009/566 Provide minor private interface modifications to support mntfs
Robert Harris <Robert.Harris@Sun.COM>
parents: 10822
diff changeset
  2958
	static volatile hrtime_t hrt;		/* The saved time. */
951a65b3846b PSARC/2009/566 Provide minor private interface modifications to support mntfs
Robert Harris <Robert.Harris@Sun.COM>
parents: 10822
diff changeset
  2959
	hrtime_t	newhrt, oldhrt;		/* For effecting the CAS. */
951a65b3846b PSARC/2009/566 Provide minor private interface modifications to support mntfs
Robert Harris <Robert.Harris@Sun.COM>
parents: 10822
diff changeset
  2960
	timespec_t	newts;
951a65b3846b PSARC/2009/566 Provide minor private interface modifications to support mntfs
Robert Harris <Robert.Harris@Sun.COM>
parents: 10822
diff changeset
  2961
11005
fe42ca39a510 6898786 vfs_mono_time() can produce time stamps from the past
Robert Harris <Robert.Harris@Sun.COM>
parents: 10922
diff changeset
  2962
	/*
fe42ca39a510 6898786 vfs_mono_time() can produce time stamps from the past
Robert Harris <Robert.Harris@Sun.COM>
parents: 10922
diff changeset
  2963
	 * Try gethrestime() first, but be prepared to fabricate a sensible
fe42ca39a510 6898786 vfs_mono_time() can produce time stamps from the past
Robert Harris <Robert.Harris@Sun.COM>
parents: 10922
diff changeset
  2964
	 * answer at the first sign of any trouble.
fe42ca39a510 6898786 vfs_mono_time() can produce time stamps from the past
Robert Harris <Robert.Harris@Sun.COM>
parents: 10922
diff changeset
  2965
	 */
10910
951a65b3846b PSARC/2009/566 Provide minor private interface modifications to support mntfs
Robert Harris <Robert.Harris@Sun.COM>
parents: 10822
diff changeset
  2966
	gethrestime(&newts);
951a65b3846b PSARC/2009/566 Provide minor private interface modifications to support mntfs
Robert Harris <Robert.Harris@Sun.COM>
parents: 10822
diff changeset
  2967
	newhrt = ts2hrt(&newts);
11005
fe42ca39a510 6898786 vfs_mono_time() can produce time stamps from the past
Robert Harris <Robert.Harris@Sun.COM>
parents: 10922
diff changeset
  2968
	for (;;) {
10910
951a65b3846b PSARC/2009/566 Provide minor private interface modifications to support mntfs
Robert Harris <Robert.Harris@Sun.COM>
parents: 10822
diff changeset
  2969
		oldhrt = hrt;
11005
fe42ca39a510 6898786 vfs_mono_time() can produce time stamps from the past
Robert Harris <Robert.Harris@Sun.COM>
parents: 10922
diff changeset
  2970
		if (newhrt <= hrt)
fe42ca39a510 6898786 vfs_mono_time() can produce time stamps from the past
Robert Harris <Robert.Harris@Sun.COM>
parents: 10922
diff changeset
  2971
			newhrt = hrt + 1;
fe42ca39a510 6898786 vfs_mono_time() can produce time stamps from the past
Robert Harris <Robert.Harris@Sun.COM>
parents: 10922
diff changeset
  2972
		if (cas64((uint64_t *)&hrt, oldhrt, newhrt) == oldhrt)
fe42ca39a510 6898786 vfs_mono_time() can produce time stamps from the past
Robert Harris <Robert.Harris@Sun.COM>
parents: 10922
diff changeset
  2973
			break;
fe42ca39a510 6898786 vfs_mono_time() can produce time stamps from the past
Robert Harris <Robert.Harris@Sun.COM>
parents: 10922
diff changeset
  2974
	}
10910
951a65b3846b PSARC/2009/566 Provide minor private interface modifications to support mntfs
Robert Harris <Robert.Harris@Sun.COM>
parents: 10822
diff changeset
  2975
	hrt2ts(newhrt, ts);
951a65b3846b PSARC/2009/566 Provide minor private interface modifications to support mntfs
Robert Harris <Robert.Harris@Sun.COM>
parents: 10822
diff changeset
  2976
}
951a65b3846b PSARC/2009/566 Provide minor private interface modifications to support mntfs
Robert Harris <Robert.Harris@Sun.COM>
parents: 10822
diff changeset
  2977
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2978
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2979
 * Update the mnttab modification time and wake up any waiters for
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2980
 * mnttab changes
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2981
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2982
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2983
vfs_mnttab_modtimeupd()
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2984
{
11005
fe42ca39a510 6898786 vfs_mono_time() can produce time stamps from the past
Robert Harris <Robert.Harris@Sun.COM>
parents: 10922
diff changeset
  2985
	hrtime_t oldhrt, newhrt;
fe42ca39a510 6898786 vfs_mono_time() can produce time stamps from the past
Robert Harris <Robert.Harris@Sun.COM>
parents: 10922
diff changeset
  2986
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2987
	ASSERT(RW_WRITE_HELD(&vfslist));
11005
fe42ca39a510 6898786 vfs_mono_time() can produce time stamps from the past
Robert Harris <Robert.Harris@Sun.COM>
parents: 10922
diff changeset
  2988
	oldhrt = ts2hrt(&vfs_mnttab_mtime);
fe42ca39a510 6898786 vfs_mono_time() can produce time stamps from the past
Robert Harris <Robert.Harris@Sun.COM>
parents: 10922
diff changeset
  2989
	gethrestime(&vfs_mnttab_mtime);
fe42ca39a510 6898786 vfs_mono_time() can produce time stamps from the past
Robert Harris <Robert.Harris@Sun.COM>
parents: 10922
diff changeset
  2990
	newhrt = ts2hrt(&vfs_mnttab_mtime);
fe42ca39a510 6898786 vfs_mono_time() can produce time stamps from the past
Robert Harris <Robert.Harris@Sun.COM>
parents: 10922
diff changeset
  2991
	if (oldhrt == (hrtime_t)0)
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2992
		vfs_mnttab_ctime = vfs_mnttab_mtime;
11005
fe42ca39a510 6898786 vfs_mono_time() can produce time stamps from the past
Robert Harris <Robert.Harris@Sun.COM>
parents: 10922
diff changeset
  2993
	/*
fe42ca39a510 6898786 vfs_mono_time() can produce time stamps from the past
Robert Harris <Robert.Harris@Sun.COM>
parents: 10922
diff changeset
  2994
	 * Attempt to provide unique mtime (like uniqtime but not).
fe42ca39a510 6898786 vfs_mono_time() can produce time stamps from the past
Robert Harris <Robert.Harris@Sun.COM>
parents: 10922
diff changeset
  2995
	 */
fe42ca39a510 6898786 vfs_mono_time() can produce time stamps from the past
Robert Harris <Robert.Harris@Sun.COM>
parents: 10922
diff changeset
  2996
	if (newhrt == oldhrt) {
fe42ca39a510 6898786 vfs_mono_time() can produce time stamps from the past
Robert Harris <Robert.Harris@Sun.COM>
parents: 10922
diff changeset
  2997
		newhrt++;
fe42ca39a510 6898786 vfs_mono_time() can produce time stamps from the past
Robert Harris <Robert.Harris@Sun.COM>
parents: 10922
diff changeset
  2998
		hrt2ts(newhrt, &vfs_mnttab_mtime);
fe42ca39a510 6898786 vfs_mono_time() can produce time stamps from the past
Robert Harris <Robert.Harris@Sun.COM>
parents: 10922
diff changeset
  2999
	}
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3000
	pollwakeup(&vfs_pollhd, (short)POLLRDBAND);
4863
7b14ad153d91 PSARC/2007/027 File Events Notification API
praks
parents: 4813
diff changeset
  3001
	vfs_mnttab_writeop();
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3002
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3003
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3004
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3005
dounmount(struct vfs *vfsp, int flag, cred_t *cr)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3006
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3007
	vnode_t *coveredvp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3008
	int error;
1488
196daa2cf3db PSARC/2006/034 fsstat
rsb
parents: 994
diff changeset
  3009
	extern void teardown_vopstats(vfs_t *);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3010
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3011
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3012
	 * Get covered vnode. This will be NULL if the vfs is not linked
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3013
	 * into the file system name space (i.e., domount() with MNT_NOSPICE).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3014
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3015
	coveredvp = vfsp->vfs_vnodecovered;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3016
	ASSERT(coveredvp == NULL || vn_vfswlock_held(coveredvp));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3017
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3018
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3019
	 * Purge all dnlc entries for this vfs.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3020
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3021
	(void) dnlc_purge_vfsp(vfsp, 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3022
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3023
	/* For forcible umount, skip VFS_SYNC() since it may hang */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3024
	if ((flag & MS_FORCE) == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3025
		(void) VFS_SYNC(vfsp, 0, cr);
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
	 * Lock the vfs to maintain fs status quo during unmount.  This
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3029
	 * has to be done after the sync because ufs_update tries to acquire
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3030
	 * the vfs_reflock.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3031
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3032
	vfs_lock_wait(vfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3033
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3034
	if (error = VFS_UNMOUNT(vfsp, flag, cr)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3035
		vfs_unlock(vfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3036
		if (coveredvp != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3037
			vn_vfsunlock(coveredvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3038
	} else if (coveredvp != NULL) {
1488
196daa2cf3db PSARC/2006/034 fsstat
rsb
parents: 994
diff changeset
  3039
		teardown_vopstats(vfsp);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3040
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3041
		 * vfs_remove() will do a VN_RELE(vfsp->vfs_vnodecovered)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3042
		 * when it frees vfsp so we do a VN_HOLD() so we can
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3043
		 * continue to use coveredvp afterwards.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3044
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3045
		VN_HOLD(coveredvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3046
		vfs_remove(vfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3047
		vn_vfsunlock(coveredvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3048
		VN_RELE(coveredvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3049
	} else {
1488
196daa2cf3db PSARC/2006/034 fsstat
rsb
parents: 994
diff changeset
  3050
		teardown_vopstats(vfsp);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3051
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3052
		 * Release the reference to vfs that is not linked
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3053
		 * into the name space.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3054
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3055
		vfs_unlock(vfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3056
		VFS_RELE(vfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3057
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3058
	return (error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3059
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3060
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
 * Vfs_unmountall() is called by uadmin() to unmount all
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3064
 * mounted file systems (except the root file system) during shutdown.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3065
 * It follows the existing locking protocol when traversing the vfs list
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3066
 * to sync and unmount vfses. Even though there should be no
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3067
 * other thread running while the system is shutting down, it is prudent
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3068
 * to still follow the locking protocol.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3069
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3070
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3071
vfs_unmountall(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3072
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3073
	struct vfs *vfsp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3074
	struct vfs *prev_vfsp = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3075
	int error;
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
	 * Toss all dnlc entries now so that the per-vfs sync
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3079
	 * and unmount operations don't have to slog through
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3080
	 * a bunch of uninteresting vnodes over and over again.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3081
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3082
	dnlc_purge();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3083
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3084
	vfs_list_lock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3085
	for (vfsp = rootvfs->vfs_prev; vfsp != rootvfs; vfsp = prev_vfsp) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3086
		prev_vfsp = vfsp->vfs_prev;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3087
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3088
		if (vfs_lock(vfsp) != 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3089
			continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3090
		error = vn_vfswlock(vfsp->vfs_vnodecovered);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3091
		vfs_unlock(vfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3092
		if (error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3093
			continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3094
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3095
		vfs_list_unlock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3096
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3097
		(void) VFS_SYNC(vfsp, SYNC_CLOSE, CRED());
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3098
		(void) dounmount(vfsp, 0, CRED());
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
		 * Since we dropped the vfslist lock above we must
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3102
		 * verify that next_vfsp still exists, else start over.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3103
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3104
		vfs_list_lock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3105
		for (vfsp = rootvfs->vfs_prev;
3912
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3904
diff changeset
  3106
		    vfsp != rootvfs; vfsp = vfsp->vfs_prev)
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3107
			if (vfsp == prev_vfsp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3108
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3109
		if (vfsp == rootvfs && prev_vfsp != rootvfs)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3110
			prev_vfsp = rootvfs->vfs_prev;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3111
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3112
	vfs_list_unlock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3113
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3114
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3115
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3116
 * Called to add an entry to the end of the vfs mount in progress list
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3117
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3118
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3119
vfs_addmip(dev_t dev, struct vfs *vfsp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3120
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3121
	struct ipmnt *mipp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3122
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3123
	mipp = (struct ipmnt *)kmem_alloc(sizeof (struct ipmnt), KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3124
	mipp->mip_next = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3125
	mipp->mip_dev = dev;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3126
	mipp->mip_vfsp = vfsp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3127
	mutex_enter(&vfs_miplist_mutex);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3128
	if (vfs_miplist_end != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3129
		vfs_miplist_end->mip_next = mipp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3130
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3131
		vfs_miplist = mipp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3132
	vfs_miplist_end = mipp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3133
	mutex_exit(&vfs_miplist_mutex);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3134
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3135
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3136
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3137
 * Called to remove an entry from the mount in progress list
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3138
 * Either because the mount completed or it failed.
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_delmip(struct vfs *vfsp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3142
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3143
	struct ipmnt *mipp, *mipprev;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3144
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3145
	mutex_enter(&vfs_miplist_mutex);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3146
	mipprev = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3147
	for (mipp = vfs_miplist;
3912
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3904
diff changeset
  3148
	    mipp && mipp->mip_vfsp != vfsp; mipp = mipp->mip_next) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3149
		mipprev = mipp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3150
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3151
	if (mipp == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3152
		return; /* shouldn't happen */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3153
	if (mipp == vfs_miplist_end)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3154
		vfs_miplist_end = mipprev;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3155
	if (mipprev == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3156
		vfs_miplist = mipp->mip_next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3157
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3158
		mipprev->mip_next = mipp->mip_next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3159
	mutex_exit(&vfs_miplist_mutex);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3160
	kmem_free(mipp, sizeof (struct ipmnt));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3161
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3162
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3163
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3164
 * vfs_add is called by a specific filesystem's mount routine to add
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3165
 * the new vfs into the vfs list/hash and to cover the mounted-on vnode.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3166
 * The vfs should already have been locked by the caller.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3167
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3168
 * coveredvp is NULL if this is the root.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3169
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3170
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3171
vfs_add(vnode_t *coveredvp, struct vfs *vfsp, int mflag)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3172
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3173
	int newflag;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3174
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3175
	ASSERT(vfs_lock_held(vfsp));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3176
	VFS_HOLD(vfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3177
	newflag = vfsp->vfs_flag;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3178
	if (mflag & MS_RDONLY)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3179
		newflag |= VFS_RDONLY;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3180
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3181
		newflag &= ~VFS_RDONLY;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3182
	if (mflag & MS_NOSUID)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3183
		newflag |= (VFS_NOSETUID|VFS_NODEVICES);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3184
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3185
		newflag &= ~(VFS_NOSETUID|VFS_NODEVICES);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3186
	if (mflag & MS_NOMNTTAB)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3187
		newflag |= VFS_NOMNTTAB;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3188
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3189
		newflag &= ~VFS_NOMNTTAB;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3190
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3191
	if (coveredvp != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3192
		ASSERT(vn_vfswlock_held(coveredvp));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3193
		coveredvp->v_vfsmountedhere = vfsp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3194
		VN_HOLD(coveredvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3195
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3196
	vfsp->vfs_vnodecovered = coveredvp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3197
	vfsp->vfs_flag = newflag;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3198
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3199
	vfs_list_add(vfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3200
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3201
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3202
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3203
 * Remove a vfs from the vfs list, null out the pointer from the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3204
 * covered vnode to the vfs (v_vfsmountedhere), and null out the pointer
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3205
 * from the vfs to the covered vnode (vfs_vnodecovered). Release the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3206
 * reference to the vfs and to the covered vnode.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3207
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3208
 * Called from dounmount after it's confirmed with the file system
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3209
 * that the unmount is legal.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3210
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3211
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3212
vfs_remove(struct vfs *vfsp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3213
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3214
	vnode_t *vp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3215
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3216
	ASSERT(vfs_lock_held(vfsp));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3217
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3218
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3219
	 * Can't unmount root.  Should never happen because fs will
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3220
	 * be busy.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3221
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3222
	if (vfsp == rootvfs)
3446
5903aece022d PSARC 2006/469 EOF and removal of eeprom -I
mrj
parents: 2621
diff changeset
  3223
		panic("vfs_remove: unmounting root");
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3224
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3225
	vfs_list_remove(vfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3226
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3227
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3228
	 * Unhook from the file system name space.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3229
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3230
	vp = vfsp->vfs_vnodecovered;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3231
	ASSERT(vn_vfswlock_held(vp));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3232
	vp->v_vfsmountedhere = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3233
	vfsp->vfs_vnodecovered = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3234
	VN_RELE(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3235
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3236
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3237
	 * Release lock and wakeup anybody waiting.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3238
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3239
	vfs_unlock(vfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3240
	VFS_RELE(vfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3241
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3242
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3243
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3244
 * Lock a filesystem to prevent access to it while mounting,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3245
 * unmounting and syncing.  Return EBUSY immediately if lock
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3246
 * can't be acquired.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3247
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3248
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3249
vfs_lock(vfs_t *vfsp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3250
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3251
	vn_vfslocks_entry_t *vpvfsentry;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3252
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3253
	vpvfsentry = vn_vfslocks_getlock(vfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3254
	if (rwst_tryenter(&vpvfsentry->ve_lock, RW_WRITER))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3255
		return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3256
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3257
	vn_vfslocks_rele(vpvfsentry);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3258
	return (EBUSY);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3259
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3260
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3261
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3262
vfs_rlock(vfs_t *vfsp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3263
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3264
	vn_vfslocks_entry_t *vpvfsentry;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3265
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3266
	vpvfsentry = vn_vfslocks_getlock(vfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3267
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3268
	if (rwst_tryenter(&vpvfsentry->ve_lock, RW_READER))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3269
		return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3270
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3271
	vn_vfslocks_rele(vpvfsentry);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3272
	return (EBUSY);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3273
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3274
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3275
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3276
vfs_lock_wait(vfs_t *vfsp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3277
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3278
	vn_vfslocks_entry_t *vpvfsentry;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3279
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3280
	vpvfsentry = vn_vfslocks_getlock(vfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3281
	rwst_enter(&vpvfsentry->ve_lock, RW_WRITER);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3282
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3283
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3284
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3285
vfs_rlock_wait(vfs_t *vfsp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3286
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3287
	vn_vfslocks_entry_t *vpvfsentry;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3288
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3289
	vpvfsentry = vn_vfslocks_getlock(vfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3290
	rwst_enter(&vpvfsentry->ve_lock, RW_READER);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3291
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3292
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3293
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3294
 * Unlock a locked filesystem.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3295
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3296
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3297
vfs_unlock(vfs_t *vfsp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3298
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3299
	vn_vfslocks_entry_t *vpvfsentry;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3300
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3301
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3302
	 * vfs_unlock will mimic sema_v behaviour to fix 4748018.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3303
	 * And these changes should remain for the patch changes as it is.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3304
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3305
	if (panicstr)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3306
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3307
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3308
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3309
	 * ve_refcount needs to be dropped twice here.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3310
	 * 1. To release refernce after a call to vfs_locks_getlock()
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3311
	 * 2. To release the reference from the locking routines like
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3312
	 *    vfs_rlock_wait/vfs_wlock_wait/vfs_wlock etc,.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3313
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3314
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3315
	vpvfsentry = vn_vfslocks_getlock(vfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3316
	vn_vfslocks_rele(vpvfsentry);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3317
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3318
	rwst_exit(&vpvfsentry->ve_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3319
	vn_vfslocks_rele(vpvfsentry);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3320
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3321
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3322
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3323
 * Utility routine that allows a filesystem to construct its
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3324
 * fsid in "the usual way" - by munging some underlying dev_t and
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3325
 * the filesystem type number into the 64-bit fsid.  Note that
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3326
 * this implicitly relies on dev_t persistence to make filesystem
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3327
 * id's persistent.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3328
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3329
 * There's nothing to prevent an individual fs from constructing its
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3330
 * fsid in a different way, and indeed they should.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3331
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3332
 * Since we want fsids to be 32-bit quantities (so that they can be
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3333
 * exported identically by either 32-bit or 64-bit APIs, as well as
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3334
 * the fact that fsid's are "known" to NFS), we compress the device
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3335
 * number given down to 32-bits, and panic if that isn't possible.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3336
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3337
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3338
vfs_make_fsid(fsid_t *fsi, dev_t dev, int val)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3339
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3340
	if (!cmpldev((dev32_t *)&fsi->val[0], dev))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3341
		panic("device number too big for fsid!");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3342
	fsi->val[1] = val;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3343
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3344
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3345
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3346
vfs_lock_held(vfs_t *vfsp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3347
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3348
	int held;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3349
	vn_vfslocks_entry_t *vpvfsentry;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3350
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3351
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3352
	 * vfs_lock_held will mimic sema_held behaviour
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3353
	 * if panicstr is set. And these changes should remain
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3354
	 * for the patch changes as it is.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3355
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3356
	if (panicstr)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3357
		return (1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3358
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3359
	vpvfsentry = vn_vfslocks_getlock(vfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3360
	held = rwst_lock_held(&vpvfsentry->ve_lock, RW_WRITER);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3361
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3362
	vn_vfslocks_rele(vpvfsentry);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3363
	return (held);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3364
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3365
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3366
struct _kthread *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3367
vfs_lock_owner(vfs_t *vfsp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3368
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3369
	struct _kthread *owner;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3370
	vn_vfslocks_entry_t *vpvfsentry;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3371
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3372
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3373
	 * vfs_wlock_held will mimic sema_held behaviour
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3374
	 * if panicstr is set. And these changes should remain
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3375
	 * for the patch changes as it is.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3376
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3377
	if (panicstr)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3378
		return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3379
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3380
	vpvfsentry = vn_vfslocks_getlock(vfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3381
	owner = rwst_owner(&vpvfsentry->ve_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3382
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3383
	vn_vfslocks_rele(vpvfsentry);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3384
	return (owner);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3385
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3386
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3387
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3388
 * vfs list locking.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3389
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3390
 * Rather than manipulate the vfslist lock directly, we abstract into lock
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3391
 * and unlock routines to allow the locking implementation to be changed for
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3392
 * clustering.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3393
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3394
 * Whenever the vfs list is modified through its hash links, the overall list
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3395
 * lock must be obtained before locking the relevant hash bucket.  But to see
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3396
 * 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
  3397
 * hash bucket without getting the overall list lock.  (See getvfs() below.)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3398
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3399
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3400
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3401
vfs_list_lock()
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3402
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3403
	rw_enter(&vfslist, RW_WRITER);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3404
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3405
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3406
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3407
vfs_list_read_lock()
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3408
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3409
	rw_enter(&vfslist, RW_READER);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3410
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3411
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3412
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3413
vfs_list_unlock()
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3414
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3415
	rw_exit(&vfslist);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3416
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3417
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3418
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3419
 * Low level worker routines for adding entries to and removing entries from
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3420
 * the vfs list.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3421
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3422
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3423
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3424
vfs_hash_add(struct vfs *vfsp, int insert_at_head)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3425
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3426
	int vhno;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3427
	struct vfs **hp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3428
	dev_t dev;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3429
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3430
	ASSERT(RW_WRITE_HELD(&vfslist));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3431
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3432
	dev = expldev(vfsp->vfs_fsid.val[0]);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3433
	vhno = VFSHASH(getmajor(dev), getminor(dev));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3434
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3435
	mutex_enter(&rvfs_list[vhno].rvfs_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3436
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3437
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3438
	 * Link into the hash table, inserting it at the end, so that LOFS
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3439
	 * with the same fsid as UFS (or other) file systems will not hide the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3440
	 * UFS.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3441
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3442
	if (insert_at_head) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3443
		vfsp->vfs_hash = rvfs_list[vhno].rvfs_head;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3444
		rvfs_list[vhno].rvfs_head = vfsp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3445
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3446
		for (hp = &rvfs_list[vhno].rvfs_head; *hp != NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3447
		    hp = &(*hp)->vfs_hash)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3448
			continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3449
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3450
		 * hp now contains the address of the pointer to update
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3451
		 * to effect the insertion.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3452
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3453
		vfsp->vfs_hash = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3454
		*hp = vfsp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3455
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3456
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3457
	rvfs_list[vhno].rvfs_len++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3458
	mutex_exit(&rvfs_list[vhno].rvfs_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3459
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3460
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3461
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3462
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3463
vfs_hash_remove(struct vfs *vfsp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3464
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3465
	int vhno;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3466
	struct vfs *tvfsp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3467
	dev_t dev;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3468
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3469
	ASSERT(RW_WRITE_HELD(&vfslist));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3470
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3471
	dev = expldev(vfsp->vfs_fsid.val[0]);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3472
	vhno = VFSHASH(getmajor(dev), getminor(dev));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3473
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3474
	mutex_enter(&rvfs_list[vhno].rvfs_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3475
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3476
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3477
	 * Remove from hash.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3478
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3479
	if (rvfs_list[vhno].rvfs_head == vfsp) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3480
		rvfs_list[vhno].rvfs_head = vfsp->vfs_hash;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3481
		rvfs_list[vhno].rvfs_len--;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3482
		goto foundit;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3483
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3484
	for (tvfsp = rvfs_list[vhno].rvfs_head; tvfsp != NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3485
	    tvfsp = tvfsp->vfs_hash) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3486
		if (tvfsp->vfs_hash == vfsp) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3487
			tvfsp->vfs_hash = vfsp->vfs_hash;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3488
			rvfs_list[vhno].rvfs_len--;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3489
			goto foundit;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3490
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3491
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3492
	cmn_err(CE_WARN, "vfs_list_remove: vfs not found in hash");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3493
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3494
foundit:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3495
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3496
	mutex_exit(&rvfs_list[vhno].rvfs_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3497
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3498
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3499
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3500
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3501
vfs_list_add(struct vfs *vfsp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3502
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3503
	zone_t *zone;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3504
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3505
	/*
10910
951a65b3846b PSARC/2009/566 Provide minor private interface modifications to support mntfs
Robert Harris <Robert.Harris@Sun.COM>
parents: 10822
diff changeset
  3506
	 * Typically, the vfs_t will have been created on behalf of the file
951a65b3846b PSARC/2009/566 Provide minor private interface modifications to support mntfs
Robert Harris <Robert.Harris@Sun.COM>
parents: 10822
diff changeset
  3507
	 * system in vfs_init, where it will have been provided with a
951a65b3846b PSARC/2009/566 Provide minor private interface modifications to support mntfs
Robert Harris <Robert.Harris@Sun.COM>
parents: 10822
diff changeset
  3508
	 * vfs_impl_t. This, however, might be lacking if the vfs_t was created
951a65b3846b PSARC/2009/566 Provide minor private interface modifications to support mntfs
Robert Harris <Robert.Harris@Sun.COM>
parents: 10822
diff changeset
  3509
	 * by an unbundled file system. We therefore check for such an example
951a65b3846b PSARC/2009/566 Provide minor private interface modifications to support mntfs
Robert Harris <Robert.Harris@Sun.COM>
parents: 10822
diff changeset
  3510
	 * before stamping the vfs_t with its creation time for the benefit of
951a65b3846b PSARC/2009/566 Provide minor private interface modifications to support mntfs
Robert Harris <Robert.Harris@Sun.COM>
parents: 10822
diff changeset
  3511
	 * mntfs.
951a65b3846b PSARC/2009/566 Provide minor private interface modifications to support mntfs
Robert Harris <Robert.Harris@Sun.COM>
parents: 10822
diff changeset
  3512
	 */
951a65b3846b PSARC/2009/566 Provide minor private interface modifications to support mntfs
Robert Harris <Robert.Harris@Sun.COM>
parents: 10822
diff changeset
  3513
	if (vfsp->vfs_implp == NULL)
951a65b3846b PSARC/2009/566 Provide minor private interface modifications to support mntfs
Robert Harris <Robert.Harris@Sun.COM>
parents: 10822
diff changeset
  3514
		vfsimpl_setup(vfsp);
951a65b3846b PSARC/2009/566 Provide minor private interface modifications to support mntfs
Robert Harris <Robert.Harris@Sun.COM>
parents: 10822
diff changeset
  3515
	vfs_mono_time(&vfsp->vfs_hrctime);
951a65b3846b PSARC/2009/566 Provide minor private interface modifications to support mntfs
Robert Harris <Robert.Harris@Sun.COM>
parents: 10822
diff changeset
  3516
951a65b3846b PSARC/2009/566 Provide minor private interface modifications to support mntfs
Robert Harris <Robert.Harris@Sun.COM>
parents: 10822
diff changeset
  3517
	/*
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3518
	 * The zone that owns the mount is the one that performed the mount.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3519
	 * Note that this isn't necessarily the same as the zone mounted into.
13108
b02331b7b26d 6906740 Zones need an improved reference counting mechanism
jv227347 <Jordan.Vaughan@Sun.com>
parents: 12906
diff changeset
  3520
	 * The corresponding zone_rele_ref() will be done when the vfs_t
b02331b7b26d 6906740 Zones need an improved reference counting mechanism
jv227347 <Jordan.Vaughan@Sun.com>
parents: 12906
diff changeset
  3521
	 * is being free'd.
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3522
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3523
	vfsp->vfs_zone = curproc->p_zone;
13108
b02331b7b26d 6906740 Zones need an improved reference counting mechanism
jv227347 <Jordan.Vaughan@Sun.com>
parents: 12906
diff changeset
  3524
	zone_init_ref(&vfsp->vfs_implp->vi_zone_ref);
b02331b7b26d 6906740 Zones need an improved reference counting mechanism
jv227347 <Jordan.Vaughan@Sun.com>
parents: 12906
diff changeset
  3525
	zone_hold_ref(vfsp->vfs_zone, &vfsp->vfs_implp->vi_zone_ref,
b02331b7b26d 6906740 Zones need an improved reference counting mechanism
jv227347 <Jordan.Vaughan@Sun.com>
parents: 12906
diff changeset
  3526
	    ZONE_REF_VFS);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3527
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3528
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3529
	 * Find the zone mounted into, and put this mount on its vfs list.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3530
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3531
	zone = zone_find_by_path(refstr_value(vfsp->vfs_mntpt));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3532
	ASSERT(zone != NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3533
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3534
	 * Special casing for the root vfs.  This structure is allocated
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3535
	 * statically and hooked onto rootvfs at link time.  During the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3536
	 * vfs_mountroot call at system startup time, the root file system's
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3537
	 * VFS_MOUNTROOT routine will call vfs_add with this root vfs struct
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3538
	 * as argument.  The code below must detect and handle this special
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3539
	 * case.  The only apparent justification for this special casing is
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3540
	 * to ensure that the root file system appears at the head of the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3541
	 * list.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3542
	 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3543
	 * XXX:	I'm assuming that it's ok to do normal list locking when
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3544
	 *	adding the entry for the root file system (this used to be
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3545
	 *	done with no locks held).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3546
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3547
	vfs_list_lock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3548
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3549
	 * Link into the vfs list proper.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3550
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3551
	if (vfsp == &root) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3552
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3553
		 * Assert: This vfs is already on the list as its first entry.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3554
		 * Thus, there's nothing to do.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3555
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3556
		ASSERT(rootvfs == vfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3557
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3558
		 * Add it to the head of the global zone's vfslist.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3559
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3560
		ASSERT(zone == global_zone);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3561
		ASSERT(zone->zone_vfslist == NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3562
		zone->zone_vfslist = vfsp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3563
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3564
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3565
		 * Link to end of list using vfs_prev (as rootvfs is now a
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3566
		 * doubly linked circular list) so list is in mount order for
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3567
		 * mnttab use.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3568
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3569
		rootvfs->vfs_prev->vfs_next = vfsp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3570
		vfsp->vfs_prev = rootvfs->vfs_prev;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3571
		rootvfs->vfs_prev = vfsp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3572
		vfsp->vfs_next = rootvfs;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3573
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3574
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3575
		 * Do it again for the zone-private list (which may be NULL).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3576
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3577
		if (zone->zone_vfslist == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3578
			ASSERT(zone != global_zone);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3579
			zone->zone_vfslist = vfsp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3580
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3581
			zone->zone_vfslist->vfs_zone_prev->vfs_zone_next = vfsp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3582
			vfsp->vfs_zone_prev = zone->zone_vfslist->vfs_zone_prev;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3583
			zone->zone_vfslist->vfs_zone_prev = vfsp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3584
			vfsp->vfs_zone_next = zone->zone_vfslist;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3585
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3586
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3587
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3588
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3589
	 * Link into the hash table, inserting it at the end, so that LOFS
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3590
	 * with the same fsid as UFS (or other) file systems will not hide
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3591
	 * the UFS.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3592
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3593
	vfs_hash_add(vfsp, 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3594
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3595
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3596
	 * update the mnttab modification time
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3597
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3598
	vfs_mnttab_modtimeupd();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3599
	vfs_list_unlock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3600
	zone_rele(zone);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3601
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3602
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3603
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3604
vfs_list_remove(struct vfs *vfsp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3605
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3606
	zone_t *zone;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3607
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3608
	zone = zone_find_by_path(refstr_value(vfsp->vfs_mntpt));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3609
	ASSERT(zone != NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3610
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3611
	 * Callers are responsible for preventing attempts to unmount the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3612
	 * root.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3613
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3614
	ASSERT(vfsp != rootvfs);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3615
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3616
	vfs_list_lock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3617
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3618
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3619
	 * Remove from hash.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3620
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3621
	vfs_hash_remove(vfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3622
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3623
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3624
	 * Remove from vfs list.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3625
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3626
	vfsp->vfs_prev->vfs_next = vfsp->vfs_next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3627
	vfsp->vfs_next->vfs_prev = vfsp->vfs_prev;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3628
	vfsp->vfs_next = vfsp->vfs_prev = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3629
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3630
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3631
	 * Remove from zone-specific vfs list.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3632
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3633
	if (zone->zone_vfslist == vfsp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3634
		zone->zone_vfslist = vfsp->vfs_zone_next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3635
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3636
	if (vfsp->vfs_zone_next == vfsp) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3637
		ASSERT(vfsp->vfs_zone_prev == vfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3638
		ASSERT(zone->zone_vfslist == vfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3639
		zone->zone_vfslist = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3640
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3641
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3642
	vfsp->vfs_zone_prev->vfs_zone_next = vfsp->vfs_zone_next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3643
	vfsp->vfs_zone_next->vfs_zone_prev = vfsp->vfs_zone_prev;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3644
	vfsp->vfs_zone_next = vfsp->vfs_zone_prev = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3645
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3646
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3647
	 * update the mnttab modification time
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3648
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3649
	vfs_mnttab_modtimeupd();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3650
	vfs_list_unlock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3651
	zone_rele(zone);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3652
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3653
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3654
struct vfs *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3655
getvfs(fsid_t *fsid)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3656
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3657
	struct vfs *vfsp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3658
	int val0 = fsid->val[0];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3659
	int val1 = fsid->val[1];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3660
	dev_t dev = expldev(val0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3661
	int vhno = VFSHASH(getmajor(dev), getminor(dev));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3662
	kmutex_t *hmp = &rvfs_list[vhno].rvfs_lock;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3663
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3664
	mutex_enter(hmp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3665
	for (vfsp = rvfs_list[vhno].rvfs_head; vfsp; vfsp = vfsp->vfs_hash) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3666
		if (vfsp->vfs_fsid.val[0] == val0 &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3667
		    vfsp->vfs_fsid.val[1] == val1) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3668
			VFS_HOLD(vfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3669
			mutex_exit(hmp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3670
			return (vfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3671
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3672
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3673
	mutex_exit(hmp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3674
	return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3675
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3676
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3677
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3678
 * Search the vfs mount in progress list for a specified device/vfs entry.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3679
 * Returns 0 if the first entry in the list that the device matches has the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3680
 * given vfs pointer as well.  If the device matches but a different vfs
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3681
 * pointer is encountered in the list before the given vfs pointer then
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3682
 * a 1 is returned.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3683
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3684
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3685
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3686
vfs_devmounting(dev_t dev, struct vfs *vfsp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3687
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3688
	int retval = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3689
	struct ipmnt *mipp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3690
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3691
	mutex_enter(&vfs_miplist_mutex);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3692
	for (mipp = vfs_miplist; mipp != NULL; mipp = mipp->mip_next) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3693
		if (mipp->mip_dev == dev) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3694
			if (mipp->mip_vfsp != vfsp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3695
				retval = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3696
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3697
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3698
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3699
	mutex_exit(&vfs_miplist_mutex);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3700
	return (retval);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3701
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3702
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3703
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3704
 * Search the vfs list for a specified device.  Returns 1, if entry is found
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3705
 * or 0 if no suitable entry is found.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3706
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3707
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3708
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3709
vfs_devismounted(dev_t dev)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3710
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3711
	struct vfs *vfsp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3712
	int found;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3713
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3714
	vfs_list_read_lock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3715
	vfsp = rootvfs;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3716
	found = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3717
	do {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3718
		if (vfsp->vfs_dev == dev) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3719
			found = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3720
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3721
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3722
		vfsp = vfsp->vfs_next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3723
	} while (vfsp != rootvfs);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3724
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3725
	vfs_list_unlock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3726
	return (found);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3727
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3728
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3729
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3730
 * Search the vfs list for a specified device.  Returns a pointer to it
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3731
 * or NULL if no suitable entry is found. The caller of this routine
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3732
 * is responsible for releasing the returned vfs pointer.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3733
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3734
struct vfs *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3735
vfs_dev2vfsp(dev_t dev)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3736
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3737
	struct vfs *vfsp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3738
	int found;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3739
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3740
	vfs_list_read_lock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3741
	vfsp = rootvfs;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3742
	found = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3743
	do {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3744
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3745
		 * The following could be made more efficient by making
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3746
		 * the entire loop use vfs_zone_next if the call is from
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3747
		 * a zone.  The only callers, however, ustat(2) and
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3748
		 * umount2(2), don't seem to justify the added
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3749
		 * complexity at present.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3750
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3751
		if (vfsp->vfs_dev == dev &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3752
		    ZONE_PATH_VISIBLE(refstr_value(vfsp->vfs_mntpt),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3753
		    curproc->p_zone)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3754
			VFS_HOLD(vfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3755
			found = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3756
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3757
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3758
		vfsp = vfsp->vfs_next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3759
	} while (vfsp != rootvfs);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3760
	vfs_list_unlock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3761
	return (found ? vfsp: NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3762
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3763
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3764
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3765
 * Search the vfs list for a specified mntpoint.  Returns a pointer to it
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3766
 * or NULL if no suitable entry is found. The caller of this routine
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3767
 * is responsible for releasing the returned vfs pointer.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3768
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3769
 * Note that if multiple mntpoints match, the last one matching is
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3770
 * returned in an attempt to return the "top" mount when overlay
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3771
 * mounts are covering the same mount point.  This is accomplished by starting
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3772
 * at the end of the list and working our way backwards, stopping at the first
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3773
 * matching mount.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3774
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3775
struct vfs *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3776
vfs_mntpoint2vfsp(const char *mp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3777
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3778
	struct vfs *vfsp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3779
	struct vfs *retvfsp = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3780
	zone_t *zone = curproc->p_zone;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3781
	struct vfs *list;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3782
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3783
	vfs_list_read_lock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3784
	if (getzoneid() == GLOBAL_ZONEID) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3785
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3786
		 * The global zone may see filesystems in any zone.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3787
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3788
		vfsp = rootvfs->vfs_prev;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3789
		do {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3790
			if (strcmp(refstr_value(vfsp->vfs_mntpt), mp) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3791
				retvfsp = vfsp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3792
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3793
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3794
			vfsp = vfsp->vfs_prev;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3795
		} while (vfsp != rootvfs->vfs_prev);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3796
	} else if ((list = zone->zone_vfslist) != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3797
		const char *mntpt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3798
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3799
		vfsp = list->vfs_zone_prev;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3800
		do {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3801
			mntpt = refstr_value(vfsp->vfs_mntpt);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3802
			mntpt = ZONE_PATH_TRANSLATE(mntpt, zone);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3803
			if (strcmp(mntpt, mp) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3804
				retvfsp = vfsp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3805
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3806
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3807
			vfsp = vfsp->vfs_zone_prev;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3808
		} while (vfsp != list->vfs_zone_prev);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3809
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3810
	if (retvfsp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3811
		VFS_HOLD(retvfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3812
	vfs_list_unlock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3813
	return (retvfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3814
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3815
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3816
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3817
 * Search the vfs list for a specified vfsops.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3818
 * if vfs entry is found then return 1, else 0.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3819
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3820
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3821
vfs_opsinuse(vfsops_t *ops)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3822
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3823
	struct vfs *vfsp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3824
	int found;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3825
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3826
	vfs_list_read_lock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3827
	vfsp = rootvfs;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3828
	found = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3829
	do {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3830
		if (vfs_getops(vfsp) == ops) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3831
			found = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3832
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3833
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3834
		vfsp = vfsp->vfs_next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3835
	} while (vfsp != rootvfs);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3836
	vfs_list_unlock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3837
	return (found);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3838
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3839
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3840
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3841
 * Allocate an entry in vfssw for a file system type
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3842
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3843
struct vfssw *
6855
18f1316f1bed PSARC 2008/366 VSW_CANLOFI
johnlev
parents: 6770
diff changeset
  3844
allocate_vfssw(const char *type)
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3845
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3846
	struct vfssw *vswp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3847
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3848
	if (type[0] == '\0' || strlen(type) + 1 > _ST_FSTYPSZ) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3849
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3850
		 * The vfssw table uses the empty string to identify an
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3851
		 * available entry; we cannot add any type which has
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3852
		 * a leading NUL. The string length is limited to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3853
		 * the size of the st_fstype array in struct stat.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3854
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3855
		return (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
	ASSERT(VFSSW_WRITE_LOCKED());
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3859
	for (vswp = &vfssw[1]; vswp < &vfssw[nfstype]; vswp++)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3860
		if (!ALLOCATED_VFSSW(vswp)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3861
			vswp->vsw_name = kmem_alloc(strlen(type) + 1, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3862
			(void) strcpy(vswp->vsw_name, type);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3863
			ASSERT(vswp->vsw_count == 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3864
			vswp->vsw_count = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3865
			mutex_init(&vswp->vsw_lock, NULL, MUTEX_DEFAULT, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3866
			return (vswp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3867
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3868
	return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3869
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3870
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3871
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3872
 * Impose additional layer of translation between vfstype names
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3873
 * and module names in the filesystem.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3874
 */
6855
18f1316f1bed PSARC 2008/366 VSW_CANLOFI
johnlev
parents: 6770
diff changeset
  3875
static const char *
18f1316f1bed PSARC 2008/366 VSW_CANLOFI
johnlev
parents: 6770
diff changeset
  3876
vfs_to_modname(const char *vfstype)
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3877
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3878
	if (strcmp(vfstype, "proc") == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3879
		vfstype = "procfs";
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3880
	} else if (strcmp(vfstype, "fd") == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3881
		vfstype = "fdfs";
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3882
	} else if (strncmp(vfstype, "nfs", 3) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3883
		vfstype = "nfs";
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3884
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3885
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3886
	return (vfstype);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3887
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3888
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3889
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3890
 * Find a vfssw entry given a file system type name.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3891
 * Try to autoload the filesystem if it's not found.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3892
 * If it's installed, return the vfssw locked to prevent unloading.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3893
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3894
struct vfssw *
6855
18f1316f1bed PSARC 2008/366 VSW_CANLOFI
johnlev
parents: 6770
diff changeset
  3895
vfs_getvfssw(const char *type)
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3896
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3897
	struct vfssw *vswp;
6855
18f1316f1bed PSARC 2008/366 VSW_CANLOFI
johnlev
parents: 6770
diff changeset
  3898
	const char *modname;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3899
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3900
	RLOCK_VFSSW();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3901
	vswp = vfs_getvfsswbyname(type);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3902
	modname = vfs_to_modname(type);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3903
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3904
	if (rootdir == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3905
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3906
		 * If we haven't yet loaded the root file system, then our
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3907
		 * _init won't be called until later. Allocate vfssw entry,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3908
		 * because mod_installfs won't be called.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3909
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3910
		if (vswp == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3911
			RUNLOCK_VFSSW();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3912
			WLOCK_VFSSW();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3913
			if ((vswp = vfs_getvfsswbyname(type)) == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3914
				if ((vswp = allocate_vfssw(type)) == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3915
					WUNLOCK_VFSSW();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3916
					return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3917
				}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3918
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3919
			WUNLOCK_VFSSW();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3920
			RLOCK_VFSSW();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3921
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3922
		if (!VFS_INSTALLED(vswp)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3923
			RUNLOCK_VFSSW();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3924
			(void) modloadonly("fs", modname);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3925
		} else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3926
			RUNLOCK_VFSSW();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3927
		return (vswp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3928
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3929
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3930
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3931
	 * Try to load the filesystem.  Before calling modload(), we drop
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3932
	 * our lock on the VFS switch table, and pick it up after the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3933
	 * module is loaded.  However, there is a potential race:  the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3934
	 * module could be unloaded after the call to modload() completes
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3935
	 * but before we pick up the lock and drive on.  Therefore,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3936
	 * we keep reloading the module until we've loaded the module
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3937
	 * _and_ we have the lock on the VFS switch table.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3938
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3939
	while (vswp == NULL || !VFS_INSTALLED(vswp)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3940
		RUNLOCK_VFSSW();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3941
		if (modload("fs", modname) == -1)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3942
			return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3943
		RLOCK_VFSSW();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3944
		if (vswp == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3945
			if ((vswp = vfs_getvfsswbyname(type)) == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3946
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3947
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3948
	RUNLOCK_VFSSW();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3949
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3950
	return (vswp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3951
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3952
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3953
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3954
 * Find a vfssw entry given a file system type name.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3955
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3956
struct vfssw *
6855
18f1316f1bed PSARC 2008/366 VSW_CANLOFI
johnlev
parents: 6770
diff changeset
  3957
vfs_getvfsswbyname(const char *type)
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3958
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3959
	struct vfssw *vswp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3960
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3961
	ASSERT(VFSSW_LOCKED());
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3962
	if (type == NULL || *type == '\0')
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3963
		return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3964
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3965
	for (vswp = &vfssw[1]; vswp < &vfssw[nfstype]; vswp++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3966
		if (strcmp(type, vswp->vsw_name) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3967
			vfs_refvfssw(vswp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3968
			return (vswp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3969
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3970
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3971
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3972
	return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3973
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3974
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3975
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3976
 * Find a vfssw entry given a set of vfsops.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3977
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3978
struct vfssw *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3979
vfs_getvfsswbyvfsops(vfsops_t *vfsops)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3980
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3981
	struct vfssw *vswp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3982
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3983
	RLOCK_VFSSW();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3984
	for (vswp = &vfssw[1]; vswp < &vfssw[nfstype]; vswp++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3985
		if (ALLOCATED_VFSSW(vswp) && &vswp->vsw_vfsops == vfsops) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3986
			vfs_refvfssw(vswp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3987
			RUNLOCK_VFSSW();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3988
			return (vswp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3989
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3990
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3991
	RUNLOCK_VFSSW();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3992
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3993
	return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3994
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3995
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3996
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3997
 * Reference a vfssw entry.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3998
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3999
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4000
vfs_refvfssw(struct vfssw *vswp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4001
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4002
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4003
	mutex_enter(&vswp->vsw_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4004
	vswp->vsw_count++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4005
	mutex_exit(&vswp->vsw_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4006
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4007
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4008
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4009
 * Unreference a vfssw entry.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4010
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4011
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4012
vfs_unrefvfssw(struct vfssw *vswp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4013
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4014
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4015
	mutex_enter(&vswp->vsw_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4016
	vswp->vsw_count--;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4017
	mutex_exit(&vswp->vsw_lock);
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
int sync_timeout = 30;		/* timeout for syncing a page during panic */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4021
int sync_timeleft;		/* portion of sync_timeout remaining */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4022
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4023
static int sync_retries = 20;	/* number of retries when not making progress */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4024
static int sync_triesleft;	/* portion of sync_retries remaining */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4025
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4026
static pgcnt_t old_pgcnt, new_pgcnt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4027
static int new_bufcnt, old_bufcnt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4028
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4029
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4030
 * Sync all of the mounted filesystems, and then wait for the actual i/o to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4031
 * complete.  We wait by counting the number of dirty pages and buffers,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4032
 * pushing them out using bio_busy() and page_busy(), and then counting again.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4033
 * This routine is used during both the uadmin A_SHUTDOWN code as well as
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4034
 * the SYNC phase of the panic code (see comments in panic.c).  It should only
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4035
 * be used after some higher-level mechanism has quiesced the system so that
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4036
 * new writes are not being initiated while we are waiting for completion.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4037
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4038
 * To ensure finite running time, our algorithm uses two timeout mechanisms:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4039
 * sync_timeleft (a timer implemented by the omnipresent deadman() cyclic), and
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4040
 * sync_triesleft (a progress counter used by the vfs_syncall() loop below).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4041
 * Together these ensure that syncing completes if our i/o paths are stuck.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4042
 * The counters are declared above so they can be found easily in the debugger.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4043
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4044
 * The sync_timeleft counter is reset by bio_busy() and page_busy() using the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4045
 * vfs_syncprogress() subroutine whenever we make progress through the lists of
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4046
 * pages and buffers.  It is decremented and expired by the deadman() cyclic.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4047
 * When vfs_syncall() decides it is done, we disable the deadman() counter by
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4048
 * setting sync_timeleft to zero.  This timer guards against vfs_syncall()
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4049
 * deadlocking or hanging inside of a broken filesystem or driver routine.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4050
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4051
 * The sync_triesleft counter is updated by vfs_syncall() itself.  If we make
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4052
 * sync_retries consecutive calls to bio_busy() and page_busy() without
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4053
 * decreasing either the number of dirty buffers or dirty pages below the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4054
 * lowest count we have seen so far, we give up and return from vfs_syncall().
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4055
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4056
 * Each loop iteration ends with a call to delay() one second to allow time for
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4057
 * i/o completion and to permit the user time to read our progress messages.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4058
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4059
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4060
vfs_syncall(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4061
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4062
	if (rootdir == NULL && !modrootloaded)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4063
		return; /* panic during boot - no filesystems yet */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4064
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4065
	printf("syncing file systems...");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4066
	vfs_syncprogress();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4067
	sync();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4068
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4069
	vfs_syncprogress();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4070
	sync_triesleft = sync_retries;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4071
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4072
	old_bufcnt = new_bufcnt = INT_MAX;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4073
	old_pgcnt = new_pgcnt = ULONG_MAX;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4074
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4075
	while (sync_triesleft > 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4076
		old_bufcnt = MIN(old_bufcnt, new_bufcnt);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4077
		old_pgcnt = MIN(old_pgcnt, new_pgcnt);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4078
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4079
		new_bufcnt = bio_busy(B_TRUE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4080
		new_pgcnt = page_busy(B_TRUE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4081
		vfs_syncprogress();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4082
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4083
		if (new_bufcnt == 0 && new_pgcnt == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4084
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4085
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4086
		if (new_bufcnt < old_bufcnt || new_pgcnt < old_pgcnt)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4087
			sync_triesleft = sync_retries;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4088
		else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4089
			sync_triesleft--;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4090
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4091
		if (new_bufcnt)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4092
			printf(" [%d]", new_bufcnt);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4093
		if (new_pgcnt)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4094
			printf(" %lu", new_pgcnt);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4095
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4096
		delay(hz);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4097
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4098
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4099
	if (new_bufcnt != 0 || new_pgcnt != 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4100
		printf(" done (not all i/o completed)\n");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4101
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4102
		printf(" done\n");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4103
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4104
	sync_timeleft = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4105
	delay(hz);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4106
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4107
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4108
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4109
 * 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
  4110
 * sync_timeout to indicate that we are making progress and the deadman()
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4111
 * omnipresent cyclic should not yet time us out.  Note that it is safe to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4112
 * store to sync_timeleft here since the deadman() is firing at high-level
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4113
 * on top of us.  If we are racing with the deadman(), either the deadman()
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4114
 * will decrement the old value and then we will reset it, or we will
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4115
 * reset it and then the deadman() will immediately decrement it.  In either
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4116
 * case, correct behavior results.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4117
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4118
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4119
vfs_syncprogress(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4120
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4121
	if (panicstr)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4122
		sync_timeleft = sync_timeout;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4123
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4124
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4125
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4126
 * Map VFS flags to statvfs flags.  These shouldn't really be separate
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4127
 * flags at all.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4128
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4129
uint_t
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4130
vf_to_stf(uint_t vf)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4131
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4132
	uint_t stf = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4133
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4134
	if (vf & VFS_RDONLY)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4135
		stf |= ST_RDONLY;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4136
	if (vf & VFS_NOSETUID)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4137
		stf |= ST_NOSUID;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4138
	if (vf & VFS_NOTRUNC)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4139
		stf |= ST_NOTRUNC;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4140
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4141
	return (stf);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4142
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4143
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4144
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4145
 * Entries for (illegal) fstype 0.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4146
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4147
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4148
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4149
vfsstray_sync(struct vfs *vfsp, short arg, struct cred *cr)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4150
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4151
	cmn_err(CE_PANIC, "stray vfs operation");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4152
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4153
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4154
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4155
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4156
 * Entries for (illegal) fstype 0.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4157
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4158
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4159
vfsstray(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4160
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4161
	cmn_err(CE_PANIC, "stray vfs operation");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4162
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4163
}
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
 * Support for dealing with forced UFS unmount and its interaction with
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4167
 * LOFS. Could be used by any filesystem.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4168
 * See bug 1203132.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4169
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4170
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4171
vfs_EIO(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4172
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4173
	return (EIO);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4174
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4175
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4176
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4177
 * We've gotta define the op for sync separately, since the compiler gets
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4178
 * confused if we mix and match ANSI and normal style prototypes when
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4179
 * a "short" argument is present and spits out a warning.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4180
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4181
/*ARGSUSED*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4182
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4183
vfs_EIO_sync(struct vfs *vfsp, short arg, struct cred *cr)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4184
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4185
	return (EIO);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4186
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4187
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4188
vfs_t EIO_vfs;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4189
vfsops_t *EIO_vfsops;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4190
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4191
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4192
 * Called from startup() to initialize all loaded vfs's
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4193
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4194
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4195
vfsinit(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4196
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4197
	struct vfssw *vswp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4198
	int error;
1520
2fb01d86c1c1 6391295 fop_create() panic when running svvs over ZFS
rsb
parents: 1488
diff changeset
  4199
	extern int vopstats_enabled;
1488
196daa2cf3db PSARC/2006/034 fsstat
rsb
parents: 994
diff changeset
  4200
	extern void vopstats_startup();
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4201
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4202
	static const fs_operation_def_t EIO_vfsops_template[] = {
3898
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 3446
diff changeset
  4203
		VFSNAME_MOUNT,		{ .error = vfs_EIO },
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 3446
diff changeset
  4204
		VFSNAME_UNMOUNT,	{ .error = vfs_EIO },
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 3446
diff changeset
  4205
		VFSNAME_ROOT,		{ .error = vfs_EIO },
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 3446
diff changeset
  4206
		VFSNAME_STATVFS,	{ .error = vfs_EIO },
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 3446
diff changeset
  4207
		VFSNAME_SYNC, 		{ .vfs_sync = vfs_EIO_sync },
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 3446
diff changeset
  4208
		VFSNAME_VGET,		{ .error = vfs_EIO },
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 3446
diff changeset
  4209
		VFSNAME_MOUNTROOT,	{ .error = vfs_EIO },
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 3446
diff changeset
  4210
		VFSNAME_FREEVFS,	{ .error = vfs_EIO },
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 3446
diff changeset
  4211
		VFSNAME_VNSTATE,	{ .error = vfs_EIO },
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4212
		NULL, NULL
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4213
	};
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4214
3898
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 3446
diff changeset
  4215
	static const fs_operation_def_t stray_vfsops_template[] = {
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 3446
diff changeset
  4216
		VFSNAME_MOUNT,		{ .error = vfsstray },
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 3446
diff changeset
  4217
		VFSNAME_UNMOUNT,	{ .error = vfsstray },
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 3446
diff changeset
  4218
		VFSNAME_ROOT,		{ .error = vfsstray },
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 3446
diff changeset
  4219
		VFSNAME_STATVFS,	{ .error = vfsstray },
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 3446
diff changeset
  4220
		VFSNAME_SYNC, 		{ .vfs_sync = vfsstray_sync },
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 3446
diff changeset
  4221
		VFSNAME_VGET,		{ .error = vfsstray },
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 3446
diff changeset
  4222
		VFSNAME_MOUNTROOT,	{ .error = vfsstray },
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 3446
diff changeset
  4223
		VFSNAME_FREEVFS,	{ .error = vfsstray },
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 3446
diff changeset
  4224
		VFSNAME_VNSTATE,	{ .error = vfsstray },
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 3446
diff changeset
  4225
		NULL, NULL
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 3446
diff changeset
  4226
	};
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4227
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  4228
	/* Create vfs cache */
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  4229
	vfs_cache = kmem_cache_create("vfs_cache", sizeof (struct vfs),
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  4230
	    sizeof (uintptr_t), NULL, NULL, NULL, NULL, NULL, 0);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  4231
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4232
	/* Initialize the vnode cache (file systems may use it during init). */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4233
	vn_create_cache();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4234
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4235
	/* Setup event monitor framework */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4236
	fem_init();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4237
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4238
	/* Initialize the dummy stray file system type. */
3904
73066af3aa6a 6539420 Grab a mop! vfsinit() is leaking
rsb
parents: 3898
diff changeset
  4239
	error = vfs_setfsops(0, stray_vfsops_template, NULL);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4240
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4241
	/* Initialize the dummy EIO file system. */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4242
	error = vfs_makefsops(EIO_vfsops_template, &EIO_vfsops);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4243
	if (error != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4244
		cmn_err(CE_WARN, "vfsinit: bad EIO vfs ops template");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4245
		/* Shouldn't happen, but not bad enough to panic */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4246
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4247
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4248
	VFS_INIT(&EIO_vfs, EIO_vfsops, (caddr_t)NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4249
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4250
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4251
	 * Default EIO_vfs.vfs_flag to VFS_UNMOUNTED so a lookup
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4252
	 * on this vfs can immediately notice it's invalid.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4253
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4254
	EIO_vfs.vfs_flag |= VFS_UNMOUNTED;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4255
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4256
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4257
	 * Call the init routines of non-loadable filesystems only.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4258
	 * Filesystems which are loaded as separate modules will be
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4259
	 * initialized by the module loading code instead.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4260
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4261
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4262
	for (vswp = &vfssw[1]; vswp < &vfssw[nfstype]; vswp++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4263
		RLOCK_VFSSW();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4264
		if (vswp->vsw_init != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4265
			(*vswp->vsw_init)(vswp - vfssw, vswp->vsw_name);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4266
		RUNLOCK_VFSSW();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4267
	}
1488
196daa2cf3db PSARC/2006/034 fsstat
rsb
parents: 994
diff changeset
  4268
196daa2cf3db PSARC/2006/034 fsstat
rsb
parents: 994
diff changeset
  4269
	vopstats_startup();
1520
2fb01d86c1c1 6391295 fop_create() panic when running svvs over ZFS
rsb
parents: 1488
diff changeset
  4270
2fb01d86c1c1 6391295 fop_create() panic when running svvs over ZFS
rsb
parents: 1488
diff changeset
  4271
	if (vopstats_enabled) {
2fb01d86c1c1 6391295 fop_create() panic when running svvs over ZFS
rsb
parents: 1488
diff changeset
  4272
		/* 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
  4273
		initialize_vopstats(&EIO_vfs.vfs_vopstats);
2fb01d86c1c1 6391295 fop_create() panic when running svvs over ZFS
rsb
parents: 1488
diff changeset
  4274
		EIO_vfs.vfs_fstypevsp = NULL;
2fb01d86c1c1 6391295 fop_create() panic when running svvs over ZFS
rsb
parents: 1488
diff changeset
  4275
		EIO_vfs.vfs_vskap = NULL;
2fb01d86c1c1 6391295 fop_create() panic when running svvs over ZFS
rsb
parents: 1488
diff changeset
  4276
		EIO_vfs.vfs_flag |= VFS_STATS;
2fb01d86c1c1 6391295 fop_create() panic when running svvs over ZFS
rsb
parents: 1488
diff changeset
  4277
	}
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  4278
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  4279
	xattr_init();
10793
34709091de6d 6886081 Solaris needs reparse point support (PSARC 2009/387)
Dai Ngo <dai.ngo@sun.com>
parents: 8194
diff changeset
  4280
34709091de6d 6886081 Solaris needs reparse point support (PSARC 2009/387)
Dai Ngo <dai.ngo@sun.com>
parents: 8194
diff changeset
  4281
	reparse_point_init();
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  4282
}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  4283
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  4284
vfs_t *
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  4285
vfs_alloc(int kmflag)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  4286
{
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  4287
	vfs_t *vfsp;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  4288
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  4289
	vfsp = kmem_cache_alloc(vfs_cache, kmflag);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  4290
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  4291
	/*
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  4292
	 * Do the simplest initialization here.
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  4293
	 * Everything else gets done in vfs_init()
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  4294
	 */
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  4295
	bzero(vfsp, sizeof (vfs_t));
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  4296
	return (vfsp);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  4297
}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  4298
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  4299
void
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  4300
vfs_free(vfs_t *vfsp)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  4301
{
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  4302
	/*
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  4303
	 * One would be tempted to assert that "vfsp->vfs_count == 0".
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  4304
	 * The problem is that this gets called out of domount() with
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  4305
	 * a partially initialized vfs and a vfs_count of 1.  This is
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  4306
	 * also called from vfs_rele() with a vfs_count of 0.  We can't
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  4307
	 * call VFS_RELE() from domount() if VFS_MOUNT() hasn't successfully
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  4308
	 * returned.  This is because VFS_MOUNT() fully initializes the
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  4309
	 * vfs structure and its associated data.  VFS_RELE() will call
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  4310
	 * VFS_FREEVFS() which may panic the system if the data structures
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  4311
	 * aren't fully initialized from a successful VFS_MOUNT()).
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  4312
	 */
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  4313
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  4314
	/* If FEM was in use, make sure everything gets cleaned up */
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  4315
	if (vfsp->vfs_femhead) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  4316
		ASSERT(vfsp->vfs_femhead->femh_list == NULL);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  4317
		mutex_destroy(&vfsp->vfs_femhead->femh_lock);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  4318
		kmem_free(vfsp->vfs_femhead, sizeof (*(vfsp->vfs_femhead)));
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  4319
		vfsp->vfs_femhead = NULL;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  4320
	}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  4321
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  4322
	if (vfsp->vfs_implp)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  4323
		vfsimpl_teardown(vfsp);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  4324
	sema_destroy(&vfsp->vfs_reflock);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  4325
	kmem_cache_free(vfs_cache, vfsp);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4326
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4327
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4328
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4329
 * Increments the vfs reference count by one atomically.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4330
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4331
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4332
vfs_hold(vfs_t *vfsp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4333
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4334
	atomic_add_32(&vfsp->vfs_count, 1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4335
	ASSERT(vfsp->vfs_count != 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4336
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4337
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4338
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4339
 * Decrements the vfs reference count by one atomically. When
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4340
 * vfs reference count becomes zero, it calls the file system
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4341
 * specific vfs_freevfs() to free up the resources.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4342
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4343
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4344
vfs_rele(vfs_t *vfsp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4345
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4346
	ASSERT(vfsp->vfs_count != 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4347
	if (atomic_add_32_nv(&vfsp->vfs_count, -1) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4348
		VFS_FREEVFS(vfsp);
6734
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  4349
		lofi_remove(vfsp);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4350
		if (vfsp->vfs_zone)
13108
b02331b7b26d 6906740 Zones need an improved reference counting mechanism
jv227347 <Jordan.Vaughan@Sun.com>
parents: 12906
diff changeset
  4351
			zone_rele_ref(&vfsp->vfs_implp->vi_zone_ref,
b02331b7b26d 6906740 Zones need an improved reference counting mechanism
jv227347 <Jordan.Vaughan@Sun.com>
parents: 12906
diff changeset
  4352
			    ZONE_REF_VFS);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4353
		vfs_freemnttab(vfsp);
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  4354
		vfs_free(vfsp);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4355
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4356
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4357
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4358
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4359
 * Generic operations vector support.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4360
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4361
 * This is used to build operations vectors for both the vfs and vnode.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4362
 * It's normally called only when a file system is loaded.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4363
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4364
 * There are many possible algorithms for this, including the following:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4365
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4366
 *   (1) scan the list of known operations; for each, see if the file system
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4367
 *       includes an entry for it, and fill it in as appropriate.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4368
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4369
 *   (2) set up defaults for all known operations.  scan the list of ops
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4370
 *       supplied by the file system; for each which is both supplied and
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4371
 *       known, fill it in.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4372
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4373
 *   (3) sort the lists of known ops & supplied ops; scan the list, filling
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4374
 *       in entries as we go.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4375
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4376
 * we choose (1) for simplicity, and because performance isn't critical here.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4377
 * note that (2) could be sped up using a precomputed hash table on known ops.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4378
 * (3) could be faster than either, but only if the lists were very large or
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4379
 * supplied in sorted order.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4380
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4381
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4382
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4383
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4384
fs_build_vector(void *vector, int *unused_ops,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4385
    const fs_operation_trans_def_t *translation,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4386
    const fs_operation_def_t *operations)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4387
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4388
	int i, num_trans, num_ops, used;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4389
3898
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 3446
diff changeset
  4390
	/*
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 3446
diff changeset
  4391
	 * Count the number of translations and the number of supplied
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 3446
diff changeset
  4392
	 * operations.
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 3446
diff changeset
  4393
	 */
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4394
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4395
	{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4396
		const fs_operation_trans_def_t *p;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4397
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4398
		for (num_trans = 0, p = translation;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4399
		    p->name != NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4400
		    num_trans++, p++)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4401
			;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4402
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4403
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4404
	{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4405
		const fs_operation_def_t *p;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4406
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4407
		for (num_ops = 0, p = operations;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4408
		    p->name != NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4409
		    num_ops++, p++)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4410
			;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4411
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4412
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4413
	/* Walk through each operation known to our caller.  There will be */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4414
	/* one entry in the supplied "translation table" for each. */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4415
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4416
	used = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4417
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4418
	for (i = 0; i < num_trans; i++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4419
		int j, found;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4420
		char *curname;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4421
		fs_generic_func_p result;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4422
		fs_generic_func_p *location;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4423
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4424
		curname = translation[i].name;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4425
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4426
		/* Look for a matching operation in the list supplied by the */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4427
		/* file system. */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4428
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4429
		found = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4430
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4431
		for (j = 0; j < num_ops; j++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4432
			if (strcmp(operations[j].name, curname) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4433
				used++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4434
				found = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4435
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4436
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4437
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4438
3898
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 3446
diff changeset
  4439
		/*
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 3446
diff changeset
  4440
		 * If the file system is using a "placeholder" for default
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 3446
diff changeset
  4441
		 * or error functions, grab the appropriate function out of
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 3446
diff changeset
  4442
		 * the translation table.  If the file system didn't supply
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 3446
diff changeset
  4443
		 * this operation at all, use the default function.
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 3446
diff changeset
  4444
		 */
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4445
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4446
		if (found) {
3898
c788126f2a20 PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents: 3446
diff changeset
  4447
			result = operations[j].func.fs_generic;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4448
			if (result == fs_default) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4449
				result = translation[i].defaultFunc;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4450
			} else if (result == fs_error) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4451
				result = translation[i].errorFunc;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4452
			} else if (result == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4453
				/* Null values are PROHIBITED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4454
				return (EINVAL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4455
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4456
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4457
			result = translation[i].defaultFunc;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4458
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4459
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4460
		/* Now store the function into the operations vector. */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4461
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4462
		location = (fs_generic_func_p *)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4463
		    (((char *)vector) + translation[i].offset);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4464
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4465
		*location = result;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4466
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4467
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4468
	*unused_ops = num_ops - used;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4469
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4470
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4471
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4472
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4473
/* Placeholder functions, should never be called. */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4474
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4475
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4476
fs_error(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4477
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4478
	cmn_err(CE_PANIC, "fs_error called");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4479
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4480
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4481
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4482
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4483
fs_default(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4484
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4485
	cmn_err(CE_PANIC, "fs_default called");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4486
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4487
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4488
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4489
#ifdef __sparc
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4490
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4491
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4492
 * Part of the implementation of booting off a mirrored root
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4493
 * involves a change of dev_t for the root device.  To
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4494
 * accomplish this, first remove the existing hash table
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4495
 * entry for the root device, convert to the new dev_t,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4496
 * then re-insert in the hash table at the head of the list.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4497
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4498
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4499
vfs_root_redev(vfs_t *vfsp, dev_t ndev, int fstype)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4500
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4501
	vfs_list_lock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4502
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4503
	vfs_hash_remove(vfsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4504
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4505
	vfsp->vfs_dev = ndev;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4506
	vfs_make_fsid(&vfsp->vfs_fsid, ndev, fstype);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4507
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4508
	vfs_hash_add(vfsp, 1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4509
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4510
	vfs_list_unlock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4511
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4512
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4513
#else /* x86 NEWBOOT */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4514
6318
1d4ab74726bc PSARC/2007/664 Paravirtualized Drivers for Fully Virtualized xVM Domains
edp
parents: 6224
diff changeset
  4515
#if defined(__x86)
1d4ab74726bc PSARC/2007/664 Paravirtualized Drivers for Fully Virtualized xVM Domains
edp
parents: 6224
diff changeset
  4516
extern int hvmboot_rootconf();
1d4ab74726bc PSARC/2007/664 Paravirtualized Drivers for Fully Virtualized xVM Domains
edp
parents: 6224
diff changeset
  4517
#endif /* __x86 */
1d4ab74726bc PSARC/2007/664 Paravirtualized Drivers for Fully Virtualized xVM Domains
edp
parents: 6224
diff changeset
  4518
8194
f204d5cda6c1 PSARC 2008/427 iSCSI Boot
Jack Meng <Jack.Meng@Sun.COM>
parents: 8081
diff changeset
  4519
extern ib_boot_prop_t *iscsiboot_prop;
f204d5cda6c1 PSARC 2008/427 iSCSI Boot
Jack Meng <Jack.Meng@Sun.COM>
parents: 8081
diff changeset
  4520
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4521
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4522
rootconf()
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4523
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4524
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4525
	struct vfssw *vsw;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4526
	extern void pm_init();
5084
7d838c5c0eed PSARC 2006/260 Solaris on Xen
johnlev
parents: 4863
diff changeset
  4527
	char *fstyp, *fsmod;
8194
f204d5cda6c1 PSARC 2008/427 iSCSI Boot
Jack Meng <Jack.Meng@Sun.COM>
parents: 8081
diff changeset
  4528
	int ret = -1;
5084
7d838c5c0eed PSARC 2006/260 Solaris on Xen
johnlev
parents: 4863
diff changeset
  4529
7d838c5c0eed PSARC 2006/260 Solaris on Xen
johnlev
parents: 4863
diff changeset
  4530
	getrootfs(&fstyp, &fsmod);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4531
6318
1d4ab74726bc PSARC/2007/664 Paravirtualized Drivers for Fully Virtualized xVM Domains
edp
parents: 6224
diff changeset
  4532
#if defined(__x86)
1d4ab74726bc PSARC/2007/664 Paravirtualized Drivers for Fully Virtualized xVM Domains
edp
parents: 6224
diff changeset
  4533
	/*
1d4ab74726bc PSARC/2007/664 Paravirtualized Drivers for Fully Virtualized xVM Domains
edp
parents: 6224
diff changeset
  4534
	 * hvmboot_rootconf() is defined in the hvm_bootstrap misc module,
1d4ab74726bc PSARC/2007/664 Paravirtualized Drivers for Fully Virtualized xVM Domains
edp
parents: 6224
diff changeset
  4535
	 * which lives in /platform/i86hvm, and hence is only available when
1d4ab74726bc PSARC/2007/664 Paravirtualized Drivers for Fully Virtualized xVM Domains
edp
parents: 6224
diff changeset
  4536
	 * booted in an x86 hvm environment.  If the hvm_bootstrap misc module
1d4ab74726bc PSARC/2007/664 Paravirtualized Drivers for Fully Virtualized xVM Domains
edp
parents: 6224
diff changeset
  4537
	 * is not available then the modstub for this function will return 0.
1d4ab74726bc PSARC/2007/664 Paravirtualized Drivers for Fully Virtualized xVM Domains
edp
parents: 6224
diff changeset
  4538
	 * If the hvm_bootstrap misc module is available it will be loaded
1d4ab74726bc PSARC/2007/664 Paravirtualized Drivers for Fully Virtualized xVM Domains
edp
parents: 6224
diff changeset
  4539
	 * and hvmboot_rootconf() will be invoked.
1d4ab74726bc PSARC/2007/664 Paravirtualized Drivers for Fully Virtualized xVM Domains
edp
parents: 6224
diff changeset
  4540
	 */
1d4ab74726bc PSARC/2007/664 Paravirtualized Drivers for Fully Virtualized xVM Domains
edp
parents: 6224
diff changeset
  4541
	if (error = hvmboot_rootconf())
1d4ab74726bc PSARC/2007/664 Paravirtualized Drivers for Fully Virtualized xVM Domains
edp
parents: 6224
diff changeset
  4542
		return (error);
1d4ab74726bc PSARC/2007/664 Paravirtualized Drivers for Fully Virtualized xVM Domains
edp
parents: 6224
diff changeset
  4543
#endif /* __x86 */
1d4ab74726bc PSARC/2007/664 Paravirtualized Drivers for Fully Virtualized xVM Domains
edp
parents: 6224
diff changeset
  4544
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4545
	if (error = clboot_rootconf())
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4546
		return (error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4547
5084
7d838c5c0eed PSARC 2006/260 Solaris on Xen
johnlev
parents: 4863
diff changeset
  4548
	if (modload("fs", fsmod) == -1)
7d838c5c0eed PSARC 2006/260 Solaris on Xen
johnlev
parents: 4863
diff changeset
  4549
		panic("Cannot _init %s module", fsmod);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4550
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4551
	RLOCK_VFSSW();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4552
	vsw = vfs_getvfsswbyname(fstyp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4553
	RUNLOCK_VFSSW();
7439
fb3bf1897b9d 6317111 newboot x86 diskless client refuses to use nfs vers3 for root filesystem
Pavel Filipensky <Pavel.Filipensky@Sun.COM>
parents: 6855
diff changeset
  4554
	if (vsw == NULL) {
fb3bf1897b9d 6317111 newboot x86 diskless client refuses to use nfs vers3 for root filesystem
Pavel Filipensky <Pavel.Filipensky@Sun.COM>
parents: 6855
diff changeset
  4555
		cmn_err(CE_CONT, "Cannot find %s filesystem\n", fstyp);
fb3bf1897b9d 6317111 newboot x86 diskless client refuses to use nfs vers3 for root filesystem
Pavel Filipensky <Pavel.Filipensky@Sun.COM>
parents: 6855
diff changeset
  4556
		return (ENXIO);
fb3bf1897b9d 6317111 newboot x86 diskless client refuses to use nfs vers3 for root filesystem
Pavel Filipensky <Pavel.Filipensky@Sun.COM>
parents: 6855
diff changeset
  4557
	}
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4558
	VFS_INIT(rootvfs, &vsw->vsw_vfsops, 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4559
	VFS_HOLD(rootvfs);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4560
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4561
	/* always mount readonly first */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4562
	rootvfs->vfs_flag |= VFS_RDONLY;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4563
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4564
	pm_init();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4565
8194
f204d5cda6c1 PSARC 2008/427 iSCSI Boot
Jack Meng <Jack.Meng@Sun.COM>
parents: 8081
diff changeset
  4566
	if (netboot && iscsiboot_prop) {
f204d5cda6c1 PSARC 2008/427 iSCSI Boot
Jack Meng <Jack.Meng@Sun.COM>
parents: 8081
diff changeset
  4567
		cmn_err(CE_WARN, "NFS boot and iSCSI boot"
f204d5cda6c1 PSARC 2008/427 iSCSI Boot
Jack Meng <Jack.Meng@Sun.COM>
parents: 8081
diff changeset
  4568
		    " shouldn't happen in the same time");
f204d5cda6c1 PSARC 2008/427 iSCSI Boot
Jack Meng <Jack.Meng@Sun.COM>
parents: 8081
diff changeset
  4569
		return (EINVAL);
f204d5cda6c1 PSARC 2008/427 iSCSI Boot
Jack Meng <Jack.Meng@Sun.COM>
parents: 8081
diff changeset
  4570
	}
f204d5cda6c1 PSARC 2008/427 iSCSI Boot
Jack Meng <Jack.Meng@Sun.COM>
parents: 8081
diff changeset
  4571
10822
2a6b5dc1374c PSARC 2008/427 iSCSI Boot
Jack Meng <Jack.Meng@Sun.COM>
parents: 10793
diff changeset
  4572
	if (netboot || iscsiboot_prop) {
8194
f204d5cda6c1 PSARC 2008/427 iSCSI Boot
Jack Meng <Jack.Meng@Sun.COM>
parents: 8081
diff changeset
  4573
		ret = strplumb();
10822
2a6b5dc1374c PSARC 2008/427 iSCSI Boot
Jack Meng <Jack.Meng@Sun.COM>
parents: 10793
diff changeset
  4574
		if (ret != 0) {
2a6b5dc1374c PSARC 2008/427 iSCSI Boot
Jack Meng <Jack.Meng@Sun.COM>
parents: 10793
diff changeset
  4575
			cmn_err(CE_WARN, "Cannot plumb network device %d", ret);
2a6b5dc1374c PSARC 2008/427 iSCSI Boot
Jack Meng <Jack.Meng@Sun.COM>
parents: 10793
diff changeset
  4576
			return (EFAULT);
2a6b5dc1374c PSARC 2008/427 iSCSI Boot
Jack Meng <Jack.Meng@Sun.COM>
parents: 10793
diff changeset
  4577
		}
2a6b5dc1374c PSARC 2008/427 iSCSI Boot
Jack Meng <Jack.Meng@Sun.COM>
parents: 10793
diff changeset
  4578
	}
8194
f204d5cda6c1 PSARC 2008/427 iSCSI Boot
Jack Meng <Jack.Meng@Sun.COM>
parents: 8081
diff changeset
  4579
f204d5cda6c1 PSARC 2008/427 iSCSI Boot
Jack Meng <Jack.Meng@Sun.COM>
parents: 8081
diff changeset
  4580
	if ((ret == 0) && iscsiboot_prop) {
f204d5cda6c1 PSARC 2008/427 iSCSI Boot
Jack Meng <Jack.Meng@Sun.COM>
parents: 8081
diff changeset
  4581
		ret = modload("drv", "iscsi");
f204d5cda6c1 PSARC 2008/427 iSCSI Boot
Jack Meng <Jack.Meng@Sun.COM>
parents: 8081
diff changeset
  4582
		/* -1 indicates fail */
f204d5cda6c1 PSARC 2008/427 iSCSI Boot
Jack Meng <Jack.Meng@Sun.COM>
parents: 8081
diff changeset
  4583
		if (ret == -1) {
f204d5cda6c1 PSARC 2008/427 iSCSI Boot
Jack Meng <Jack.Meng@Sun.COM>
parents: 8081
diff changeset
  4584
			cmn_err(CE_WARN, "Failed to load iscsi module");
f204d5cda6c1 PSARC 2008/427 iSCSI Boot
Jack Meng <Jack.Meng@Sun.COM>
parents: 8081
diff changeset
  4585
			iscsi_boot_prop_free();
f204d5cda6c1 PSARC 2008/427 iSCSI Boot
Jack Meng <Jack.Meng@Sun.COM>
parents: 8081
diff changeset
  4586
			return (EINVAL);
f204d5cda6c1 PSARC 2008/427 iSCSI Boot
Jack Meng <Jack.Meng@Sun.COM>
parents: 8081
diff changeset
  4587
		} else {
f204d5cda6c1 PSARC 2008/427 iSCSI Boot
Jack Meng <Jack.Meng@Sun.COM>
parents: 8081
diff changeset
  4588
			if (!i_ddi_attach_pseudo_node("iscsi")) {
f204d5cda6c1 PSARC 2008/427 iSCSI Boot
Jack Meng <Jack.Meng@Sun.COM>
parents: 8081
diff changeset
  4589
				cmn_err(CE_WARN,
f204d5cda6c1 PSARC 2008/427 iSCSI Boot
Jack Meng <Jack.Meng@Sun.COM>
parents: 8081
diff changeset
  4590
				    "Failed to attach iscsi driver");
f204d5cda6c1 PSARC 2008/427 iSCSI Boot
Jack Meng <Jack.Meng@Sun.COM>
parents: 8081
diff changeset
  4591
				iscsi_boot_prop_free();
f204d5cda6c1 PSARC 2008/427 iSCSI Boot
Jack Meng <Jack.Meng@Sun.COM>
parents: 8081
diff changeset
  4592
				return (ENODEV);
f204d5cda6c1 PSARC 2008/427 iSCSI Boot
Jack Meng <Jack.Meng@Sun.COM>
parents: 8081
diff changeset
  4593
			}
f204d5cda6c1 PSARC 2008/427 iSCSI Boot
Jack Meng <Jack.Meng@Sun.COM>
parents: 8081
diff changeset
  4594
		}
f204d5cda6c1 PSARC 2008/427 iSCSI Boot
Jack Meng <Jack.Meng@Sun.COM>
parents: 8081
diff changeset
  4595
	}
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4596
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4597
	error = VFS_MOUNTROOT(rootvfs, ROOT_INIT);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4598
	vfs_unrefvfssw(vsw);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4599
	rootdev = rootvfs->vfs_dev;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4600
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4601
	if (error)
7439
fb3bf1897b9d 6317111 newboot x86 diskless client refuses to use nfs vers3 for root filesystem
Pavel Filipensky <Pavel.Filipensky@Sun.COM>
parents: 6855
diff changeset
  4602
		cmn_err(CE_CONT, "Cannot mount root on %s fstype %s\n",
fb3bf1897b9d 6317111 newboot x86 diskless client refuses to use nfs vers3 for root filesystem
Pavel Filipensky <Pavel.Filipensky@Sun.COM>
parents: 6855
diff changeset
  4603
		    rootfs.bo_name, fstyp);
fb3bf1897b9d 6317111 newboot x86 diskless client refuses to use nfs vers3 for root filesystem
Pavel Filipensky <Pavel.Filipensky@Sun.COM>
parents: 6855
diff changeset
  4604
	else
fb3bf1897b9d 6317111 newboot x86 diskless client refuses to use nfs vers3 for root filesystem
Pavel Filipensky <Pavel.Filipensky@Sun.COM>
parents: 6855
diff changeset
  4605
		cmn_err(CE_CONT, "?root on %s fstype %s\n",
fb3bf1897b9d 6317111 newboot x86 diskless client refuses to use nfs vers3 for root filesystem
Pavel Filipensky <Pavel.Filipensky@Sun.COM>
parents: 6855
diff changeset
  4606
		    rootfs.bo_name, fstyp);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4607
	return (error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4608
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4609
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4610
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4611
 * XXX this is called by nfs only and should probably be removed
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4612
 * If booted with ASKNAME, prompt on the console for a filesystem
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4613
 * name and return it.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4614
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4615
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4616
getfsname(char *askfor, char *name, size_t namelen)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4617
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4618
	if (boothowto & RB_ASKNAME) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4619
		printf("%s name: ", askfor);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4620
		console_gets(name, namelen);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4621
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4622
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4623
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4624
/*
7439
fb3bf1897b9d 6317111 newboot x86 diskless client refuses to use nfs vers3 for root filesystem
Pavel Filipensky <Pavel.Filipensky@Sun.COM>
parents: 6855
diff changeset
  4625
 * Init the root filesystem type (rootfs.bo_fstype) from the "fstype"
fb3bf1897b9d 6317111 newboot x86 diskless client refuses to use nfs vers3 for root filesystem
Pavel Filipensky <Pavel.Filipensky@Sun.COM>
parents: 6855
diff changeset
  4626
 * property.
fb3bf1897b9d 6317111 newboot x86 diskless client refuses to use nfs vers3 for root filesystem
Pavel Filipensky <Pavel.Filipensky@Sun.COM>
parents: 6855
diff changeset
  4627
 *
fb3bf1897b9d 6317111 newboot x86 diskless client refuses to use nfs vers3 for root filesystem
Pavel Filipensky <Pavel.Filipensky@Sun.COM>
parents: 6855
diff changeset
  4628
 * Filesystem types starting with the prefix "nfs" are diskless clients;
fb3bf1897b9d 6317111 newboot x86 diskless client refuses to use nfs vers3 for root filesystem
Pavel Filipensky <Pavel.Filipensky@Sun.COM>
parents: 6855
diff changeset
  4629
 * init the root filename name (rootfs.bo_name), too.
fb3bf1897b9d 6317111 newboot x86 diskless client refuses to use nfs vers3 for root filesystem
Pavel Filipensky <Pavel.Filipensky@Sun.COM>
parents: 6855
diff changeset
  4630
 *
fb3bf1897b9d 6317111 newboot x86 diskless client refuses to use nfs vers3 for root filesystem
Pavel Filipensky <Pavel.Filipensky@Sun.COM>
parents: 6855
diff changeset
  4631
 * If we are booting via NFS we currently have these options:
fb3bf1897b9d 6317111 newboot x86 diskless client refuses to use nfs vers3 for root filesystem
Pavel Filipensky <Pavel.Filipensky@Sun.COM>
parents: 6855
diff changeset
  4632
 *	nfs -	dynamically choose NFS V2, V3, or V4 (default)
fb3bf1897b9d 6317111 newboot x86 diskless client refuses to use nfs vers3 for root filesystem
Pavel Filipensky <Pavel.Filipensky@Sun.COM>
parents: 6855
diff changeset
  4633
 *	nfs2 -	force NFS V2
fb3bf1897b9d 6317111 newboot x86 diskless client refuses to use nfs vers3 for root filesystem
Pavel Filipensky <Pavel.Filipensky@Sun.COM>
parents: 6855
diff changeset
  4634
 *	nfs3 -	force NFS V3
fb3bf1897b9d 6317111 newboot x86 diskless client refuses to use nfs vers3 for root filesystem
Pavel Filipensky <Pavel.Filipensky@Sun.COM>
parents: 6855
diff changeset
  4635
 *	nfs4 -	force NFS V4
fb3bf1897b9d 6317111 newboot x86 diskless client refuses to use nfs vers3 for root filesystem
Pavel Filipensky <Pavel.Filipensky@Sun.COM>
parents: 6855
diff changeset
  4636
 * Because we need to maintain backward compatibility with the naming
fb3bf1897b9d 6317111 newboot x86 diskless client refuses to use nfs vers3 for root filesystem
Pavel Filipensky <Pavel.Filipensky@Sun.COM>
parents: 6855
diff changeset
  4637
 * convention that the NFS V2 filesystem name is "nfs" (see vfs_conf.c)
fb3bf1897b9d 6317111 newboot x86 diskless client refuses to use nfs vers3 for root filesystem
Pavel Filipensky <Pavel.Filipensky@Sun.COM>
parents: 6855
diff changeset
  4638
 * we need to map "nfs" => "nfsdyn" and "nfs2" => "nfs".  The dynamic
fb3bf1897b9d 6317111 newboot x86 diskless client refuses to use nfs vers3 for root filesystem
Pavel Filipensky <Pavel.Filipensky@Sun.COM>
parents: 6855
diff changeset
  4639
 * nfs module will map the type back to either "nfs", "nfs3", or "nfs4".
fb3bf1897b9d 6317111 newboot x86 diskless client refuses to use nfs vers3 for root filesystem
Pavel Filipensky <Pavel.Filipensky@Sun.COM>
parents: 6855
diff changeset
  4640
 * This is only for root filesystems, all other uses such as cachefs
fb3bf1897b9d 6317111 newboot x86 diskless client refuses to use nfs vers3 for root filesystem
Pavel Filipensky <Pavel.Filipensky@Sun.COM>
parents: 6855
diff changeset
  4641
 * will expect that "nfs" == NFS V2.
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4642
 */
5084
7d838c5c0eed PSARC 2006/260 Solaris on Xen
johnlev
parents: 4863
diff changeset
  4643
static void
7d838c5c0eed PSARC 2006/260 Solaris on Xen
johnlev
parents: 4863
diff changeset
  4644
getrootfs(char **fstypp, char **fsmodp)
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4645
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4646
	extern char *strplumb_get_netdev_path(void);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4647
	char *propstr = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4648
7439
fb3bf1897b9d 6317111 newboot x86 diskless client refuses to use nfs vers3 for root filesystem
Pavel Filipensky <Pavel.Filipensky@Sun.COM>
parents: 6855
diff changeset
  4649
	/*
fb3bf1897b9d 6317111 newboot x86 diskless client refuses to use nfs vers3 for root filesystem
Pavel Filipensky <Pavel.Filipensky@Sun.COM>
parents: 6855
diff changeset
  4650
	 * Check fstype property; for diskless it should be one of "nfs",
fb3bf1897b9d 6317111 newboot x86 diskless client refuses to use nfs vers3 for root filesystem
Pavel Filipensky <Pavel.Filipensky@Sun.COM>
parents: 6855
diff changeset
  4651
	 * "nfs2", "nfs3" or "nfs4".
fb3bf1897b9d 6317111 newboot x86 diskless client refuses to use nfs vers3 for root filesystem
Pavel Filipensky <Pavel.Filipensky@Sun.COM>
parents: 6855
diff changeset
  4652
	 */
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4653
	if (ddi_prop_lookup_string(DDI_DEV_T_ANY, ddi_root_node(),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4654
	    DDI_PROP_DONTPASS, "fstype", &propstr)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4655
	    == DDI_SUCCESS) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4656
		(void) strncpy(rootfs.bo_fstype, propstr, BO_MAXFSNAME);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4657
		ddi_prop_free(propstr);
3912
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3904
diff changeset
  4658
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3904
diff changeset
  4659
	/*
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3904
diff changeset
  4660
	 * if the boot property 'fstype' is not set, but 'zfs-bootfs' is set,
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3904
diff changeset
  4661
	 * assume the type of this root filesystem is 'zfs'.
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3904
diff changeset
  4662
	 */
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3904
diff changeset
  4663
	} else if (ddi_prop_lookup_string(DDI_DEV_T_ANY, ddi_root_node(),
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3904
diff changeset
  4664
	    DDI_PROP_DONTPASS, "zfs-bootfs", &propstr)
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3904
diff changeset
  4665
	    == DDI_SUCCESS) {
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3904
diff changeset
  4666
		(void) strncpy(rootfs.bo_fstype, "zfs", BO_MAXFSNAME);
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3904
diff changeset
  4667
		ddi_prop_free(propstr);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4668
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4669
5084
7d838c5c0eed PSARC 2006/260 Solaris on Xen
johnlev
parents: 4863
diff changeset
  4670
	if (strncmp(rootfs.bo_fstype, "nfs", 3) != 0) {
7d838c5c0eed PSARC 2006/260 Solaris on Xen
johnlev
parents: 4863
diff changeset
  4671
		*fstypp = *fsmodp = rootfs.bo_fstype;
7d838c5c0eed PSARC 2006/260 Solaris on Xen
johnlev
parents: 4863
diff changeset
  4672
		return;
7d838c5c0eed PSARC 2006/260 Solaris on Xen
johnlev
parents: 4863
diff changeset
  4673
	}
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4674
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4675
	++netboot;
7439
fb3bf1897b9d 6317111 newboot x86 diskless client refuses to use nfs vers3 for root filesystem
Pavel Filipensky <Pavel.Filipensky@Sun.COM>
parents: 6855
diff changeset
  4676
fb3bf1897b9d 6317111 newboot x86 diskless client refuses to use nfs vers3 for root filesystem
Pavel Filipensky <Pavel.Filipensky@Sun.COM>
parents: 6855
diff changeset
  4677
	if (strcmp(rootfs.bo_fstype, "nfs2") == 0)
fb3bf1897b9d 6317111 newboot x86 diskless client refuses to use nfs vers3 for root filesystem
Pavel Filipensky <Pavel.Filipensky@Sun.COM>
parents: 6855
diff changeset
  4678
		(void) strcpy(rootfs.bo_fstype, "nfs");
fb3bf1897b9d 6317111 newboot x86 diskless client refuses to use nfs vers3 for root filesystem
Pavel Filipensky <Pavel.Filipensky@Sun.COM>
parents: 6855
diff changeset
  4679
	else if (strcmp(rootfs.bo_fstype, "nfs") == 0)
fb3bf1897b9d 6317111 newboot x86 diskless client refuses to use nfs vers3 for root filesystem
Pavel Filipensky <Pavel.Filipensky@Sun.COM>
parents: 6855
diff changeset
  4680
		(void) strcpy(rootfs.bo_fstype, "nfsdyn");
fb3bf1897b9d 6317111 newboot x86 diskless client refuses to use nfs vers3 for root filesystem
Pavel Filipensky <Pavel.Filipensky@Sun.COM>
parents: 6855
diff changeset
  4681
5084
7d838c5c0eed PSARC 2006/260 Solaris on Xen
johnlev
parents: 4863
diff changeset
  4682
	/*
7d838c5c0eed PSARC 2006/260 Solaris on Xen
johnlev
parents: 4863
diff changeset
  4683
	 * check if path to network interface is specified in bootpath
7d838c5c0eed PSARC 2006/260 Solaris on Xen
johnlev
parents: 4863
diff changeset
  4684
	 * or by a hypervisor domain configuration file.
7d838c5c0eed PSARC 2006/260 Solaris on Xen
johnlev
parents: 4863
diff changeset
  4685
	 * XXPV - enable strlumb_get_netdev_path()
7d838c5c0eed PSARC 2006/260 Solaris on Xen
johnlev
parents: 4863
diff changeset
  4686
	 */
7d838c5c0eed PSARC 2006/260 Solaris on Xen
johnlev
parents: 4863
diff changeset
  4687
	if (ddi_prop_exists(DDI_DEV_T_ANY, ddi_root_node(), DDI_PROP_DONTPASS,
7d838c5c0eed PSARC 2006/260 Solaris on Xen
johnlev
parents: 4863
diff changeset
  4688
	    "xpv-nfsroot")) {
7d838c5c0eed PSARC 2006/260 Solaris on Xen
johnlev
parents: 4863
diff changeset
  4689
		(void) strcpy(rootfs.bo_name, "/xpvd/xnf@0");
7d838c5c0eed PSARC 2006/260 Solaris on Xen
johnlev
parents: 4863
diff changeset
  4690
	} else if (ddi_prop_lookup_string(DDI_DEV_T_ANY, ddi_root_node(),
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4691
	    DDI_PROP_DONTPASS, "bootpath", &propstr)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4692
	    == DDI_SUCCESS) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4693
		(void) strncpy(rootfs.bo_name, propstr, BO_MAXOBJNAME);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4694
		ddi_prop_free(propstr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4695
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4696
		/* attempt to determine netdev_path via boot_mac address */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4697
		netdev_path = strplumb_get_netdev_path();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4698
		if (netdev_path == NULL)
3446
5903aece022d PSARC 2006/469 EOF and removal of eeprom -I
mrj
parents: 2621
diff changeset
  4699
			panic("cannot find boot network interface");
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4700
		(void) strncpy(rootfs.bo_name, netdev_path, BO_MAXOBJNAME);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4701
	}
5084
7d838c5c0eed PSARC 2006/260 Solaris on Xen
johnlev
parents: 4863
diff changeset
  4702
	*fstypp = rootfs.bo_fstype;
7d838c5c0eed PSARC 2006/260 Solaris on Xen
johnlev
parents: 4863
diff changeset
  4703
	*fsmodp = "nfs";
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4704
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4705
#endif
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  4706
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  4707
/*
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  4708
 * VFS feature routines
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  4709
 */
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  4710
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  4711
#define	VFTINDEX(feature)	(((feature) >> 32) & 0xFFFFFFFF)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  4712
#define	VFTBITS(feature)	((feature) & 0xFFFFFFFFLL)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  4713
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  4714
/* Register a feature in the vfs */
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  4715
void
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  4716
vfs_set_feature(vfs_t *vfsp, vfs_feature_t feature)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  4717
{
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  4718
	/* Note that vfs_featureset[] is found in *vfsp->vfs_implp */
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  4719
	if (vfsp->vfs_implp == NULL)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  4720
		return;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  4721
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  4722
	vfsp->vfs_featureset[VFTINDEX(feature)] |= VFTBITS(feature);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  4723
}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  4724
13178
5f70b43d6386 6977619 NULL pointer deference in sa_handle_get_from_db()
Mark Shellenbaum <Mark.Shellenbaum@Oracle.COM>
parents: 13108
diff changeset
  4725
void
5f70b43d6386 6977619 NULL pointer deference in sa_handle_get_from_db()
Mark Shellenbaum <Mark.Shellenbaum@Oracle.COM>
parents: 13108
diff changeset
  4726
vfs_clear_feature(vfs_t *vfsp, vfs_feature_t feature)
5f70b43d6386 6977619 NULL pointer deference in sa_handle_get_from_db()
Mark Shellenbaum <Mark.Shellenbaum@Oracle.COM>
parents: 13108
diff changeset
  4727
{
5f70b43d6386 6977619 NULL pointer deference in sa_handle_get_from_db()
Mark Shellenbaum <Mark.Shellenbaum@Oracle.COM>
parents: 13108
diff changeset
  4728
	/* Note that vfs_featureset[] is found in *vfsp->vfs_implp */
5f70b43d6386 6977619 NULL pointer deference in sa_handle_get_from_db()
Mark Shellenbaum <Mark.Shellenbaum@Oracle.COM>
parents: 13108
diff changeset
  4729
	if (vfsp->vfs_implp == NULL)
5f70b43d6386 6977619 NULL pointer deference in sa_handle_get_from_db()
Mark Shellenbaum <Mark.Shellenbaum@Oracle.COM>
parents: 13108
diff changeset
  4730
		return;
5f70b43d6386 6977619 NULL pointer deference in sa_handle_get_from_db()
Mark Shellenbaum <Mark.Shellenbaum@Oracle.COM>
parents: 13108
diff changeset
  4731
	vfsp->vfs_featureset[VFTINDEX(feature)] &= VFTBITS(~feature);
5f70b43d6386 6977619 NULL pointer deference in sa_handle_get_from_db()
Mark Shellenbaum <Mark.Shellenbaum@Oracle.COM>
parents: 13108
diff changeset
  4732
}
5f70b43d6386 6977619 NULL pointer deference in sa_handle_get_from_db()
Mark Shellenbaum <Mark.Shellenbaum@Oracle.COM>
parents: 13108
diff changeset
  4733
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  4734
/*
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  4735
 * Query a vfs for a feature.
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  4736
 * Returns 1 if feature is present, 0 if not
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  4737
 */
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  4738
int
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  4739
vfs_has_feature(vfs_t *vfsp, vfs_feature_t feature)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  4740
{
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  4741
	int	ret = 0;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  4742
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  4743
	/* Note that vfs_featureset[] is found in *vfsp->vfs_implp */
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  4744
	if (vfsp->vfs_implp == NULL)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  4745
		return (ret);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  4746
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  4747
	if (vfsp->vfs_featureset[VFTINDEX(feature)] & VFTBITS(feature))
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  4748
		ret = 1;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  4749
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  4750
	return (ret);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 5302
diff changeset
  4751
}
6224
723c47040516 6671591 lofs needs to propagate vfs features from real vfs
marks
parents: 5331
diff changeset
  4752
723c47040516 6671591 lofs needs to propagate vfs features from real vfs
marks
parents: 5331
diff changeset
  4753
/*
723c47040516 6671591 lofs needs to propagate vfs features from real vfs
marks
parents: 5331
diff changeset
  4754
 * Propagate feature set from one vfs to another
723c47040516 6671591 lofs needs to propagate vfs features from real vfs
marks
parents: 5331
diff changeset
  4755
 */
723c47040516 6671591 lofs needs to propagate vfs features from real vfs
marks
parents: 5331
diff changeset
  4756
void
723c47040516 6671591 lofs needs to propagate vfs features from real vfs
marks
parents: 5331
diff changeset
  4757
vfs_propagate_features(vfs_t *from, vfs_t *to)
723c47040516 6671591 lofs needs to propagate vfs features from real vfs
marks
parents: 5331
diff changeset
  4758
{
723c47040516 6671591 lofs needs to propagate vfs features from real vfs
marks
parents: 5331
diff changeset
  4759
	int i;
723c47040516 6671591 lofs needs to propagate vfs features from real vfs
marks
parents: 5331
diff changeset
  4760
723c47040516 6671591 lofs needs to propagate vfs features from real vfs
marks
parents: 5331
diff changeset
  4761
	if (to->vfs_implp == NULL || from->vfs_implp == NULL)
723c47040516 6671591 lofs needs to propagate vfs features from real vfs
marks
parents: 5331
diff changeset
  4762
		return;
723c47040516 6671591 lofs needs to propagate vfs features from real vfs
marks
parents: 5331
diff changeset
  4763
723c47040516 6671591 lofs needs to propagate vfs features from real vfs
marks
parents: 5331
diff changeset
  4764
	for (i = 1; i <= to->vfs_featureset[0]; i++) {
723c47040516 6671591 lofs needs to propagate vfs features from real vfs
marks
parents: 5331
diff changeset
  4765
		to->vfs_featureset[i] = from->vfs_featureset[i];
723c47040516 6671591 lofs needs to propagate vfs features from real vfs
marks
parents: 5331
diff changeset
  4766
	}
723c47040516 6671591 lofs needs to propagate vfs features from real vfs
marks
parents: 5331
diff changeset
  4767
}
6734
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  4768
12633
9f2cda0ed938 PSARC 2010/144 lofi(7D) in non global zones
John Levon <john.levon@sun.com>
parents: 11173
diff changeset
  4769
#define	LOFINODE_PATH "/dev/lofi/%d"
6734
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  4770
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  4771
/*
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  4772
 * Return the vnode for the lofi node if there's a lofi mount in place.
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  4773
 * Returns -1 when there's no lofi node, 0 on success, and > 0 on
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  4774
 * failure.
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  4775
 */
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  4776
int
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  4777
vfs_get_lofi(vfs_t *vfsp, vnode_t **vpp)
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  4778
{
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  4779
	char *path = NULL;
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  4780
	int strsize;
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  4781
	int err;
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  4782
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  4783
	if (vfsp->vfs_lofi_minor == 0) {
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  4784
		*vpp = NULL;
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  4785
		return (-1);
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  4786
	}
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  4787
12633
9f2cda0ed938 PSARC 2010/144 lofi(7D) in non global zones
John Levon <john.levon@sun.com>
parents: 11173
diff changeset
  4788
	strsize = snprintf(NULL, 0, LOFINODE_PATH, vfsp->vfs_lofi_minor);
6734
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  4789
	path = kmem_alloc(strsize + 1, KM_SLEEP);
12633
9f2cda0ed938 PSARC 2010/144 lofi(7D) in non global zones
John Levon <john.levon@sun.com>
parents: 11173
diff changeset
  4790
	(void) snprintf(path, strsize + 1, LOFINODE_PATH, vfsp->vfs_lofi_minor);
9f2cda0ed938 PSARC 2010/144 lofi(7D) in non global zones
John Levon <john.levon@sun.com>
parents: 11173
diff changeset
  4791
9f2cda0ed938 PSARC 2010/144 lofi(7D) in non global zones
John Levon <john.levon@sun.com>
parents: 11173
diff changeset
  4792
	/*
9f2cda0ed938 PSARC 2010/144 lofi(7D) in non global zones
John Levon <john.levon@sun.com>
parents: 11173
diff changeset
  4793
	 * We may be inside a zone, so we need to use the /dev path, but
9f2cda0ed938 PSARC 2010/144 lofi(7D) in non global zones
John Levon <john.levon@sun.com>
parents: 11173
diff changeset
  4794
	 * it's created asynchronously, so we wait here.
9f2cda0ed938 PSARC 2010/144 lofi(7D) in non global zones
John Levon <john.levon@sun.com>
parents: 11173
diff changeset
  4795
	 */
9f2cda0ed938 PSARC 2010/144 lofi(7D) in non global zones
John Levon <john.levon@sun.com>
parents: 11173
diff changeset
  4796
	for (;;) {
9f2cda0ed938 PSARC 2010/144 lofi(7D) in non global zones
John Levon <john.levon@sun.com>
parents: 11173
diff changeset
  4797
		err = lookupname(path, UIO_SYSSPACE, FOLLOW, NULLVPP, vpp);
9f2cda0ed938 PSARC 2010/144 lofi(7D) in non global zones
John Levon <john.levon@sun.com>
parents: 11173
diff changeset
  4798
9f2cda0ed938 PSARC 2010/144 lofi(7D) in non global zones
John Levon <john.levon@sun.com>
parents: 11173
diff changeset
  4799
		if (err != ENOENT)
9f2cda0ed938 PSARC 2010/144 lofi(7D) in non global zones
John Levon <john.levon@sun.com>
parents: 11173
diff changeset
  4800
			break;
9f2cda0ed938 PSARC 2010/144 lofi(7D) in non global zones
John Levon <john.levon@sun.com>
parents: 11173
diff changeset
  4801
9f2cda0ed938 PSARC 2010/144 lofi(7D) in non global zones
John Levon <john.levon@sun.com>
parents: 11173
diff changeset
  4802
		if ((err = delay_sig(hz / 8)) == EINTR)
9f2cda0ed938 PSARC 2010/144 lofi(7D) in non global zones
John Levon <john.levon@sun.com>
parents: 11173
diff changeset
  4803
			break;
9f2cda0ed938 PSARC 2010/144 lofi(7D) in non global zones
John Levon <john.levon@sun.com>
parents: 11173
diff changeset
  4804
	}
6734
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  4805
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  4806
	if (err)
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  4807
		*vpp = NULL;
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  4808
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  4809
	kmem_free(path, strsize + 1);
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  4810
	return (err);
d16dda992d39 PSARC/2008/290 lofi mount
johnlev
parents: 6423
diff changeset
  4811
}